From 2fd10b5d1519469995f16518b6e8c6a108950bea Mon Sep 17 00:00:00 2001 From: Malcrom Date: Wed, 2 Jan 2013 14:11:39 -0330 Subject: Core/Scripting: Properly name boss_thorngrin_the_tender file. --- src/server/scripts/Outland/CMakeLists.txt | 2 +- .../botanica/boss_thorngrin_the_tender.cpp | 152 +++++++++++++++++++++ .../TempestKeep/botanica/thorngrin_the_tender.cpp | 152 --------------------- 3 files changed, 153 insertions(+), 153 deletions(-) create mode 100644 src/server/scripts/Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp delete mode 100644 src/server/scripts/Outland/TempestKeep/botanica/thorngrin_the_tender.cpp (limited to 'src') diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index 173af3374ad..b7f4736e91b 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -62,7 +62,7 @@ set(scripts_STAT_SRCS Outland/TempestKeep/botanica/the_botanica.h Outland/TempestKeep/botanica/instance_the_botanica.cpp Outland/TempestKeep/botanica/boss_commander_sarannis.cpp - Outland/TempestKeep/botanica/thorngrin_the_tender.cpp + Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp Outland/TempestKeep/botanica/boss_warp_splinter.cpp Outland/TempestKeep/botanica/boss_laj.cpp diff --git a/src/server/scripts/Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp b/src/server/scripts/Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp new file mode 100644 index 00000000000..ffd48f4dcb5 --- /dev/null +++ b/src/server/scripts/Outland/TempestKeep/botanica/boss_thorngrin_the_tender.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_botanica.h" + +enum Says +{ + SAY_AGGRO = 0, + SAY_20_PERCENT_HP = 1, + SAY_KILL = 2, + SAY_CAST_SACRIFICE = 3, + SAY_50_PERCENT_HP = 4, + SAY_CAST_HELLFIRE = 5, + SAY_DEATH = 6, + EMOTE_ENRAGE = 7 +}; + +enum Spells +{ + SPELL_SACRIFICE = 34661, + SPELL_HELLFIRE_NORMAL = 34659, + SPELL_HELLFIRE_HEROIC = 39131, + SPELL_ENRAGE = 34670 +}; + +enum Events +{ + EVENT_SACRIFICE = 1, + EVENT_HELLFIRE = 2, + EVENT_ENRAGE = 3 +}; + +class boss_thorngrin_the_tender : public CreatureScript +{ + public: boss_thorngrin_the_tender() : CreatureScript("thorngrin_the_tender") { } + + struct boss_thorngrin_the_tenderAI : public BossAI + { + boss_thorngrin_the_tenderAI(Creature* creature) : BossAI(creature, DATA_THORNGRIN_THE_TENDER) { } + + void Reset() + { + _Reset(); + _phase1 = true; + _phase2 = true; + } + + void EnterCombat(Unit* /*who*/) + { + _EnterCombat(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_SACRIFICE, 5700); + events.ScheduleEvent(EVENT_HELLFIRE, IsHeroic() ? urand(17400, 19300) : 18000); + events.ScheduleEvent(EVENT_ENRAGE, 12000); + } + + void KilledUnit(Unit* /*victim*/) + { + Talk(SAY_KILL); + } + + void JustDied(Unit* /*killer*/) + { + _JustDied(); + Talk(SAY_DEATH); + } + + void DamageTaken(Unit* /*killer*/, uint32 &damage) + { + if (me->HealthBelowPctDamaged(50, damage) && _phase1) + { + _phase1 = false; + Talk(SAY_50_PERCENT_HP); + } + if (me->HealthBelowPctDamaged(20, damage) && _phase2) + { + _phase2 = false; + Talk(SAY_20_PERCENT_HP); + } + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SACRIFICE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + { + Talk(SAY_CAST_SACRIFICE); + DoCast(target, SPELL_SACRIFICE, true); + } + events.ScheduleEvent(EVENT_SACRIFICE, 29400); + break; + case EVENT_HELLFIRE: + Talk(SAY_CAST_HELLFIRE); + DoCastVictim(DUNGEON_MODE(SPELL_HELLFIRE_NORMAL, SPELL_HELLFIRE_HEROIC), true); + events.ScheduleEvent(EVENT_HELLFIRE, IsHeroic() ? urand(17400, 19300) : 18000); + break; + case EVENT_ENRAGE: + Talk(EMOTE_ENRAGE); + DoCast(me, SPELL_ENRAGE); + events.ScheduleEvent(EVENT_ENRAGE, 33000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool _phase1; + bool _phase2; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_thorngrin_the_tenderAI(creature); + } +}; + +void AddSC_boss_thorngrin_the_tender() +{ + new boss_thorngrin_the_tender(); +} diff --git a/src/server/scripts/Outland/TempestKeep/botanica/thorngrin_the_tender.cpp b/src/server/scripts/Outland/TempestKeep/botanica/thorngrin_the_tender.cpp deleted file mode 100644 index ffd48f4dcb5..00000000000 --- a/src/server/scripts/Outland/TempestKeep/botanica/thorngrin_the_tender.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "the_botanica.h" - -enum Says -{ - SAY_AGGRO = 0, - SAY_20_PERCENT_HP = 1, - SAY_KILL = 2, - SAY_CAST_SACRIFICE = 3, - SAY_50_PERCENT_HP = 4, - SAY_CAST_HELLFIRE = 5, - SAY_DEATH = 6, - EMOTE_ENRAGE = 7 -}; - -enum Spells -{ - SPELL_SACRIFICE = 34661, - SPELL_HELLFIRE_NORMAL = 34659, - SPELL_HELLFIRE_HEROIC = 39131, - SPELL_ENRAGE = 34670 -}; - -enum Events -{ - EVENT_SACRIFICE = 1, - EVENT_HELLFIRE = 2, - EVENT_ENRAGE = 3 -}; - -class boss_thorngrin_the_tender : public CreatureScript -{ - public: boss_thorngrin_the_tender() : CreatureScript("thorngrin_the_tender") { } - - struct boss_thorngrin_the_tenderAI : public BossAI - { - boss_thorngrin_the_tenderAI(Creature* creature) : BossAI(creature, DATA_THORNGRIN_THE_TENDER) { } - - void Reset() - { - _Reset(); - _phase1 = true; - _phase2 = true; - } - - void EnterCombat(Unit* /*who*/) - { - _EnterCombat(); - Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_SACRIFICE, 5700); - events.ScheduleEvent(EVENT_HELLFIRE, IsHeroic() ? urand(17400, 19300) : 18000); - events.ScheduleEvent(EVENT_ENRAGE, 12000); - } - - void KilledUnit(Unit* /*victim*/) - { - Talk(SAY_KILL); - } - - void JustDied(Unit* /*killer*/) - { - _JustDied(); - Talk(SAY_DEATH); - } - - void DamageTaken(Unit* /*killer*/, uint32 &damage) - { - if (me->HealthBelowPctDamaged(50, damage) && _phase1) - { - _phase1 = false; - Talk(SAY_50_PERCENT_HP); - } - if (me->HealthBelowPctDamaged(20, damage) && _phase2) - { - _phase2 = false; - Talk(SAY_20_PERCENT_HP); - } - } - - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SACRIFICE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) - { - Talk(SAY_CAST_SACRIFICE); - DoCast(target, SPELL_SACRIFICE, true); - } - events.ScheduleEvent(EVENT_SACRIFICE, 29400); - break; - case EVENT_HELLFIRE: - Talk(SAY_CAST_HELLFIRE); - DoCastVictim(DUNGEON_MODE(SPELL_HELLFIRE_NORMAL, SPELL_HELLFIRE_HEROIC), true); - events.ScheduleEvent(EVENT_HELLFIRE, IsHeroic() ? urand(17400, 19300) : 18000); - break; - case EVENT_ENRAGE: - Talk(EMOTE_ENRAGE); - DoCast(me, SPELL_ENRAGE); - events.ScheduleEvent(EVENT_ENRAGE, 33000); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - bool _phase1; - bool _phase2; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_thorngrin_the_tenderAI(creature); - } -}; - -void AddSC_boss_thorngrin_the_tender() -{ - new boss_thorngrin_the_tender(); -} -- cgit v1.2.3 From 38c55a15adcd708c76c1f813cbe265c4005f9593 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Wed, 2 Jan 2013 14:52:13 -0330 Subject: Core/Scripting: Rename zone scripts. --- src/server/scripts/EasternKingdoms/CMakeLists.txt | 46 +- .../scripts/EasternKingdoms/alterac_mountains.cpp | 35 - .../scripts/EasternKingdoms/arathi_highlands.cpp | 146 -- .../scripts/EasternKingdoms/blasted_lands.cpp | 76 - .../scripts/EasternKingdoms/burning_steppes.cpp | 158 -- src/server/scripts/EasternKingdoms/duskwood.cpp | 143 -- .../EasternKingdoms/eastern_plaguelands.cpp | 192 -- .../scripts/EasternKingdoms/eversong_woods.cpp | 634 ----- src/server/scripts/EasternKingdoms/ghostlands.cpp | 226 -- src/server/scripts/EasternKingdoms/hinterlands.cpp | 352 --- src/server/scripts/EasternKingdoms/ironforge.cpp | 99 - .../scripts/EasternKingdoms/isle_of_queldanas.cpp | 159 -- src/server/scripts/EasternKingdoms/loch_modan.cpp | 106 - .../scripts/EasternKingdoms/redridge_mountains.cpp | 173 -- .../scripts/EasternKingdoms/silvermoon_city.cpp | 111 - .../scripts/EasternKingdoms/silverpine_forest.cpp | 327 --- .../scripts/EasternKingdoms/stormwind_city.cpp | 647 ----- .../scripts/EasternKingdoms/stranglethorn_vale.cpp | 129 - .../scripts/EasternKingdoms/swamp_of_sorrows.cpp | 155 -- .../scripts/EasternKingdoms/tirisfal_glades.cpp | 217 -- src/server/scripts/EasternKingdoms/undercity.cpp | 334 --- .../EasternKingdoms/western_plaguelands.cpp | 419 ---- src/server/scripts/EasternKingdoms/westfall.cpp | 272 --- src/server/scripts/EasternKingdoms/wetlands.cpp | 172 -- .../EasternKingdoms/zone_alterac_mountains.cpp | 35 + .../EasternKingdoms/zone_arathi_highlands.cpp | 146 ++ .../scripts/EasternKingdoms/zone_blasted_lands.cpp | 76 + .../EasternKingdoms/zone_burning_steppes.cpp | 158 ++ .../scripts/EasternKingdoms/zone_duskwood.cpp | 143 ++ .../EasternKingdoms/zone_eastern_plaguelands.cpp | 192 ++ .../EasternKingdoms/zone_eversong_woods.cpp | 634 +++++ .../scripts/EasternKingdoms/zone_ghostlands.cpp | 226 ++ .../scripts/EasternKingdoms/zone_hinterlands.cpp | 352 +++ .../scripts/EasternKingdoms/zone_ironforge.cpp | 99 + .../EasternKingdoms/zone_isle_of_queldanas.cpp | 159 ++ .../scripts/EasternKingdoms/zone_loch_modan.cpp | 106 + .../EasternKingdoms/zone_redridge_mountains.cpp | 173 ++ .../EasternKingdoms/zone_silvermoon_city.cpp | 111 + .../EasternKingdoms/zone_silverpine_forest.cpp | 327 +++ .../EasternKingdoms/zone_stormwind_city.cpp | 647 +++++ .../EasternKingdoms/zone_stranglethorn_vale.cpp | 129 + .../EasternKingdoms/zone_swamp_of_sorrows.cpp | 155 ++ .../EasternKingdoms/zone_tirisfal_glades.cpp | 217 ++ .../scripts/EasternKingdoms/zone_undercity.cpp | 334 +++ .../EasternKingdoms/zone_western_plaguelands.cpp | 419 ++++ .../scripts/EasternKingdoms/zone_westfall.cpp | 272 +++ .../scripts/EasternKingdoms/zone_wetlands.cpp | 172 ++ src/server/scripts/Kalimdor/CMakeLists.txt | 44 +- src/server/scripts/Kalimdor/ashenvale.cpp | 486 ---- src/server/scripts/Kalimdor/azshara.cpp | 525 ---- src/server/scripts/Kalimdor/azuremyst_isle.cpp | 770 ------ src/server/scripts/Kalimdor/bloodmyst_isle.cpp | 212 -- src/server/scripts/Kalimdor/darkshore.cpp | 394 --- src/server/scripts/Kalimdor/desolace.cpp | 308 --- src/server/scripts/Kalimdor/durotar.cpp | 589 ----- src/server/scripts/Kalimdor/dustwallow_marsh.cpp | 780 ------ src/server/scripts/Kalimdor/felwood.cpp | 106 - src/server/scripts/Kalimdor/feralas.cpp | 249 -- src/server/scripts/Kalimdor/moonglade.cpp | 714 ------ src/server/scripts/Kalimdor/mulgore.cpp | 327 --- src/server/scripts/Kalimdor/orgrimmar.cpp | 254 -- src/server/scripts/Kalimdor/silithus.cpp | 1515 ------------ .../scripts/Kalimdor/stonetalon_mountains.cpp | 179 -- src/server/scripts/Kalimdor/tanaris.cpp | 685 ------ src/server/scripts/Kalimdor/teldrassil.cpp | 114 - src/server/scripts/Kalimdor/the_barrens.cpp | 695 ------ src/server/scripts/Kalimdor/thousand_needles.cpp | 463 ---- src/server/scripts/Kalimdor/thunder_bluff.cpp | 147 -- src/server/scripts/Kalimdor/ungoro_crater.cpp | 348 --- src/server/scripts/Kalimdor/winterspring.cpp | 72 - src/server/scripts/Kalimdor/zone_ashenvale.cpp | 486 ++++ src/server/scripts/Kalimdor/zone_azshara.cpp | 525 ++++ .../scripts/Kalimdor/zone_azuremyst_isle.cpp | 770 ++++++ .../scripts/Kalimdor/zone_bloodmyst_isle.cpp | 212 ++ src/server/scripts/Kalimdor/zone_darkshore.cpp | 394 +++ src/server/scripts/Kalimdor/zone_desolace.cpp | 308 +++ src/server/scripts/Kalimdor/zone_durotar.cpp | 589 +++++ .../scripts/Kalimdor/zone_dustwallow_marsh.cpp | 780 ++++++ src/server/scripts/Kalimdor/zone_felwood.cpp | 106 + src/server/scripts/Kalimdor/zone_feralas.cpp | 249 ++ src/server/scripts/Kalimdor/zone_moonglade.cpp | 714 ++++++ src/server/scripts/Kalimdor/zone_mulgore.cpp | 327 +++ src/server/scripts/Kalimdor/zone_orgrimmar.cpp | 254 ++ src/server/scripts/Kalimdor/zone_silithus.cpp | 1515 ++++++++++++ .../scripts/Kalimdor/zone_stonetalon_mountains.cpp | 179 ++ src/server/scripts/Kalimdor/zone_tanaris.cpp | 685 ++++++ src/server/scripts/Kalimdor/zone_teldrassil.cpp | 114 + src/server/scripts/Kalimdor/zone_the_barrens.cpp | 695 ++++++ .../scripts/Kalimdor/zone_thousand_needles.cpp | 463 ++++ src/server/scripts/Kalimdor/zone_thunder_bluff.cpp | 147 ++ src/server/scripts/Kalimdor/zone_ungoro_crater.cpp | 348 +++ src/server/scripts/Kalimdor/zone_winterspring.cpp | 72 + src/server/scripts/Northrend/CMakeLists.txt | 22 +- src/server/scripts/Northrend/borean_tundra.cpp | 2537 -------------------- .../scripts/Northrend/crystalsong_forest.cpp | 112 - src/server/scripts/Northrend/dalaran.cpp | 177 -- src/server/scripts/Northrend/dragonblight.cpp | 309 --- src/server/scripts/Northrend/grizzly_hills.cpp | 705 ------ src/server/scripts/Northrend/howling_fjord.cpp | 440 ---- src/server/scripts/Northrend/icecrown.cpp | 878 ------- src/server/scripts/Northrend/sholazar_basin.cpp | 1048 -------- src/server/scripts/Northrend/storm_peaks.cpp | 629 ----- src/server/scripts/Northrend/wintergrasp.cpp | 624 ----- .../scripts/Northrend/zone_borean_tundra.cpp | 2537 ++++++++++++++++++++ .../scripts/Northrend/zone_crystalsong_forest.cpp | 112 + src/server/scripts/Northrend/zone_dalaran.cpp | 177 ++ src/server/scripts/Northrend/zone_dragonblight.cpp | 309 +++ .../scripts/Northrend/zone_grizzly_hills.cpp | 705 ++++++ .../scripts/Northrend/zone_howling_fjord.cpp | 440 ++++ src/server/scripts/Northrend/zone_icecrown.cpp | 878 +++++++ .../scripts/Northrend/zone_sholazar_basin.cpp | 1048 ++++++++ src/server/scripts/Northrend/zone_storm_peaks.cpp | 629 +++++ src/server/scripts/Northrend/zone_wintergrasp.cpp | 624 +++++ src/server/scripts/Northrend/zone_zuldrak.cpp | 1431 +++++++++++ src/server/scripts/Northrend/zuldrak.cpp | 1431 ----------- src/server/scripts/Outland/CMakeLists.txt | 16 +- .../scripts/Outland/blades_edge_mountains.cpp | 1157 --------- src/server/scripts/Outland/hellfire_peninsula.cpp | 522 ---- src/server/scripts/Outland/nagrand.cpp | 708 ------ src/server/scripts/Outland/netherstorm.cpp | 1077 --------- src/server/scripts/Outland/shadowmoon_valley.cpp | 1998 --------------- src/server/scripts/Outland/shattrath_city.cpp | 739 ------ src/server/scripts/Outland/terokkar_forest.cpp | 715 ------ src/server/scripts/Outland/zangarmarsh.cpp | 459 ---- .../scripts/Outland/zone_blades_edge_mountains.cpp | 1157 +++++++++ .../scripts/Outland/zone_hellfire_peninsula.cpp | 522 ++++ src/server/scripts/Outland/zone_nagrand.cpp | 708 ++++++ src/server/scripts/Outland/zone_netherstorm.cpp | 1077 +++++++++ .../scripts/Outland/zone_shadowmoon_valley.cpp | 1998 +++++++++++++++ src/server/scripts/Outland/zone_shattrath_city.cpp | 739 ++++++ .../scripts/Outland/zone_terokkar_forest.cpp | 715 ++++++ src/server/scripts/Outland/zone_zangarmarsh.cpp | 459 ++++ 132 files changed, 31543 insertions(+), 31543 deletions(-) delete mode 100644 src/server/scripts/EasternKingdoms/alterac_mountains.cpp delete mode 100644 src/server/scripts/EasternKingdoms/arathi_highlands.cpp delete mode 100644 src/server/scripts/EasternKingdoms/blasted_lands.cpp delete mode 100644 src/server/scripts/EasternKingdoms/burning_steppes.cpp delete mode 100644 src/server/scripts/EasternKingdoms/duskwood.cpp delete mode 100644 src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp delete mode 100644 src/server/scripts/EasternKingdoms/eversong_woods.cpp delete mode 100644 src/server/scripts/EasternKingdoms/ghostlands.cpp delete mode 100644 src/server/scripts/EasternKingdoms/hinterlands.cpp delete mode 100644 src/server/scripts/EasternKingdoms/ironforge.cpp delete mode 100644 src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp delete mode 100644 src/server/scripts/EasternKingdoms/loch_modan.cpp delete mode 100644 src/server/scripts/EasternKingdoms/redridge_mountains.cpp delete mode 100644 src/server/scripts/EasternKingdoms/silvermoon_city.cpp delete mode 100644 src/server/scripts/EasternKingdoms/silverpine_forest.cpp delete mode 100644 src/server/scripts/EasternKingdoms/stormwind_city.cpp delete mode 100644 src/server/scripts/EasternKingdoms/stranglethorn_vale.cpp delete mode 100644 src/server/scripts/EasternKingdoms/swamp_of_sorrows.cpp delete mode 100644 src/server/scripts/EasternKingdoms/tirisfal_glades.cpp delete mode 100644 src/server/scripts/EasternKingdoms/undercity.cpp delete mode 100644 src/server/scripts/EasternKingdoms/western_plaguelands.cpp delete mode 100644 src/server/scripts/EasternKingdoms/westfall.cpp delete mode 100644 src/server/scripts/EasternKingdoms/wetlands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_alterac_mountains.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_duskwood.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_ghostlands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_hinterlands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_ironforge.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_loch_modan.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_silvermoon_city.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_undercity.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_westfall.cpp create mode 100644 src/server/scripts/EasternKingdoms/zone_wetlands.cpp delete mode 100644 src/server/scripts/Kalimdor/ashenvale.cpp delete mode 100644 src/server/scripts/Kalimdor/azshara.cpp delete mode 100644 src/server/scripts/Kalimdor/azuremyst_isle.cpp delete mode 100644 src/server/scripts/Kalimdor/bloodmyst_isle.cpp delete mode 100644 src/server/scripts/Kalimdor/darkshore.cpp delete mode 100644 src/server/scripts/Kalimdor/desolace.cpp delete mode 100644 src/server/scripts/Kalimdor/durotar.cpp delete mode 100644 src/server/scripts/Kalimdor/dustwallow_marsh.cpp delete mode 100644 src/server/scripts/Kalimdor/felwood.cpp delete mode 100644 src/server/scripts/Kalimdor/feralas.cpp delete mode 100644 src/server/scripts/Kalimdor/moonglade.cpp delete mode 100644 src/server/scripts/Kalimdor/mulgore.cpp delete mode 100644 src/server/scripts/Kalimdor/orgrimmar.cpp delete mode 100644 src/server/scripts/Kalimdor/silithus.cpp delete mode 100644 src/server/scripts/Kalimdor/stonetalon_mountains.cpp delete mode 100644 src/server/scripts/Kalimdor/tanaris.cpp delete mode 100644 src/server/scripts/Kalimdor/teldrassil.cpp delete mode 100644 src/server/scripts/Kalimdor/the_barrens.cpp delete mode 100644 src/server/scripts/Kalimdor/thousand_needles.cpp delete mode 100644 src/server/scripts/Kalimdor/thunder_bluff.cpp delete mode 100644 src/server/scripts/Kalimdor/ungoro_crater.cpp delete mode 100644 src/server/scripts/Kalimdor/winterspring.cpp create mode 100644 src/server/scripts/Kalimdor/zone_ashenvale.cpp create mode 100644 src/server/scripts/Kalimdor/zone_azshara.cpp create mode 100644 src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp create mode 100644 src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp create mode 100644 src/server/scripts/Kalimdor/zone_darkshore.cpp create mode 100644 src/server/scripts/Kalimdor/zone_desolace.cpp create mode 100644 src/server/scripts/Kalimdor/zone_durotar.cpp create mode 100644 src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp create mode 100644 src/server/scripts/Kalimdor/zone_felwood.cpp create mode 100644 src/server/scripts/Kalimdor/zone_feralas.cpp create mode 100644 src/server/scripts/Kalimdor/zone_moonglade.cpp create mode 100644 src/server/scripts/Kalimdor/zone_mulgore.cpp create mode 100644 src/server/scripts/Kalimdor/zone_orgrimmar.cpp create mode 100644 src/server/scripts/Kalimdor/zone_silithus.cpp create mode 100644 src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp create mode 100644 src/server/scripts/Kalimdor/zone_tanaris.cpp create mode 100644 src/server/scripts/Kalimdor/zone_teldrassil.cpp create mode 100644 src/server/scripts/Kalimdor/zone_the_barrens.cpp create mode 100644 src/server/scripts/Kalimdor/zone_thousand_needles.cpp create mode 100644 src/server/scripts/Kalimdor/zone_thunder_bluff.cpp create mode 100644 src/server/scripts/Kalimdor/zone_ungoro_crater.cpp create mode 100644 src/server/scripts/Kalimdor/zone_winterspring.cpp delete mode 100644 src/server/scripts/Northrend/borean_tundra.cpp delete mode 100644 src/server/scripts/Northrend/crystalsong_forest.cpp delete mode 100644 src/server/scripts/Northrend/dalaran.cpp delete mode 100644 src/server/scripts/Northrend/dragonblight.cpp delete mode 100644 src/server/scripts/Northrend/grizzly_hills.cpp delete mode 100644 src/server/scripts/Northrend/howling_fjord.cpp delete mode 100644 src/server/scripts/Northrend/icecrown.cpp delete mode 100644 src/server/scripts/Northrend/sholazar_basin.cpp delete mode 100644 src/server/scripts/Northrend/storm_peaks.cpp delete mode 100644 src/server/scripts/Northrend/wintergrasp.cpp create mode 100644 src/server/scripts/Northrend/zone_borean_tundra.cpp create mode 100644 src/server/scripts/Northrend/zone_crystalsong_forest.cpp create mode 100644 src/server/scripts/Northrend/zone_dalaran.cpp create mode 100644 src/server/scripts/Northrend/zone_dragonblight.cpp create mode 100644 src/server/scripts/Northrend/zone_grizzly_hills.cpp create mode 100644 src/server/scripts/Northrend/zone_howling_fjord.cpp create mode 100644 src/server/scripts/Northrend/zone_icecrown.cpp create mode 100644 src/server/scripts/Northrend/zone_sholazar_basin.cpp create mode 100644 src/server/scripts/Northrend/zone_storm_peaks.cpp create mode 100644 src/server/scripts/Northrend/zone_wintergrasp.cpp create mode 100644 src/server/scripts/Northrend/zone_zuldrak.cpp delete mode 100644 src/server/scripts/Northrend/zuldrak.cpp delete mode 100644 src/server/scripts/Outland/blades_edge_mountains.cpp delete mode 100644 src/server/scripts/Outland/hellfire_peninsula.cpp delete mode 100644 src/server/scripts/Outland/nagrand.cpp delete mode 100644 src/server/scripts/Outland/netherstorm.cpp delete mode 100644 src/server/scripts/Outland/shadowmoon_valley.cpp delete mode 100644 src/server/scripts/Outland/shattrath_city.cpp delete mode 100644 src/server/scripts/Outland/terokkar_forest.cpp delete mode 100644 src/server/scripts/Outland/zangarmarsh.cpp create mode 100644 src/server/scripts/Outland/zone_blades_edge_mountains.cpp create mode 100644 src/server/scripts/Outland/zone_hellfire_peninsula.cpp create mode 100644 src/server/scripts/Outland/zone_nagrand.cpp create mode 100644 src/server/scripts/Outland/zone_netherstorm.cpp create mode 100644 src/server/scripts/Outland/zone_shadowmoon_valley.cpp create mode 100644 src/server/scripts/Outland/zone_shattrath_city.cpp create mode 100644 src/server/scripts/Outland/zone_terokkar_forest.cpp create mode 100644 src/server/scripts/Outland/zone_zangarmarsh.cpp (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index 854124ee05c..bbdbe396a95 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -10,8 +10,8 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} - EasternKingdoms/ghostlands.cpp - EasternKingdoms/eversong_woods.cpp + EasternKingdoms/zone_ghostlands.cpp + EasternKingdoms/zone_eversong_woods.cpp EasternKingdoms/AlteracValley/boss_galvangar.cpp EasternKingdoms/AlteracValley/boss_balinda.cpp EasternKingdoms/AlteracValley/boss_drekthar.cpp @@ -31,7 +31,7 @@ set(scripts_STAT_SRCS EasternKingdoms/Scholomance/instance_scholomance.cpp EasternKingdoms/Scholomance/boss_lorekeeper_polkelt.cpp EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp - EasternKingdoms/isle_of_queldanas.cpp + EasternKingdoms/zone_isle_of_queldanas.cpp EasternKingdoms/boss_kruul.cpp EasternKingdoms/ZulGurub/boss_hakkar.cpp EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -48,12 +48,12 @@ set(scripts_STAT_SRCS EasternKingdoms/ZulGurub/boss_jindo.cpp EasternKingdoms/ZulGurub/boss_wushoolay.cpp EasternKingdoms/ZulGurub/boss_thekal.cpp - EasternKingdoms/wetlands.cpp - EasternKingdoms/arathi_highlands.cpp + EasternKingdoms/zone_wetlands.cpp + EasternKingdoms/zone_arathi_highlands.cpp EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp EasternKingdoms/Gnomeregan/gnomeregan.cpp EasternKingdoms/Gnomeregan/gnomeregan.h - EasternKingdoms/redridge_mountains.cpp + EasternKingdoms/zone_redridge_mountains.cpp EasternKingdoms/BlackrockDepths/boss_high_interrogator_gerstahn.cpp EasternKingdoms/BlackrockDepths/boss_gorosh_the_dervish.cpp EasternKingdoms/BlackrockDepths/blackrock_depths.cpp @@ -67,12 +67,12 @@ set(scripts_STAT_SRCS EasternKingdoms/BlackrockDepths/blackrock_depths.h EasternKingdoms/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp EasternKingdoms/BlackrockDepths/boss_magmus.cpp - EasternKingdoms/ironforge.cpp + EasternKingdoms/zone_ironforge.cpp EasternKingdoms/ScarletEnclave/chapter2.cpp EasternKingdoms/ScarletEnclave/chapter5.cpp EasternKingdoms/ScarletEnclave/chapter1.cpp EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp - EasternKingdoms/eastern_plaguelands.cpp + EasternKingdoms/zone_eastern_plaguelands.cpp EasternKingdoms/MoltenCore/boss_gehennas.cpp EasternKingdoms/MoltenCore/boss_lucifron.cpp EasternKingdoms/MoltenCore/boss_golemagg.cpp @@ -99,7 +99,7 @@ set(scripts_STAT_SRCS EasternKingdoms/Stratholme/boss_postmaster_malown.cpp EasternKingdoms/Stratholme/stratholme.h EasternKingdoms/Stratholme/stratholme.cpp - EasternKingdoms/tirisfal_glades.cpp + EasternKingdoms/zone_tirisfal_glades.cpp EasternKingdoms/SunkenTemple/sunken_temple.cpp EasternKingdoms/SunkenTemple/sunken_temple.h EasternKingdoms/SunkenTemple/instance_sunken_temple.cpp @@ -115,7 +115,7 @@ set(scripts_STAT_SRCS EasternKingdoms/Uldaman/uldaman.h EasternKingdoms/Uldaman/instance_uldaman.cpp EasternKingdoms/Uldaman/boss_archaedas.cpp - EasternKingdoms/swamp_of_sorrows.cpp + EasternKingdoms/zone_swamp_of_sorrows.cpp EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp EasternKingdoms/BlackrockSpire/boss_drakkisath.cpp EasternKingdoms/BlackrockSpire/boss_warmaster_voone.cpp @@ -139,12 +139,12 @@ set(scripts_STAT_SRCS EasternKingdoms/SunwellPlateau/boss_brutallus.cpp EasternKingdoms/SunwellPlateau/sunwell_plateau.cpp EasternKingdoms/SunwellPlateau/boss_felmyst.cpp - EasternKingdoms/stranglethorn_vale.cpp + EasternKingdoms/zone_stranglethorn_vale.cpp EasternKingdoms/Deadmines/deadmines.h EasternKingdoms/Deadmines/deadmines.cpp EasternKingdoms/Deadmines/boss_mr_smite.cpp EasternKingdoms/Deadmines/instance_deadmines.cpp - EasternKingdoms/duskwood.cpp + EasternKingdoms/zone_duskwood.cpp EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp @@ -157,13 +157,13 @@ set(scripts_STAT_SRCS EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp EasternKingdoms/ScarletMonastery/boss_herod.cpp EasternKingdoms/ScarletMonastery/boss_scorn.cpp - EasternKingdoms/undercity.cpp - EasternKingdoms/silvermoon_city.cpp - EasternKingdoms/loch_modan.cpp + EasternKingdoms/zone_undercity.cpp + EasternKingdoms/zone_silvermoon_city.cpp + EasternKingdoms/zone_loch_modan.cpp EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp EasternKingdoms/ShadowfangKeep/instance_shadowfang_keep.cpp EasternKingdoms/ShadowfangKeep/shadowfang_keep.h - EasternKingdoms/burning_steppes.cpp + EasternKingdoms/zone_burning_steppes.cpp EasternKingdoms/BlackwingLair/boss_chromaggus.cpp EasternKingdoms/BlackwingLair/boss_razorgore.cpp EasternKingdoms/BlackwingLair/boss_firemaw.cpp @@ -174,8 +174,8 @@ set(scripts_STAT_SRCS EasternKingdoms/BlackwingLair/boss_nefarian.cpp EasternKingdoms/BlackwingLair/boss_flamegor.cpp EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp - EasternKingdoms/blasted_lands.cpp - EasternKingdoms/stormwind_city.cpp + EasternKingdoms/zone_blasted_lands.cpp + EasternKingdoms/zone_stormwind_city.cpp EasternKingdoms/ZulAman/boss_halazzi.cpp EasternKingdoms/ZulAman/boss_hexlord.cpp EasternKingdoms/ZulAman/boss_zuljin.cpp @@ -185,11 +185,11 @@ set(scripts_STAT_SRCS EasternKingdoms/ZulAman/boss_nalorakk.cpp EasternKingdoms/ZulAman/zulaman.cpp EasternKingdoms/ZulAman/zulaman.h - EasternKingdoms/hinterlands.cpp - EasternKingdoms/western_plaguelands.cpp - EasternKingdoms/alterac_mountains.cpp - EasternKingdoms/westfall.cpp - EasternKingdoms/silverpine_forest.cpp + EasternKingdoms/zone_hinterlands.cpp + EasternKingdoms/zone_western_plaguelands.cpp + EasternKingdoms/zone_alterac_mountains.cpp + EasternKingdoms/zone_westfall.cpp + EasternKingdoms/zone_silverpine_forest.cpp EasternKingdoms/Karazhan/instance_karazhan.cpp EasternKingdoms/Karazhan/boss_nightbane.cpp EasternKingdoms/Karazhan/karazhan.cpp diff --git a/src/server/scripts/EasternKingdoms/alterac_mountains.cpp b/src/server/scripts/EasternKingdoms/alterac_mountains.cpp deleted file mode 100644 index 9b9af494554..00000000000 --- a/src/server/scripts/EasternKingdoms/alterac_mountains.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Alterac_Mountains -SD%Complete: 0 -SDComment: Placeholder -SDCategory: Alterac Mountains -EndScriptData */ - -/* ContentData -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" - -/*void AddSC_alterac_mountains() -{ - Script* newscript; -}*/ diff --git a/src/server/scripts/EasternKingdoms/arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/arathi_highlands.cpp deleted file mode 100644 index d638a435936..00000000000 --- a/src/server/scripts/EasternKingdoms/arathi_highlands.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Arathi Highlands -SD%Complete: 100 -SDComment: Quest support: 665 -SDCategory: Arathi Highlands -EndScriptData */ - -/* ContentData -npc_professor_phizzlethorpe -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_professor_phizzlethorpe -######*/ - -enum eEnums -{ - SAY_PROGRESS_1 = 0, - SAY_PROGRESS_2 = 1, - SAY_PROGRESS_3 = 2, - EMOTE_PROGRESS_4 = 3, - SAY_AGGRO = 4, - SAY_PROGRESS_5 = 5, - SAY_PROGRESS_6 = 6, - SAY_PROGRESS_7 = 7, - EMOTE_PROGRESS_8 = 8, - SAY_PROGRESS_9 = 9, - - QUEST_SUNKEN_TREASURE = 665, - MOB_VENGEFUL_SURGE = 2776 -}; - -class npc_professor_phizzlethorpe : public CreatureScript -{ - public: - - npc_professor_phizzlethorpe() - : CreatureScript("npc_professor_phizzlethorpe") - { - } - - struct npc_professor_phizzlethorpeAI : public npc_escortAI - { - npc_professor_phizzlethorpeAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 4: - Talk(SAY_PROGRESS_2, player->GetGUID()); - break; - case 5: - Talk(SAY_PROGRESS_3, player->GetGUID()); - break; - case 8: - Talk(EMOTE_PROGRESS_4); - break; - case 9: - me->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); - me->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); - break; - case 10: - Talk(SAY_PROGRESS_5, player->GetGUID()); - break; - case 11: - Talk(SAY_PROGRESS_6, player->GetGUID()); - SetRun(); - break; - case 19: - Talk(SAY_PROGRESS_7, player->GetGUID()); - break; - case 20: - Talk(EMOTE_PROGRESS_8); - Talk(SAY_PROGRESS_9, player->GetGUID()); - player->GroupEventHappens(QUEST_SUNKEN_TREASURE, me); - break; - } - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void EnterCombat(Unit* /*who*/) - { - Talk(SAY_AGGRO); - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_professor_phizzlethorpeAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_SUNKEN_TREASURE) - { - creature->AI()->Talk(SAY_PROGRESS_1, player->GetGUID()); - if (npc_escortAI* pEscortAI = CAST_AI(npc_professor_phizzlethorpeAI, (creature->AI()))) - pEscortAI->Start(false, false, player->GetGUID(), quest); - - creature->setFaction(113); - } - return true; - } -}; - -void AddSC_arathi_highlands() -{ - new npc_professor_phizzlethorpe(); -} diff --git a/src/server/scripts/EasternKingdoms/blasted_lands.cpp b/src/server/scripts/EasternKingdoms/blasted_lands.cpp deleted file mode 100644 index 4f76edf4406..00000000000 --- a/src/server/scripts/EasternKingdoms/blasted_lands.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Blasted_Lands -SD%Complete: 90 -SDComment: Quest support: 3628. Teleporter to Rise of the Defiler missing group support. -SDCategory: Blasted Lands -EndScriptData */ - -/* ContentData -npc_deathly_usher -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_deathly_usher -######*/ - -#define GOSSIP_ITEM_USHER "I wish to to visit the Rise of the Defiler." - -#define SPELL_TELEPORT_SINGLE 12885 -#define SPELL_TELEPORT_SINGLE_IN_GROUP 13142 -#define SPELL_TELEPORT_GROUP 27686 - -class npc_deathly_usher : public CreatureScript -{ -public: - npc_deathly_usher() : CreatureScript("npc_deathly_usher") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_TELEPORT_SINGLE, true); - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(3628) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(10757)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_USHER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -void AddSC_blasted_lands() -{ - new npc_deathly_usher(); -} diff --git a/src/server/scripts/EasternKingdoms/burning_steppes.cpp b/src/server/scripts/EasternKingdoms/burning_steppes.cpp deleted file mode 100644 index b6899c534e4..00000000000 --- a/src/server/scripts/EasternKingdoms/burning_steppes.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Burning_Steppes -SD%Complete: 100 -SDComment: Quest support: 4224, 4866 -SDCategory: Burning Steppes -EndScriptData */ - -/* ContentData -npc_ragged_john -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_ragged_john -######*/ - -#define GOSSIP_HELLO "Official buisness, John. I need some information about Marsha Windsor. Tell me about the last time you saw him." -#define GOSSIP_SELECT1 "So what did you do?" -#define GOSSIP_SELECT2 "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'." -#define GOSSIP_SELECT3 "Ironfoe?" -#define GOSSIP_SELECT4 "Interesting... continue John." -#define GOSSIP_SELECT5 "So that's how Windsor died..." -#define GOSSIP_SELECT6 "So how did he die?" -#define GOSSIP_SELECT7 "Ok so where the hell is he? Wait a minute! Are you drunk?" -#define GOSSIP_SELECT8 "WHY is he in Blackrock Depths?" -#define GOSSIP_SELECT9 "300? So the Dark Irons killed him and dragged him into the Depths?" -#define GOSSIP_SELECT10 "Ahh... Ironfoe" -#define GOSSIP_SELECT11 "Thanks, Ragged John. Your story was very uplifting and informative" - -class npc_ragged_john : public CreatureScript -{ -public: - npc_ragged_john() : CreatureScript("npc_ragged_john") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2714, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2715, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2716, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(2717, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(2718, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(2719, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(2720, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); - player->SEND_GOSSIP_MENU(2721, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+8: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); - player->SEND_GOSSIP_MENU(2722, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+9: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); - player->SEND_GOSSIP_MENU(2723, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+10: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - player->SEND_GOSSIP_MENU(2725, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+11: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(4224); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(4224) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(2713, creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ragged_johnAI (creature); - } - - struct npc_ragged_johnAI : public ScriptedAI - { - npc_ragged_johnAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - - void MoveInLineOfSight(Unit* who) - { - if (who->HasAura(16468)) - { - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 15) && who->isInAccessiblePlaceFor(me)) - { - DoCast(who, 16472); - CAST_PLR(who)->AreaExploredOrEventHappens(4866); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void EnterCombat(Unit* /*who*/) {} - }; -}; - -void AddSC_burning_steppes() -{ - new npc_ragged_john(); -} diff --git a/src/server/scripts/EasternKingdoms/duskwood.cpp b/src/server/scripts/EasternKingdoms/duskwood.cpp deleted file mode 100644 index 1ce83d31a63..00000000000 --- a/src/server/scripts/EasternKingdoms/duskwood.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Duskwood -SD%Complete: 100 -SDComment: Quest Support:8735 -SDCategory: Duskwood -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" - -enum Yells -{ - YELL_TWILIGHTCORRUPTOR_RESPAWN = 0, - YELL_TWILIGHTCORRUPTOR_AGGRO = 1, - YELL_TWILIGHTCORRUPTOR_KILL = 2, -}; - - -/*###### -# at_twilight_grove -######*/ - -class at_twilight_grove : public AreaTriggerScript -{ -public: - at_twilight_grove() : AreaTriggerScript("at_twilight_grove") { } - - bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) - { - if (player->HasQuestForItem(21149)) - { - if (Unit* TCorrupter = player->SummonCreature(15625, -10328.16f, -489.57f, 49.95f, 0, TEMPSUMMON_MANUAL_DESPAWN, 60000)) - { - TCorrupter->setFaction(14); - TCorrupter->SetMaxHealth(832750); - } - if (Creature* CorrupterSpeaker = player->SummonCreature(1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()-1, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) - { - CorrupterSpeaker->SetName("Twilight Corrupter"); - CorrupterSpeaker->SetVisible(true); - CorrupterSpeaker->AI()->Talk(YELL_TWILIGHTCORRUPTOR_RESPAWN, player->GetGUID()); - } - } - return false; - }; -}; - -/*###### -# boss_twilight_corrupter -######*/ - -#define SPELL_SOUL_CORRUPTION 25805 -#define SPELL_CREATURE_OF_NIGHTMARE 25806 -#define SPELL_LEVEL_UP 24312 - -class boss_twilight_corrupter : public CreatureScript -{ -public: - boss_twilight_corrupter() : CreatureScript("boss_twilight_corrupter") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_twilight_corrupterAI (creature); - } - - struct boss_twilight_corrupterAI : public ScriptedAI - { - boss_twilight_corrupterAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 SoulCorruption_Timer; - uint32 CreatureOfNightmare_Timer; - uint8 KillCount; - - void Reset() - { - SoulCorruption_Timer = 15000; - CreatureOfNightmare_Timer = 30000; - KillCount = 0; - } - void EnterCombat(Unit* /*who*/) - { - Talk(YELL_TWILIGHTCORRUPTOR_AGGRO); - } - - void KilledUnit(Unit* victim) - { - if (victim->GetTypeId() == TYPEID_PLAYER) - { - ++KillCount; - Talk(YELL_TWILIGHTCORRUPTOR_KILL, victim->GetGUID()); - - if (KillCount == 3) - { - DoCast(me, SPELL_LEVEL_UP, true); - KillCount = 0; - } - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - if (SoulCorruption_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SOUL_CORRUPTION); - SoulCorruption_Timer = rand()%4000+15000; //gotta confirm Timers - } else SoulCorruption_Timer-=diff; - - if (CreatureOfNightmare_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_CREATURE_OF_NIGHTMARE); - CreatureOfNightmare_Timer = 45000; //gotta confirm Timers - } else CreatureOfNightmare_Timer-=diff; - DoMeleeAttackIfReady(); - }; - }; -}; - -void AddSC_duskwood() -{ - new boss_twilight_corrupter(); - new at_twilight_grove(); -} diff --git a/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp b/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp deleted file mode 100644 index a2522fd9495..00000000000 --- a/src/server/scripts/EasternKingdoms/eastern_plaguelands.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Eastern_Plaguelands -SD%Complete: 100 -SDComment: Quest support: 5211, 5742. Special vendor Augustus the Touched -SDCategory: Eastern Plaguelands -EndScriptData */ - -/* ContentData -mobs_ghoul_flayer -npc_augustus_the_touched -npc_darrowshire_spirit -npc_tirion_fordring -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "WorldSession.h" - -class mobs_ghoul_flayer : public CreatureScript -{ -public: - mobs_ghoul_flayer() : CreatureScript("mobs_ghoul_flayer") { } - - struct mobs_ghoul_flayerAI : public ScriptedAI - { - mobs_ghoul_flayerAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() {} - - void EnterCombat(Unit* /*who*/) {} - - void JustDied(Unit* killer) - { - if (killer->GetTypeId() == TYPEID_PLAYER) - me->SummonCreature(11064, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mobs_ghoul_flayerAI (creature); - } -}; - -/*###### -## npc_augustus_the_touched -######*/ - -class npc_augustus_the_touched : public CreatureScript -{ -public: - npc_augustus_the_touched() : CreatureScript("npc_augustus_the_touched") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor() && player->GetQuestRewardStatus(6164)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_darrowshire_spirit -######*/ - -#define SPELL_SPIRIT_SPAWNIN 17321 - -class npc_darrowshire_spirit : public CreatureScript -{ -public: - npc_darrowshire_spirit() : CreatureScript("npc_darrowshire_spirit") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - player->SEND_GOSSIP_MENU(3873, creature->GetGUID()); - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_darrowshire_spiritAI (creature); - } - - struct npc_darrowshire_spiritAI : public ScriptedAI - { - npc_darrowshire_spiritAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - DoCast(me, SPELL_SPIRIT_SPAWNIN); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - - void EnterCombat(Unit* /*who*/) {} - }; -}; - -/*###### -## npc_tirion_fordring -######*/ - -#define GOSSIP_HELLO "I am ready to hear your tale, Tirion." -#define GOSSIP_SELECT1 "Thank you, Tirion. What of your identity?" -#define GOSSIP_SELECT2 "That is terrible." -#define GOSSIP_SELECT3 "I will, Tirion." - -class npc_tirion_fordring : public CreatureScript -{ -public: - npc_tirion_fordring() : CreatureScript("npc_tirion_fordring") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(4493, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(4494, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(4495, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(5742); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == UNIT_STAND_STATE_SIT) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -void AddSC_eastern_plaguelands() -{ - new mobs_ghoul_flayer(); - new npc_augustus_the_touched(); - new npc_darrowshire_spirit(); - new npc_tirion_fordring(); -} diff --git a/src/server/scripts/EasternKingdoms/eversong_woods.cpp b/src/server/scripts/EasternKingdoms/eversong_woods.cpp deleted file mode 100644 index 432768a51de..00000000000 --- a/src/server/scripts/EasternKingdoms/eversong_woods.cpp +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Eversong_Woods -SD%Complete: 100 -SDComment: Quest support: 8483, 8488, 8490, 9686 -SDCategory: Eversong Woods -EndScriptData */ - -/* ContentData -npc_prospector_anvilward -npc_apprentice_mirveda -npc_infused_crystal -npc_kelerun_bloodmourn -go_harbinger_second_trial -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## Quest 9686 Second Trial -######*/ - -enum SeconTrial -{ - QUEST_SECOND_TRIAL = 9686, - OFFSET_NEXT_ATTACK = 750, -}; - -enum eSpells -{ - SPELL_FLASH_OF_LIGHT = 19939, - SPELL_SEAL_OF_JUSTICE = 20164, - SPELL_JUDGEMENT_OF_LIGHT = 20271, - SPELL_SEAL_OF_COMMAND = 20375, -}; - -enum eNpc -{ - MASTER_KELERUN_BLOODMOURN = 17807, - CHAMPION_BLOODWRATH = 17809, - CHAMPION_LIGHTREND = 17810, - CHAMPION_SWIFTBLADE = 17811, - CHAMPION_SUNSTRIKER = 17812, -}; - -enum eFaction -{ - FACTION_HOSTILE = 45, - FACTION_FRIENDLY = 7, -}; - -enum eSays -{ - TEXT_SECOND_TRIAL_1 = 0, - TEXT_SECOND_TRIAL_2 = 1, - TEXT_SECOND_TRIAL_3 = 2, - TEXT_SECOND_TRIAL_4 = 3, -}; - -struct Locations -{ - float x, y, z, o; -}; - -static Locations SpawnPosition[]= -{ - {5.3f, -11.8f, 0.361f, 4.2f}, - {11.2f, -29.17f, 0.361f, 2.7f}, - {-5.7f, -34.85f, 0.361f, 1.09f}, - {-11.9f, -18, 0.361f, 5.87f} -}; - -static uint32 PaladinEntry[] = {CHAMPION_BLOODWRATH, CHAMPION_LIGHTREND, CHAMPION_SWIFTBLADE, CHAMPION_SUNSTRIKER}; - -/*###### -## npc_second_trial_paladin -######*/ - -class npc_second_trial_paladin : public CreatureScript -{ -public: - npc_second_trial_paladin() : CreatureScript("npc_second_trial_paladin") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_secondTrialAI (creature); - } - - struct npc_secondTrialAI : public ScriptedAI - { - npc_secondTrialAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 timer; - uint8 questPhase; - uint64 summonerGuid; - - bool spellFlashLight; - bool spellJustice; - bool spellJudLight; - bool spellCommand; - - uint32 timerFlashLight; - uint32 timerJustice; - uint32 timerJudLight; - uint32 timerCommand; - - void Reset() - { - timer = 2000; - questPhase = 0; - summonerGuid = 0; - - me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL); - me->setFaction(FACTION_FRIENDLY); - - spellFlashLight = false; - spellJustice = false; - spellJudLight = false; - spellCommand = false; - - switch (me->GetEntry()) - { - case CHAMPION_BLOODWRATH: - spellFlashLight = true; - timerFlashLight = 3225; - break; - case CHAMPION_LIGHTREND: - spellJustice = true; - timerJustice = 500; - break; - case CHAMPION_SWIFTBLADE: - spellJudLight = false; // Misses Script Effect // http://www.wowhead.com/?spell=20271 - timerJudLight = 500; - break; - case CHAMPION_SUNSTRIKER: - spellFlashLight = true; - spellJudLight = false; // Misses Script Effect // http://www.wowhead.com/?spell=20271 - spellCommand = false; // Misses Dummy // http://www.wowhead.com/?spell=20375 - timerFlashLight = 3225; - timerJudLight = 500; - timerCommand = 1500; - break; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (questPhase == 1) - { - if (timer <= diff) - { - me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); - me->setFaction(FACTION_HOSTILE); - questPhase = 0; - - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - { - me->AddThreat(target, 5000000.0f); - AttackStart(target); - } - } - else - timer -= diff; - } - - if (!UpdateVictim()) - return; - - // healer - if (spellFlashLight && HealthBelowPct(70)) - { - if (timerFlashLight <= diff) - { - DoCast(me, SPELL_FLASH_OF_LIGHT); - timerFlashLight = 3225 + rand()%3225; - } - else - timerFlashLight -= diff; - } - - if (spellJustice) - { - if (timerJustice <= diff) - { - DoCast(me, SPELL_SEAL_OF_JUSTICE); - timerJustice = urand(10000, 20000); - } - else - timerJustice -= diff; - } - - if (spellJudLight) - { - if (timerJudLight <= diff) - { - DoCast(me, SPELL_JUDGEMENT_OF_LIGHT); - timerJudLight = urand(10000, 20000); - } - else - timerJudLight -= diff; - } - - if (spellCommand) - { - if (timerCommand <= diff) - { - DoCast(me, SPELL_SEAL_OF_COMMAND); - timerCommand = urand(20000, 40000); - } - else - timerCommand -= diff; - } - - DoMeleeAttackIfReady(); - } - - void Activate(uint64 summonerguid) - { - questPhase = 1; - summonerGuid = summonerguid; - } - - void KilledUnit(Unit* Killed) - { - if (Killed->GetTypeId() == TYPEID_PLAYER) - if (CAST_PLR(Killed)->GetQuestStatus(QUEST_SECOND_TRIAL) == QUEST_STATUS_INCOMPLETE) - CAST_PLR(Killed)->FailQuest(QUEST_SECOND_TRIAL); - } - - void JustDied(Unit* killer); - }; -}; - -/*###### -## npc_second_trial_controller -######*/ - -class npc_second_trial_controller : public CreatureScript -{ -public: - npc_second_trial_controller() : CreatureScript("npc_second_trial_controller") { } - - bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest) - { - // One Player exclusive quest, wait for user go activation - if (quest->GetQuestId() == QUEST_SECOND_TRIAL) - CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, creature->AI())->questPhase = 1; - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - // quest only available if not already started - // Quest_template flag is set to : QUEST_FLAGS_EVENT - // Escort quests or any other event-driven quests. If player in party, all players that can accept this quest will receive confirmation box to accept quest. - // !not sure if this really works! - - if (CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, creature->AI())->questPhase == 0) - { - player->PrepareQuestMenu(creature->GetGUID()); - player->SendPreparedQuest(creature->GetGUID()); - } - - player->SEND_GOSSIP_MENU(creature->GetEntry(), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new master_kelerun_bloodmournAI (creature); - } - - struct master_kelerun_bloodmournAI : public ScriptedAI - { - master_kelerun_bloodmournAI(Creature* creature) : ScriptedAI(creature) {} - - uint8 questPhase; - uint8 paladinPhase; - uint32 timer; - - uint64 paladinGuid[4]; - - void Reset() - { - questPhase = 0; - timer = 60000; - paladinPhase = 0; - for (uint8 i = 0; i < 4; ++i) - paladinGuid[i] = 0; - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - // Quest accepted but object not activated, object despawned (if in sync 1 minute!) - if (questPhase == 1) - { - if (timer <= diff) - Reset(); - else - timer -= diff; - } - // fight the 4 paladin mobs phase - else if (questPhase == 2) - { - if (timer <= diff) - { - if (Creature* paladinSpawn = Unit::GetCreature((*me), paladinGuid[paladinPhase])) - { - CAST_AI(npc_second_trial_paladin::npc_secondTrialAI, paladinSpawn->AI())->Activate(me->GetGUID()); - - switch (paladinPhase) - { - case 0: - Talk(TEXT_SECOND_TRIAL_1); - break; - case 1: - Talk(TEXT_SECOND_TRIAL_2); - break; - case 2: - Talk(TEXT_SECOND_TRIAL_3); - break; - case 3: - Talk(TEXT_SECOND_TRIAL_4); - break; - } - } - else - Reset(); - - questPhase = 4; - timer = OFFSET_NEXT_ATTACK; - } - else - timer -= diff; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void StartEvent() - { - if (questPhase == 1) - { // no player check, quest can be finished as group, so no complex PlayerGUID/group search code - for (uint8 i = 0; i < 4; ++i) - if (Creature* summoned = DoSpawnCreature(PaladinEntry[i], SpawnPosition[i].x, SpawnPosition[i].y, SpawnPosition[i].z, SpawnPosition[i].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 180000)) - paladinGuid[i] = summoned->GetGUID(); - - timer = OFFSET_NEXT_ATTACK; - questPhase = 2; - } - } - - void SecondTrialKill() - { - if (questPhase > 0) - { - ++paladinPhase; - - if (paladinPhase < 4) - questPhase = 2; - else - Reset(); // Quest Complete, QuestComplete handler is - } - } - - void SummonedCreatureDespawn(Creature* /*c*/) {} - }; -}; - -void npc_second_trial_paladin::npc_secondTrialAI::JustDied(Unit* Killer) -{ - if (Killer->GetTypeId() == TYPEID_PLAYER) - { - if (Creature* summoner = Unit::GetCreature((*me), summonerGuid)) - CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, summoner->AI())->SecondTrialKill(); - - // last kill quest complete for group - if (me->GetEntry() == CHAMPION_SUNSTRIKER) - { - if (Killer->GetTypeId() == TYPEID_PLAYER) - Killer->ToPlayer()->GroupEventHappens(QUEST_SECOND_TRIAL, Killer); - } - } -} - -/*###### -## go_second_trial -######*/ -class go_second_trial : public GameObjectScript -{ -public: - go_second_trial() : GameObjectScript("go_second_trial") { } - - bool OnGossipHello(Player* /*player*/, GameObject* go) - { - // find spawn :: master_kelerun_bloodmourn - if (Creature* creature = go->FindNearestCreature(MASTER_KELERUN_BLOODMOURN, 30.0f)) - CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, creature->AI())->StartEvent(); - - return true; - } -}; - -/*###### -## npc_apprentice_mirveda -######*/ - -#define QUEST_UNEXPECTED_RESULT 8488 -#define MOB_GHARZUL 15958 -#define MOB_ANGERSHADE 15656 - -class npc_apprentice_mirveda : public CreatureScript -{ -public: - npc_apprentice_mirveda() : CreatureScript("npc_apprentice_mirveda") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_UNEXPECTED_RESULT) - { - CAST_AI(npc_apprentice_mirveda::npc_apprentice_mirvedaAI, creature->AI())->Summon = true; - CAST_AI(npc_apprentice_mirveda::npc_apprentice_mirvedaAI, creature->AI())->PlayerGUID = player->GetGUID(); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_apprentice_mirvedaAI (creature); - } - - struct npc_apprentice_mirvedaAI : public ScriptedAI - { - npc_apprentice_mirvedaAI(Creature* creature) : ScriptedAI(creature), Summons(me) {} - - uint32 KillCount; - uint64 PlayerGUID; - bool Summon; - SummonList Summons; - - void Reset() - { - KillCount = 0; - PlayerGUID = 0; - Summons.DespawnAll(); - Summon = false; - } - - void EnterCombat(Unit* /*who*/){} - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - Summons.Summon(summoned); - } - - void SummonedCreatureDespawn(Creature* summoned) - { - Summons.Despawn(summoned); - ++KillCount; - } - - void JustDied(Unit* /*killer*/) - { - if (PlayerGUID) - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - player->FailQuest(QUEST_UNEXPECTED_RESULT); - } - - void UpdateAI(const uint32 /*diff*/) - { - if (KillCount >= 3 && PlayerGUID) - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - player->CompleteQuest(QUEST_UNEXPECTED_RESULT); - - if (Summon) - { - me->SummonCreature(MOB_GHARZUL, 8745, -7134.32f, 35.22f, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000); - me->SummonCreature(MOB_ANGERSHADE, 8745, -7134.32f, 35.22f, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000); - me->SummonCreature(MOB_ANGERSHADE, 8745, -7134.32f, 35.22f, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000); - Summon = false; - } - } - }; -}; - -/*###### -## npc_infused_crystal -######*/ - -enum InfusedCrystal -{ - MOB_ENRAGED_WRAITH = 17086, - EMOTE = 0, - QUEST_POWERING_OUR_DEFENSES = 8490 -}; - -struct Location -{ - float x, y, z; -}; - -static Location SpawnLocations[] = -{ - {8270.68f, -7188.53f, 139.619f}, - {8284.27f, -7187.78f, 139.603f}, - {8297.43f, -7193.53f, 139.603f}, - {8303.5f, -7201.96f, 139.577f}, - {8273.22f, -7241.82f, 139.382f}, - {8254.89f, -7222.12f, 139.603f}, - {8278.51f, -7242.13f, 139.162f}, - {8267.97f, -7239.17f, 139.517f} -}; - -class npc_infused_crystal : public CreatureScript -{ -public: - npc_infused_crystal() : CreatureScript("npc_infused_crystal") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_infused_crystalAI (creature); - } - - struct npc_infused_crystalAI : public Scripted_NoMovementAI - { - npc_infused_crystalAI(Creature* creature) : Scripted_NoMovementAI(creature) {} - - uint32 EndTimer; - uint32 WaveTimer; - bool Completed; - bool Progress; - uint64 PlayerGUID; - - void Reset() - { - EndTimer = 0; - Completed = false; - Progress = false; - PlayerGUID = 0; - WaveTimer = 0; - } - - void MoveInLineOfSight(Unit* who) - { - if (!Progress && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 10.0f)) - { - if (CAST_PLR(who)->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) == QUEST_STATUS_INCOMPLETE) - { - PlayerGUID = who->GetGUID(); - WaveTimer = 1000; - EndTimer = 60000; - Progress = true; - } - } - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void JustDied(Unit* /*killer*/) - { - if (PlayerGUID && !Completed) - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - CAST_PLR(player)->FailQuest(QUEST_POWERING_OUR_DEFENSES); - } - - void UpdateAI(const uint32 diff) - { - if (EndTimer < diff && Progress) - { - Talk(EMOTE); - Completed = true; - if (PlayerGUID) - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - CAST_PLR(player)->CompleteQuest(QUEST_POWERING_OUR_DEFENSES); - - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - me->RemoveCorpse(); - } else EndTimer -= diff; - - if (WaveTimer < diff && !Completed && Progress) - { - uint32 ran1 = rand()%8; - uint32 ran2 = rand()%8; - uint32 ran3 = rand()%8; - me->SummonCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran1].x, SpawnLocations[ran1].y, SpawnLocations[ran1].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); - me->SummonCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran2].x, SpawnLocations[ran2].y, SpawnLocations[ran2].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); - me->SummonCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran3].x, SpawnLocations[ran3].y, SpawnLocations[ran3].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); - WaveTimer = 30000; - } else WaveTimer -= diff; - } - }; -}; - -void AddSC_eversong_woods() -{ - new npc_second_trial_controller(); - new npc_second_trial_paladin(); - new go_second_trial(); - new npc_apprentice_mirveda(); - new npc_infused_crystal(); -} diff --git a/src/server/scripts/EasternKingdoms/ghostlands.cpp b/src/server/scripts/EasternKingdoms/ghostlands.cpp deleted file mode 100644 index 9e00ceb2aa5..00000000000 --- a/src/server/scripts/EasternKingdoms/ghostlands.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Ghostlands -SD%Complete: 100 -SDComment: Quest support: 9692, 9212. Obtain Budd's Guise of Zul'aman. Vendor Rathis Tomber -SDCategory: Ghostlands -EndScriptData */ - -/* ContentData -npc_blood_knight_dawnstar -npc_budd_nedreck -npc_rathis_tomber -npc_ranger_lilatha -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_budd_nedreck -######*/ - -#define GOSSIP_HBN "You gave the crew disguises?" - -class npc_budd_nedreck : public CreatureScript -{ -public: - npc_budd_nedreck() : CreatureScript("npc_budd_nedreck") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 42540, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(11166) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_rathis_tomber -######*/ - -class npc_rathis_tomber : public CreatureScript -{ -public: - npc_rathis_tomber() : CreatureScript("npc_rathis_tomber") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor() && player->GetQuestRewardStatus(9152)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(8432, creature->GetGUID()); - }else - player->SEND_GOSSIP_MENU(8431, creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_ranger_lilatha -######*/ - -enum eEnums -{ - SAY_START = 0, - SAY_PROGRESS1 = 1, - SAY_PROGRESS2 = 2, - SAY_PROGRESS3 = 3, - SAY_END1 = 4, - SAY_END2 = 5, - SAY_CAPTAIN_ANSWER = 0, - - QUEST_ESCAPE_FROM_THE_CATACOMBS = 9212, - GO_CAGE = 181152, - NPC_CAPTAIN_HELIOS = 16220, - FACTION_SMOON_E = 1603 -}; - -class npc_ranger_lilatha : public CreatureScript -{ -public: - npc_ranger_lilatha() : CreatureScript("npc_ranger_lilatha") { } - - struct npc_ranger_lilathaAI : public npc_escortAI - { - npc_ranger_lilathaAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 0: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) - Cage->SetGoState(GO_STATE_ACTIVE); - Talk(SAY_START, player->GetGUID()); - break; - case 5: - Talk(SAY_PROGRESS1, player->GetGUID()); - break; - case 11: - Talk(SAY_PROGRESS2, player->GetGUID()); - me->SetOrientation(4.762841f); - break; - case 18: - { - Talk(SAY_PROGRESS3, player->GetGUID()); - Creature* Summ1 = me->SummonCreature(16342, 7627.083984f, -7532.538086f, 152.128616f, 1.082733f, TEMPSUMMON_DEAD_DESPAWN, 0); - Creature* Summ2 = me->SummonCreature(16343, 7620.432129f, -7532.550293f, 152.454865f, 0.827478f, TEMPSUMMON_DEAD_DESPAWN, 0); - if (Summ1 && Summ2) - { - Summ1->Attack(me, true); - Summ2->Attack(player, true); - } - me->AI()->AttackStart(Summ1); - } - break; - case 19: - me->SetWalk(false); - break; - case 25: - me->SetWalk(true); - break; - case 30: - if (player->GetTypeId() == TYPEID_PLAYER) - CAST_PLR(player)->GroupEventHappens(QUEST_ESCAPE_FROM_THE_CATACOMBS, me); - break; - case 32: - me->SetOrientation(2.978281f); - Talk(SAY_END1, player->GetGUID()); - break; - case 33: - me->SetOrientation(5.858011f); - Talk(SAY_END2, player->GetGUID()); - Creature* CaptainHelios = me->FindNearestCreature(NPC_CAPTAIN_HELIOS, 50); - if (CaptainHelios) - CaptainHelios->AI()->Talk(SAY_CAPTAIN_ANSWER, player->GetGUID()); - break; - } - } - - void Reset() - { - if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) - Cage->SetGoState(GO_STATE_READY); - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPE_FROM_THE_CATACOMBS) - { - creature->setFaction(113); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_ranger_lilatha::npc_ranger_lilathaAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ranger_lilathaAI(creature); - } - -}; - -void AddSC_ghostlands() -{ - new npc_budd_nedreck(); - new npc_rathis_tomber(); - new npc_ranger_lilatha(); -} diff --git a/src/server/scripts/EasternKingdoms/hinterlands.cpp b/src/server/scripts/EasternKingdoms/hinterlands.cpp deleted file mode 100644 index ffd31937677..00000000000 --- a/src/server/scripts/EasternKingdoms/hinterlands.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Hinterlands -SD%Complete: 100 -SDComment: Quest support: 863, 2742 -SDCategory: The Hinterlands -EndScriptData */ - -/* ContentData -npc_00x09hl -npc_rinji -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_00x09hl -######*/ - -enum eOOX -{ - SAY_OOX_START = 0, - SAY_OOX_AGGRO = 1, - SAY_OOX_AMBUSH = 3, - SAY_OOX_AMBUSH_REPLY = 4, - SAY_OOX_END = 5, - - QUEST_RESQUE_OOX_09 = 836, - - NPC_MARAUDING_OWL = 7808, - NPC_VILE_AMBUSHER = 7809, - - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775 -}; - -class npc_00x09hl : public CreatureScript -{ -public: - npc_00x09hl() : CreatureScript("npc_00x09hl") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_RESQUE_OOX_09) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - - if (player->GetTeam() == ALLIANCE) - creature->setFaction(FACTION_ESCORTEE_A); - else if (player->GetTeam() == HORDE) - creature->setFaction(FACTION_ESCORTEE_H); - - creature->AI()->Talk(SAY_OOX_START, player->GetGUID()); - - if (npc_00x09hlAI* pEscortAI = CAST_AI(npc_00x09hl::npc_00x09hlAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_00x09hlAI(creature); - } - - struct npc_00x09hlAI : public npc_escortAI - { - npc_00x09hlAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() { } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 26: - Talk(SAY_OOX_AMBUSH); - break; - case 43: - Talk(SAY_OOX_AMBUSH); - break; - case 64: - Talk(SAY_OOX_END); - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_RESQUE_OOX_09, me); - break; - } - } - - void WaypointStart(uint32 uiPointId) - { - switch (uiPointId) - { - case 27: - for (uint8 i = 0; i < 3; ++i) - { - const Position src = {147.927444f, -3851.513428f, 130.893f, 0}; - Position dst; - me->GetRandomPoint(src, 7.0f, dst); - DoSummon(NPC_MARAUDING_OWL, dst, 25000, TEMPSUMMON_CORPSE_TIMED_DESPAWN); - } - break; - case 44: - for (uint8 i = 0; i < 3; ++i) - { - const Position src = {-141.151581f, -4291.213867f, 120.130f, 0}; - Position dst; - me->GetRandomPoint(src, 7.0f, dst); - me->SummonCreature(NPC_VILE_AMBUSHER, dst, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000); - } - break; - } - } - - void EnterCombat(Unit* who) - { - if (who->GetEntry() == NPC_MARAUDING_OWL || who->GetEntry() == NPC_VILE_AMBUSHER) - return; - - Talk(SAY_OOX_AGGRO); - } - - void JustSummoned(Creature* summoned) - { - summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - } - }; -}; - -/*###### -## npc_rinji -######*/ - -enum eRinji -{ - SAY_RIN_BY_OUTRUNNER = 0, - - SAY_RIN_FREE = 0, //from here - SAY_RIN_HELP = 1, - SAY_RIN_COMPLETE = 2, - SAY_RIN_PROGRESS_1 = 3, - SAY_RIN_PROGRESS_2 = 4, - - QUEST_RINJI_TRAPPED = 2742, - NPC_RANGER = 2694, - NPC_OUTRUNNER = 2691, - GO_RINJI_CAGE = 142036 -}; - -struct Location -{ - float m_fX, m_fY, m_fZ; -}; - -Location m_afAmbushSpawn[] = -{ - {191.296204f, -2839.329346f, 107.388f}, - {70.972466f, -2848.674805f, 109.459f} -}; - -Location m_afAmbushMoveTo[] = -{ - {166.630386f, -2824.780273f, 108.153f}, - {70.886589f, -2874.335449f, 116.675f} -}; - -class npc_rinji : public CreatureScript -{ -public: - npc_rinji() : CreatureScript("npc_rinji") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_RINJI_TRAPPED) - { - if (GameObject* go = creature->FindNearestGameObject(GO_RINJI_CAGE, INTERACTION_DISTANCE)) - go->UseDoorOrButton(); - - if (npc_rinjiAI* pEscortAI = CAST_AI(npc_rinji::npc_rinjiAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_rinjiAI(creature); - } - - struct npc_rinjiAI : public npc_escortAI - { - npc_rinjiAI(Creature* creature) : npc_escortAI(creature) - { - m_bIsByOutrunner = false; - m_iSpawnId = 0; - } - - bool m_bIsByOutrunner; - uint32 m_uiPostEventCount; - uint32 m_uiPostEventTimer; - int m_iSpawnId; - - void Reset() - { - m_uiPostEventCount = 0; - m_uiPostEventTimer = 3000; - } - - void JustRespawned() - { - m_bIsByOutrunner = false; - m_iSpawnId = 0; - - npc_escortAI::JustRespawned(); - } - - void EnterCombat(Unit* who) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (who->GetEntry() == NPC_OUTRUNNER && !m_bIsByOutrunner) - { - if (Creature* talker = who->ToCreature()) - talker->AI()->Talk(SAY_RIN_BY_OUTRUNNER); - m_bIsByOutrunner = true; - } - - if (rand()%4) - return; - - //only if attacked and escorter is not in combat? - Talk(SAY_RIN_HELP); - } - } - - void DoSpawnAmbush(bool bFirst) - { - if (!bFirst) - m_iSpawnId = 1; - - me->SummonCreature(NPC_RANGER, - m_afAmbushSpawn[m_iSpawnId].m_fX, m_afAmbushSpawn[m_iSpawnId].m_fY, m_afAmbushSpawn[m_iSpawnId].m_fZ, 0.0f, - TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); - - for (int i = 0; i < 2; ++i) - { - me->SummonCreature(NPC_OUTRUNNER, - m_afAmbushSpawn[m_iSpawnId].m_fX, m_afAmbushSpawn[m_iSpawnId].m_fY, m_afAmbushSpawn[m_iSpawnId].m_fZ, 0.0f, - TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); - } - } - - void JustSummoned(Creature* summoned) - { - summoned->SetWalk(false); - summoned->GetMotionMaster()->MovePoint(0, m_afAmbushMoveTo[m_iSpawnId].m_fX, m_afAmbushMoveTo[m_iSpawnId].m_fY, m_afAmbushMoveTo[m_iSpawnId].m_fZ); - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 1: - Talk(SAY_RIN_FREE, player->GetGUID()); - break; - case 7: - DoSpawnAmbush(true); - break; - case 13: - DoSpawnAmbush(false); - break; - case 17: - Talk(SAY_RIN_COMPLETE, player->GetGUID()); - player->GroupEventHappens(QUEST_RINJI_TRAPPED, me); - SetRun(); - m_uiPostEventCount = 1; - break; - } - } - - void UpdateEscortAI(const uint32 uiDiff) - { - //Check if we have a current target - if (!UpdateVictim()) - { - if (HasEscortState(STATE_ESCORT_ESCORTING) && m_uiPostEventCount) - { - if (m_uiPostEventTimer <= uiDiff) - { - m_uiPostEventTimer = 3000; - - if (Player* player = GetPlayerForEscort()) - { - switch (m_uiPostEventCount) - { - case 1: - Talk(SAY_RIN_PROGRESS_1, player->GetGUID()); - ++m_uiPostEventCount; - break; - case 2: - Talk(SAY_RIN_PROGRESS_2, player->GetGUID()); - m_uiPostEventCount = 0; - break; - } - } - else - { - me->DespawnOrUnsummon(); - return; - } - } - else - m_uiPostEventTimer -= uiDiff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_hinterlands() -{ - new npc_00x09hl(); - new npc_rinji(); -} diff --git a/src/server/scripts/EasternKingdoms/ironforge.cpp b/src/server/scripts/EasternKingdoms/ironforge.cpp deleted file mode 100644 index f9e8d4d16c6..00000000000 --- a/src/server/scripts/EasternKingdoms/ironforge.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Ironforge -SD%Complete: 100 -SDComment: Quest support: 3702 -SDCategory: Ironforge -EndScriptData */ - -/* ContentData -npc_royal_historian_archesonus -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_royal_historian_archesonus -######*/ - -#define GOSSIP_ITEM_ROYAL "I am ready to listen" -#define GOSSIP_ITEM_ROYAL_1 "That is tragic. How did this happen?" -#define GOSSIP_ITEM_ROYAL_2 "Interesting, continue please." -#define GOSSIP_ITEM_ROYAL_3 "Unbelievable! How dare they??" -#define GOSSIP_ITEM_ROYAL_4 "Of course I will help!" - -class npc_royal_historian_archesonus : public CreatureScript -{ -public: - npc_royal_historian_archesonus() : CreatureScript("npc_royal_historian_archesonus") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2236, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2237, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2238, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(2239, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(3702); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(3702) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(2235, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -void AddSC_ironforge() -{ - new npc_royal_historian_archesonus(); -} diff --git a/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp b/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp deleted file mode 100644 index bfd4d24cec6..00000000000 --- a/src/server/scripts/EasternKingdoms/isle_of_queldanas.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Isle_of_Queldanas -SD%Complete: 100 -SDComment: Quest support: 11524, 11525, 11532, 11533, 11542, 11543, 11541 -SDCategory: Isle Of Quel'Danas -EndScriptData */ - -/* ContentData -npc_converted_sentry -npc_greengill_slave -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" -#include "Pet.h" -#include "SpellInfo.h" - -/*###### -## npc_converted_sentry -######*/ -enum ConvertedSentry -{ - SAY_CONVERTED = 0, - - SPELL_CONVERT_CREDIT = 45009 -}; - - -class npc_converted_sentry : public CreatureScript -{ -public: - npc_converted_sentry() : CreatureScript("npc_converted_sentry") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_converted_sentryAI (creature); - } - - struct npc_converted_sentryAI : public ScriptedAI - { - npc_converted_sentryAI(Creature* creature) : ScriptedAI(creature) {} - - bool Credit; - uint32 Timer; - - void Reset() - { - Credit = false; - Timer = 2500; - } - - void MoveInLineOfSight(Unit* /*who*/) {} - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (!Credit) - { - if (Timer <= diff) - { - Talk(SAY_CONVERTED); - - DoCast(me, SPELL_CONVERT_CREDIT); - if (me->isPet()) - me->ToPet()->SetDuration(7500); - Credit = true; - } else Timer -= diff; - } - } - }; -}; - -/*###### -## npc_greengill_slave -######*/ - -#define ENRAGE 45111 -#define ORB 45109 -#define QUESTG 11541 -#define DM 25060 - -class npc_greengill_slave : public CreatureScript -{ -public: - npc_greengill_slave() : CreatureScript("npc_greengill_slave") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_greengill_slaveAI(creature); - } - - struct npc_greengill_slaveAI : public ScriptedAI - { - npc_greengill_slaveAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - - void EnterCombat(Unit* /*who*/){} - - void Reset() - { - PlayerGUID = 0; - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (!caster) - return; - - if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == ORB && !me->HasAura(ENRAGE)) - { - PlayerGUID = caster->GetGUID(); - if (PlayerGUID) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player && player->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE) - DoCast(player, 45110, true); - } - DoCast(me, ENRAGE); - Unit* Myrmidon = me->FindNearestCreature(DM, 70); - if (Myrmidon) - { - me->AddThreat(Myrmidon, 100000.0f); - AttackStart(Myrmidon); - } - } - } - - void UpdateAI(const uint32 /*diff*/) - { - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_isle_of_queldanas() -{ - new npc_converted_sentry(); - new npc_greengill_slave(); -} diff --git a/src/server/scripts/EasternKingdoms/loch_modan.cpp b/src/server/scripts/EasternKingdoms/loch_modan.cpp deleted file mode 100644 index 30f12718d64..00000000000 --- a/src/server/scripts/EasternKingdoms/loch_modan.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Loch_Modan -SD%Complete: 100 -SDComment: Quest support: 3181 -SDCategory: Loch Modan -EndScriptData */ - -/* ContentData -npc_mountaineer_pebblebitty -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_mountaineer_pebblebitty -######*/ - -#define GOSSIP_MP "Open the gate please, i need to get to Searing Gorge" - -#define GOSSIP_MP1 "But i need to get there, now open the gate!" -#define GOSSIP_MP2 "Ok, so what is this other way?" -#define GOSSIP_MP3 "Doesn't matter, i'm invulnerable." -#define GOSSIP_MP4 "Yes..." -#define GOSSIP_MP5 "Ok, i'll try to remember that." -#define GOSSIP_MP6 "A key? Ok!" - -class npc_mountaineer_pebblebitty : public CreatureScript -{ -public: - npc_mountaineer_pebblebitty() : CreatureScript("npc_mountaineer_pebblebitty") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(1833, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(1834, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(1835, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(1836, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(1837, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(1838, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->CLOSE_GOSSIP_MENU(); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (!player->GetQuestRewardStatus(3181) == 1) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -void AddSC_loch_modan() -{ - new npc_mountaineer_pebblebitty(); -} diff --git a/src/server/scripts/EasternKingdoms/redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/redridge_mountains.cpp deleted file mode 100644 index 5ff95f83f25..00000000000 --- a/src/server/scripts/EasternKingdoms/redridge_mountains.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* Script Data Start -SDName: Redridge Mountains -SD%Complete: 100% -SDComment: Support for quest 219. -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -enum eCorporalKeeshan -{ - QUEST_MISSING_IN_ACTION = 219, - - SAY_CORPORAL_1 = 0, - SAY_CORPORAL_2 = 1, - SAY_CORPORAL_3 = 2, - SAY_CORPORAL_4 = 3, - SAY_CORPORAL_5 = 4, - - SPELL_MOCKING_BLOW = 21008, - SPELL_SHIELD_BASH = 11972, -}; - -class npc_corporal_keeshan : public CreatureScript -{ -public: - npc_corporal_keeshan() : CreatureScript("npc_corporal_keeshan") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_MISSING_IN_ACTION) - { - CAST_AI(npc_corporal_keeshan::npc_corporal_keeshanAI, creature->AI())->Start(true, false, player->GetGUID(), quest); - creature->AI()->Talk(SAY_CORPORAL_1); - } - - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_corporal_keeshanAI(creature); - } - - struct npc_corporal_keeshanAI : public npc_escortAI - { - npc_corporal_keeshanAI(Creature* creature) : npc_escortAI(creature) {} - - uint32 uiPhase; - uint32 uiTimer; - uint32 uiMockingBlowTimer; - uint32 uiShieldBashTimer; - - void Reset() - { - uiTimer = 0; - uiPhase = 0; - uiMockingBlowTimer = 5000; - uiShieldBashTimer = 8000; - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - if (waypointId >= 65 && me->GetUnitMovementFlags() == MOVEMENTFLAG_WALKING) - me->SetWalk(false); - - switch (waypointId) - { - case 39: - SetEscortPaused(true); - uiTimer = 2000; - uiPhase = 1; - break; - case 65: - me->SetWalk(false); - break; - case 115: - player->AreaExploredOrEventHappens(QUEST_MISSING_IN_ACTION); - uiTimer = 2000; - uiPhase = 4; - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (HasEscortState(STATE_ESCORT_NONE)) - return; - - npc_escortAI::UpdateAI(uiDiff); - - if (uiPhase) - { - if (uiTimer <= uiDiff) - { - switch (uiPhase) - { - case 1: - me->SetStandState(UNIT_STAND_STATE_SIT); - uiTimer = 1000; - uiPhase = 2; - break; - case 2: - Talk(SAY_CORPORAL_2); - uiTimer = 15000; - uiPhase = 3; - break; - case 3: - Talk(SAY_CORPORAL_3); - me->SetStandState(UNIT_STAND_STATE_STAND); - SetEscortPaused(false); - uiTimer = 0; - uiPhase = 0; - break; - case 4: - Talk(SAY_CORPORAL_4); - uiTimer = 2500; - uiPhase = 5; - case 5: - Talk(SAY_CORPORAL_5); - uiTimer = 0; - uiPhase = 0; - } - } else uiTimer -= uiDiff; - } - - if (!UpdateVictim()) - return; - - if (uiMockingBlowTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_MOCKING_BLOW); - uiMockingBlowTimer = 5000; - } else uiMockingBlowTimer -= uiDiff; - - if (uiShieldBashTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_MOCKING_BLOW); - uiShieldBashTimer = 8000; - } else uiShieldBashTimer -= uiDiff; - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_redridge_mountains() -{ - new npc_corporal_keeshan(); -} diff --git a/src/server/scripts/EasternKingdoms/silvermoon_city.cpp b/src/server/scripts/EasternKingdoms/silvermoon_city.cpp deleted file mode 100644 index e750faefbf5..00000000000 --- a/src/server/scripts/EasternKingdoms/silvermoon_city.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Silvermoon_City -SD%Complete: 100 -SDComment: Quest support: 9685 -SDCategory: Silvermoon City -EndScriptData */ - -/* ContentData -npc_blood_knight_stillblade -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" -#include "SpellInfo.h" - -/*####### -# npc_blood_knight_stillblade -#######*/ -enum eStillbladeData -{ - SAY_HEAL = 0, - - QUEST_REDEEMING_THE_DEAD = 9685, - SPELL_SHIMMERING_VESSEL = 31225, - SPELL_REVIVE_SELF = 32343, -}; - -class npc_blood_knight_stillblade : public CreatureScript -{ -public: - npc_blood_knight_stillblade() : CreatureScript("npc_blood_knight_stillblade") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_blood_knight_stillbladeAI (creature); - } - - struct npc_blood_knight_stillbladeAI : public ScriptedAI - { - npc_blood_knight_stillbladeAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 lifeTimer; - bool spellHit; - - void Reset() - { - lifeTimer = 120000; - me->SetStandState(UNIT_STAND_STATE_DEAD); - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 7); // lay down - spellHit = false; - } - - void EnterCombat(Unit* /*who*/) - { - } - - void MoveInLineOfSight(Unit* /*who*/) - { - } - - void UpdateAI(const uint32 diff) - { - if (me->IsStandState()) - { - if (lifeTimer <= diff) - me->AI()->EnterEvadeMode(); - else - lifeTimer -= diff; - } - } - - void SpellHit(Unit* Hitter, const SpellInfo* Spellkind) - { - if ((Spellkind->Id == SPELL_SHIMMERING_VESSEL) && !spellHit && - (Hitter->GetTypeId() == TYPEID_PLAYER) && (CAST_PLR(Hitter)->IsActiveQuest(QUEST_REDEEMING_THE_DEAD))) - { - CAST_PLR(Hitter)->AreaExploredOrEventHappens(QUEST_REDEEMING_THE_DEAD); - DoCast(me, SPELL_REVIVE_SELF); - me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); - //me->RemoveAllAuras(); - Talk(SAY_HEAL); - spellHit = true; - } - } - }; -}; - -void AddSC_silvermoon_city() -{ - new npc_blood_knight_stillblade(); -} diff --git a/src/server/scripts/EasternKingdoms/silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/silverpine_forest.cpp deleted file mode 100644 index 290f7fa6882..00000000000 --- a/src/server/scripts/EasternKingdoms/silverpine_forest.cpp +++ /dev/null @@ -1,327 +0,0 @@ - /* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Silverpine_Forest -SD%Complete: 100 -SDComment: Quest support: 435, 452 -SDCategory: Silverpine Forest -EndScriptData */ - -/* ContentData -npc_deathstalker_erland -pyrewood_ambush -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_deathstalker_erland -######*/ - -enum eErland -{ - SAY_QUESTACCEPT = 0, - SAY_START = 1, - SAY_AGGRO = 2, - SAY_PROGRESS = 3, - SAY_LAST = 4, - - SAY_RANE = 0, - SAY_RANE_ANSWER = 5, - SAY_MOVE_QUINN = 6, - - SAY_QUINN = 7, - SAY_QUINN_ANSWER = 0, - SAY_BYE = 8, - - QUEST_ESCORTING = 435, - NPC_RANE = 1950, - NPC_QUINN = 1951 -}; - -class npc_deathstalker_erland : public CreatureScript -{ -public: - npc_deathstalker_erland() : CreatureScript("npc_deathstalker_erland") { } - - struct npc_deathstalker_erlandAI : public npc_escortAI - { - npc_deathstalker_erlandAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 1: - Talk(SAY_START, player->GetGUID()); - break; - case 10: - Talk(SAY_PROGRESS); - break; - case 13: - Talk(SAY_LAST, player->GetGUID()); - player->GroupEventHappens(QUEST_ESCORTING, me); - break; - case 15: - if (Creature* rane = me->FindNearestCreature(NPC_RANE, 20.0f)) - rane->AI()->Talk(SAY_RANE); - break; - case 16: - Talk(SAY_RANE_ANSWER); - break; - case 17: - Talk(SAY_MOVE_QUINN); - break; - case 24: - Talk(SAY_QUINN); - break; - case 25: - if (Creature* quinn = me->FindNearestCreature(NPC_QUINN, 20.0f)) - quinn->AI()->Talk(SAY_QUINN_ANSWER); - break; - case 26: - Talk(SAY_BYE); - break; - } - } - - void Reset() {} - - void EnterCombat(Unit* who) - { - Talk(SAY_AGGRO, who->GetGUID()); - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCORTING) - { - creature->AI()->Talk(SAY_QUESTACCEPT, player->GetGUID()); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_deathstalker_erland::npc_deathstalker_erlandAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_deathstalker_erlandAI(creature); - } -}; - -/*###### -## pyrewood_ambush -#######*/ - -#define QUEST_PYREWOOD_AMBUSH 452 - -#define NPCSAY_INIT "Get ready, they'll be arriving any minute..." //not blizzlike -#define NPCSAY_END "Thanks for your help!" //not blizzlike - -static float PyrewoodSpawnPoints[3][4] = -{ - //pos_x pos_y pos_z orien - //outside - /* - {-400.85f, 1513.64f, 18.67f, 0}, - {-397.32f, 1514.12f, 18.67f, 0}, - {-397.44f, 1511.09f, 18.67f, 0}, - */ - //door - {-396.17f, 1505.86f, 19.77f, 0}, - {-396.91f, 1505.77f, 19.77f, 0}, - {-397.94f, 1504.74f, 19.77f, 0}, -}; - -#define WAIT_SECS 6000 - -class pyrewood_ambush : public CreatureScript -{ -public: - pyrewood_ambush() : CreatureScript("pyrewood_ambush") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest *quest) - { - if (quest->GetQuestId() == QUEST_PYREWOOD_AMBUSH && !CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress) - { - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress = true; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->Phase = 0; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->KillCount = 0; - CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->PlayerGUID = player->GetGUID(); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new pyrewood_ambushAI (creature); - } - - struct pyrewood_ambushAI : public ScriptedAI - { - pyrewood_ambushAI(Creature* creature) : ScriptedAI(creature), Summons(me) - { - QuestInProgress = false; - } - - uint32 Phase; - int8 KillCount; - uint32 WaitTimer; - uint64 PlayerGUID; - SummonList Summons; - - bool QuestInProgress; - - void Reset() - { - WaitTimer = WAIT_SECS; - - if (!QuestInProgress) //fix reset values (see UpdateVictim) - { - Phase = 0; - KillCount = 0; - PlayerGUID = 0; - Summons.DespawnAll(); - } - } - - void EnterCombat(Unit* /*who*/){} - - void JustSummoned(Creature* summoned) - { - Summons.Summon(summoned); - ++KillCount; - } - - void SummonedCreatureDespawn(Creature* summoned) - { - Summons.Despawn(summoned); - --KillCount; - } - - void SummonCreatureWithRandomTarget(uint32 creatureId, int position) - { - if (Creature* summoned = me->SummonCreature(creatureId, PyrewoodSpawnPoints[position][0], PyrewoodSpawnPoints[position][1], PyrewoodSpawnPoints[position][2], PyrewoodSpawnPoints[position][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000)) - { - Unit* target = NULL; - if (PlayerGUID) - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - if (player->isAlive() && RAND(0, 1)) - target = player; - - if (!target) - target = me; - - summoned->setFaction(168); - summoned->AddThreat(target, 32.0f); - summoned->AI()->AttackStart(target); - } - } - - void JustDied(Unit* /*killer*/) - { - if (PlayerGUID) - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - if (player->GetQuestStatus(QUEST_PYREWOOD_AMBUSH) == QUEST_STATUS_INCOMPLETE) - player->FailQuest(QUEST_PYREWOOD_AMBUSH); - } - - void UpdateAI(const uint32 diff) - { - //sLog->outInfo(LOG_FILTER_TSCR, "DEBUG: p(%i) k(%i) d(%u) W(%i)", Phase, KillCount, diff, WaitTimer); - - if (!QuestInProgress) - return; - - if (KillCount && Phase < 6) - { - if (!UpdateVictim()) //reset() on target Despawn... - return; - - DoMeleeAttackIfReady(); - return; - } - - switch (Phase) - { - case 0: - if (WaitTimer == WAIT_SECS) - me->MonsterSay(NPCSAY_INIT, LANG_UNIVERSAL, 0); //no blizzlike - - if (WaitTimer <= diff) - { - WaitTimer -= diff; - return; - } - break; - case 1: - SummonCreatureWithRandomTarget(2060, 1); - break; - case 2: - SummonCreatureWithRandomTarget(2061, 2); - SummonCreatureWithRandomTarget(2062, 0); - break; - case 3: - SummonCreatureWithRandomTarget(2063, 1); - SummonCreatureWithRandomTarget(2064, 2); - SummonCreatureWithRandomTarget(2065, 0); - break; - case 4: - SummonCreatureWithRandomTarget(2066, 1); - SummonCreatureWithRandomTarget(2067, 0); - SummonCreatureWithRandomTarget(2068, 2); - break; - case 5: //end - if (PlayerGUID) - { - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - { - me->MonsterSay(NPCSAY_END, LANG_UNIVERSAL, 0); //not blizzlike - player->GroupEventHappens(QUEST_PYREWOOD_AMBUSH, me); - } - } - QuestInProgress = false; - Reset(); - break; - } - ++Phase; //prepare next phase - } - }; -}; - -/*###### -## AddSC -######*/ - -void AddSC_silverpine_forest() -{ - new npc_deathstalker_erland(); - new pyrewood_ambush(); -} diff --git a/src/server/scripts/EasternKingdoms/stormwind_city.cpp b/src/server/scripts/EasternKingdoms/stormwind_city.cpp deleted file mode 100644 index e81567a1a7a..00000000000 --- a/src/server/scripts/EasternKingdoms/stormwind_city.cpp +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Stormwind_City -SD%Complete: 100 -SDComment: Quest support: 1640, 1447, 4185, 11223, 434. -SDCategory: Stormwind City -EndScriptData */ - -/* ContentData -npc_archmage_malin -npc_bartleby -npc_lady_katrana_prestor -npc_tyrion -npc_tyrion_spybot -npc_marzon_silent_blade -npc_lord_gregor_lescovar -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_archmage_malin -######*/ - -#define GOSSIP_ITEM_MALIN "Can you send me to Theramore? I have an urgent message for Lady Jaina from Highlord Bolvar." - -class npc_archmage_malin : public CreatureScript -{ -public: - npc_archmage_malin() : CreatureScript("npc_archmage_malin") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 42711, true); - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(11223) == QUEST_STATUS_COMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MALIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_bartleby -######*/ - -enum eBartleby -{ - FACTION_ENEMY = 168, - QUEST_BEAT = 1640 -}; - -class npc_bartleby : public CreatureScript -{ -public: - npc_bartleby() : CreatureScript("npc_bartleby") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_BEAT) - { - creature->setFaction(FACTION_ENEMY); - creature->AI()->AttackStart(player); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_bartlebyAI(creature); - } - - struct npc_bartlebyAI : public ScriptedAI - { - npc_bartlebyAI(Creature* creature) : ScriptedAI(creature) - { - m_uiNormalFaction = creature->getFaction(); - } - - uint32 m_uiNormalFaction; - - void Reset() - { - if (me->getFaction() != m_uiNormalFaction) - me->setFaction(m_uiNormalFaction); - } - - void AttackedBy(Unit* pAttacker) - { - if (me->getVictim()) - return; - - if (me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) - { - if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) - { - //Take 0 damage - uiDamage = 0; - - if (pDoneBy->GetTypeId() == TYPEID_PLAYER) - CAST_PLR(pDoneBy)->AreaExploredOrEventHappens(QUEST_BEAT); - EnterEvadeMode(); - } - } - }; -}; - -/*###### -## npc_lady_katrana_prestor -######*/ - -#define GOSSIP_ITEM_KAT_1 "Pardon the intrusion, Lady Prestor, but Highlord Bolvar suggested that I seek your advice." -#define GOSSIP_ITEM_KAT_2 "My apologies, Lady Prestor." -#define GOSSIP_ITEM_KAT_3 "Begging your pardon, Lady Prestor. That was not my intent." -#define GOSSIP_ITEM_KAT_4 "Thank you for your time, Lady Prestor." - -class npc_lady_katrana_prestor : public CreatureScript -{ -public: - npc_lady_katrana_prestor() : CreatureScript("npc_lady_katrana_prestor") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(2694, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(2695, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(2696, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(4185); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(4185) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(2693, creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_lord_gregor_lescovar -######*/ - -enum eLordGregorLescovar -{ - SAY_GUARD_2 = 0, - SAY_LESCOVAR_2 = 0, - SAY_LESCOVAR_3 = 1, - SAY_LESCOVAR_4 = 2, - SAY_MARZON_1 = 0, - SAY_MARZON_2 = 1, - SAY_TYRION_2 = 1, - - NPC_STORMWIND_ROYAL = 1756, - NPC_MARZON_BLADE = 1755, - NPC_TYRION = 7766, - - QUEST_THE_ATTACK = 434 -}; - -class npc_lord_gregor_lescovar : public CreatureScript -{ -public: - npc_lord_gregor_lescovar() : CreatureScript("npc_lord_gregor_lescovar") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lord_gregor_lescovarAI(creature); - } - - struct npc_lord_gregor_lescovarAI : public npc_escortAI - { - npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) - { - creature->RestoreFaction(); - } - - uint32 uiTimer; - uint32 uiPhase; - - uint64 MarzonGUID; - - void Reset() - { - uiTimer = 0; - uiPhase = 0; - - MarzonGUID = 0; - } - - void EnterEvadeMode() - { - me->DisappearAndDie(); - - if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) - { - if (pMarzon->isAlive()) - pMarzon->DisappearAndDie(); - } - } - - void EnterCombat(Unit* who) - { - if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) - { - if (pMarzon->isAlive() && !pMarzon->isInCombat()) - pMarzon->AI()->AttackStart(who); - } - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 14: - SetEscortPaused(true); - Talk(SAY_LESCOVAR_2); - uiTimer = 3000; - uiPhase = 1; - break; - case 16: - SetEscortPaused(true); - if (Creature* pMarzon = me->SummonCreature(NPC_MARZON_BLADE, -8411.360352f, 480.069733f, 123.760895f, 4.941504f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) - { - pMarzon->GetMotionMaster()->MovePoint(0, -8408.000977f, 468.611450f, 123.759903f); - MarzonGUID = pMarzon->GetGUID(); - } - uiTimer = 2000; - uiPhase = 4; - break; - } - } - //TO-DO: We don't have movemaps, also we can't make 2 npcs walks to one point propperly (and we can not use escort ai, because they are 2 different spawns and with same entry), because of it we make them, disappear. - void DoGuardsDisappearAndDie() - { - std::list GuardList; - me->GetCreatureListWithEntryInGrid(GuardList, NPC_STORMWIND_ROYAL, 8.0f); - if (!GuardList.empty()) - { - for (std::list::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr) - { - if (Creature* pGuard = *itr) - pGuard->DisappearAndDie(); - } - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (uiPhase) - { - if (uiTimer <= uiDiff) - { - switch (uiPhase) - { - case 1: - if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 8.0f, true)) - pGuard->AI()->Talk(SAY_GUARD_2); - uiTimer = 3000; - uiPhase = 2; - break; - case 2: - DoGuardsDisappearAndDie(); - uiTimer = 2000; - uiPhase = 3; - break; - case 3: - SetEscortPaused(false); - uiTimer = 0; - uiPhase = 0; - break; - case 4: - Talk(SAY_LESCOVAR_3); - uiTimer = 0; - uiPhase = 0; - break; - case 5: - if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) - pMarzon->AI()->Talk(SAY_MARZON_1); - uiTimer = 3000; - uiPhase = 6; - break; - case 6: - Talk(SAY_LESCOVAR_4); - if (Player* player = GetPlayerForEscort()) - player->AreaExploredOrEventHappens(QUEST_THE_ATTACK); - uiTimer = 2000; - uiPhase = 7; - break; - case 7: - if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 20.0f, true)) - pTyrion->AI()->Talk(SAY_TYRION_2); - if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) - pMarzon->setFaction(14); - me->setFaction(14); - uiTimer = 0; - uiPhase = 0; - break; - } - } else uiTimer -= uiDiff; - } - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_marzon_silent_blade -######*/ - -class npc_marzon_silent_blade : public CreatureScript -{ -public: - npc_marzon_silent_blade() : CreatureScript("npc_marzon_silent_blade") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_marzon_silent_bladeAI(creature); - } - - struct npc_marzon_silent_bladeAI : public ScriptedAI - { - npc_marzon_silent_bladeAI(Creature* creature) : ScriptedAI(creature) - { - me->SetWalk(true); - } - - void Reset() - { - me->RestoreFaction(); - } - - void EnterCombat(Unit* who) - { - Talk(SAY_MARZON_2); - - if (me->isSummon()) - { - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - { - if (summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive() && !summoner->isInCombat()) - summoner->ToCreature()->AI()->AttackStart(who); - } - } - } - - void EnterEvadeMode() - { - me->DisappearAndDie(); - - if (me->isSummon()) - { - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - { - if (summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive()) - summoner->ToCreature()->DisappearAndDie(); - } - } - } - - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (me->isSummon()) - { - Unit* summoner = me->ToTempSummon()->GetSummoner(); - if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAIEnabled) - { - npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI* ai = - CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, summoner->GetAI()); - if (ai) - { - ai->uiTimer = 2000; - ai->uiPhase = 5; - } - //me->ChangeOrient(0.0f, summoner); - } - } - } - - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_tyrion_spybot -######*/ - -enum eTyrionSpybot -{ - SAY_QUEST_ACCEPT_ATTACK = 0, - SAY_SPYBOT_1 = 1, - SAY_SPYBOT_2 = 2, - SAY_SPYBOT_3 = 3, - SAY_SPYBOT_4 = 4, - SAY_TYRION_1 = 0, - SAY_GUARD_1 = 1, - SAY_LESCOVAR_1 = 3, - - NPC_PRIESTESS_TYRIONA = 7779, - NPC_LORD_GREGOR_LESCOVAR = 1754, -}; - -class npc_tyrion_spybot : public CreatureScript -{ -public: - npc_tyrion_spybot() : CreatureScript("npc_tyrion_spybot") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_tyrion_spybotAI(creature); - } - - struct npc_tyrion_spybotAI : public npc_escortAI - { - npc_tyrion_spybotAI(Creature* creature) : npc_escortAI(creature) {} - - uint32 uiTimer; - uint32 uiPhase; - - void Reset() - { - uiTimer = 0; - uiPhase = 0; - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 1: - SetEscortPaused(true); - uiTimer = 2000; - uiPhase = 1; - break; - case 5: - SetEscortPaused(true); - Talk(SAY_SPYBOT_1); - uiTimer = 2000; - uiPhase = 5; - break; - case 17: - SetEscortPaused(true); - Talk(SAY_SPYBOT_3); - uiTimer = 3000; - uiPhase = 8; - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (uiPhase) - { - if (uiTimer <= uiDiff) - { - switch (uiPhase) - { - case 1: - Talk(SAY_QUEST_ACCEPT_ATTACK); - uiTimer = 3000; - uiPhase = 2; - break; - case 2: - if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 10.0f)) - pTyrion->AI()->Talk(SAY_TYRION_1); - uiTimer = 3000; - uiPhase = 3; - break; - case 3: - me->UpdateEntry(NPC_PRIESTESS_TYRIONA, ALLIANCE); - uiTimer = 2000; - uiPhase = 4; - break; - case 4: - SetEscortPaused(false); - uiPhase = 0; - uiTimer = 0; - break; - case 5: - if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 10.0f, true)) - pGuard->AI()->Talk(SAY_GUARD_1); - uiTimer = 3000; - uiPhase = 6; - break; - case 6: - Talk(SAY_SPYBOT_2); - uiTimer = 3000; - uiPhase = 7; - break; - case 7: - SetEscortPaused(false); - uiTimer = 0; - uiPhase = 0; - break; - case 8: - if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f)) - pLescovar->AI()->Talk(SAY_LESCOVAR_1); - uiTimer = 3000; - uiPhase = 9; - break; - case 9: - Talk(SAY_SPYBOT_4); - uiTimer = 3000; - uiPhase = 10; - break; - case 10: - if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f)) - { - if (Player* player = GetPlayerForEscort()) - { - CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->Start(false, false, player->GetGUID()); - CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->SetMaxPlayerDistance(200.0f); - } - } - me->DisappearAndDie(); - uiTimer = 0; - uiPhase = 0; - break; - } - } else uiTimer -= uiDiff; - } - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_tyrion -######*/ - -enum eTyrion -{ - NPC_TYRION_SPYBOT = 8856 -}; - -class npc_tyrion : public CreatureScript -{ -public: - npc_tyrion() : CreatureScript("npc_tyrion") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_THE_ATTACK) - { - if (Creature* pSpybot = creature->FindNearestCreature(NPC_TYRION_SPYBOT, 5.0f, true)) - { - CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->Start(false, false, player->GetGUID()); - CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->SetMaxPlayerDistance(200.0f); - } - return true; - } - return false; - } -}; - -void AddSC_stormwind_city() -{ - new npc_archmage_malin(); - new npc_bartleby(); - new npc_lady_katrana_prestor(); - new npc_tyrion(); - new npc_tyrion_spybot(); - new npc_lord_gregor_lescovar(); - new npc_marzon_silent_blade(); -} diff --git a/src/server/scripts/EasternKingdoms/stranglethorn_vale.cpp b/src/server/scripts/EasternKingdoms/stranglethorn_vale.cpp deleted file mode 100644 index 6e14ef840a3..00000000000 --- a/src/server/scripts/EasternKingdoms/stranglethorn_vale.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Stranglethorn_Vale -SD%Complete: 100 -SDComment: Quest support: 592 -SDCategory: Stranglethorn Vale -EndScriptData */ - -/* ContentData -mob_yenniku -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" -#include "SpellInfo.h" - -/*###### -## mob_yenniku -######*/ - -class mob_yenniku : public CreatureScript -{ -public: - mob_yenniku() : CreatureScript("mob_yenniku") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_yennikuAI (creature); - } - - struct mob_yennikuAI : public ScriptedAI - { - mob_yennikuAI(Creature* creature) : ScriptedAI(creature) - { - bReset = false; - } - - uint32 Reset_Timer; - bool bReset; - - void Reset() - { - Reset_Timer = 0; - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (caster->GetTypeId() == TYPEID_PLAYER) - { - //Yenniku's Release - if (!bReset && CAST_PLR(caster)->GetQuestStatus(592) == QUEST_STATUS_INCOMPLETE && spell->Id == 3607) - { - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); - me->CombatStop(); //stop combat - me->DeleteThreatList(); //unsure of this - me->setFaction(83); //horde generic - - bReset = true; - Reset_Timer = 60000; - } - } - return; - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (bReset) - { - if (Reset_Timer <= diff) - { - EnterEvadeMode(); - bReset = false; - me->setFaction(28); //troll, bloodscalp - return; - } - else Reset_Timer -= diff; - - if (me->isInCombat() && me->getVictim()) - { - if (me->getVictim()->GetTypeId() == TYPEID_PLAYER) - { - Unit* victim = me->getVictim(); - if (CAST_PLR(victim)->GetTeam() == HORDE) - { - me->CombatStop(); - me->DeleteThreatList(); - } - } - } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## -######*/ - -void AddSC_stranglethorn_vale() -{ - new mob_yenniku(); -} diff --git a/src/server/scripts/EasternKingdoms/swamp_of_sorrows.cpp b/src/server/scripts/EasternKingdoms/swamp_of_sorrows.cpp deleted file mode 100644 index f686de5d88f..00000000000 --- a/src/server/scripts/EasternKingdoms/swamp_of_sorrows.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_galen_goodward -######*/ - -enum Galen -{ - QUEST_GALENS_ESCAPE = 1393, - - GO_GALENS_CAGE = 37118, - - SAY_PERIODIC = 0, - SAY_QUEST_ACCEPTED = 1, - SAY_ATTACKED = 2, - SAY_QUEST_COMPLETE = 3, - EMOTE_WHISPER = 4, - EMOTE_DISAPPEAR = 5, -}; - -class npc_galen_goodward : public CreatureScript -{ -public: - - npc_galen_goodward() : CreatureScript("npc_galen_goodward") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_GALENS_ESCAPE) - { - CAST_AI(npc_galen_goodward::npc_galen_goodwardAI, creature->AI())->Start(false, false, player->GetGUID()); - creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE); - creature->AI()->Talk(SAY_QUEST_ACCEPTED); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_galen_goodwardAI(creature); - } - - struct npc_galen_goodwardAI : public npc_escortAI - { - npc_galen_goodwardAI(Creature* creature) : npc_escortAI(creature) - { - m_uiGalensCageGUID = 0; - Reset(); - } - - uint64 m_uiGalensCageGUID; - uint32 m_uiPeriodicSay; - - void Reset() - { - m_uiPeriodicSay = 6000; - } - - void EnterCombat(Unit* who) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - Talk(SAY_ATTACKED, who->GetGUID()); - } - - void WaypointStart(uint32 uiPointId) - { - switch (uiPointId) - { - case 0: - { - GameObject* pCage = NULL; - if (m_uiGalensCageGUID) - pCage = me->GetMap()->GetGameObject(m_uiGalensCageGUID); - else - pCage = GetClosestGameObjectWithEntry(me, GO_GALENS_CAGE, INTERACTION_DISTANCE); - if (pCage) - { - pCage->UseDoorOrButton(); - m_uiGalensCageGUID = pCage->GetGUID(); - } - break; - } - case 21: - Talk(EMOTE_DISAPPEAR); - break; - } - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 0: - if (GameObject* pCage = me->GetMap()->GetGameObject(m_uiGalensCageGUID)) - pCage->ResetDoorOrButton(); - break; - case 20: - if (Player* player = GetPlayerForEscort()) - { - me->SetFacingToObject(player); - Talk(SAY_QUEST_COMPLETE, player->GetGUID()); - Talk(EMOTE_WHISPER, player->GetGUID()); - player->GroupEventHappens(QUEST_GALENS_ESCAPE, me); - } - SetRun(true); - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (HasEscortState(STATE_ESCORT_NONE)) - return; - - if (m_uiPeriodicSay < uiDiff) - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - Talk(SAY_PERIODIC); - m_uiPeriodicSay = 15000; - } - else - m_uiPeriodicSay -= uiDiff; - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_swamp_of_sorrows() -{ - new npc_galen_goodward(); -} diff --git a/src/server/scripts/EasternKingdoms/tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/tirisfal_glades.cpp deleted file mode 100644 index f36220dec0f..00000000000 --- a/src/server/scripts/EasternKingdoms/tirisfal_glades.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Tirisfal_Glades -SD%Complete: 100 -SDComment: Quest support: 590, 1819 -SDCategory: Tirisfal Glades -EndScriptData */ - -/* ContentData -npc_calvin_montague -go_mausoleum_door -go_mausoleum_trigger -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" - -/*###### -## npc_calvin_montague -######*/ - -enum Calvin -{ - SAY_COMPLETE = 0, - SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct) - QUEST_590 = 590, - FACTION_HOSTILE = 168 -}; - -class npc_calvin_montague : public CreatureScript -{ -public: - npc_calvin_montague() : CreatureScript("npc_calvin_montague") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_590) - { - creature->setFaction(FACTION_HOSTILE); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - CAST_AI(npc_calvin_montague::npc_calvin_montagueAI, creature->AI())->AttackStart(player); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_calvin_montagueAI (creature); - } - - struct npc_calvin_montagueAI : public ScriptedAI - { - npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 m_uiPhase; - uint32 m_uiPhaseTimer; - uint64 m_uiPlayerGUID; - - void Reset() - { - m_uiPhase = 0; - m_uiPhaseTimer = 5000; - m_uiPlayerGUID = 0; - - me->RestoreFaction(); - - if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - } - - void EnterCombat(Unit* /*who*/) {} - - void AttackedBy(Unit* pAttacker) - { - if (me->getVictim() || me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) - { - if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) - { - uiDamage = 0; - - me->RestoreFaction(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->CombatStop(true); - - m_uiPhase = 1; - - if (pDoneBy->GetTypeId() == TYPEID_PLAYER) - m_uiPlayerGUID = pDoneBy->GetGUID(); - } - } - - void UpdateAI(uint32 const diff) - { - if (m_uiPhase) - { - if (m_uiPhaseTimer <= diff) - m_uiPhaseTimer = 7500; - else - { - m_uiPhaseTimer -= diff; - return; - } - - switch (m_uiPhase) - { - case 1: - Talk(SAY_COMPLETE); - ++m_uiPhase; - break; - case 2: - if (Player* player = Unit::GetPlayer(*me, m_uiPlayerGUID)) - player->AreaExploredOrEventHappens(QUEST_590); - - DoCast(me, SPELL_DRINK, true); - ++m_uiPhase; - break; - case 3: - EnterEvadeMode(); - break; - } - - return; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## go_mausoleum_door -## go_mausoleum_trigger -######*/ - -enum eMausoleum -{ - QUEST_ULAG = 1819, - NPC_ULAG = 6390, - GO_TRIGGER = 104593, - GO_DOOR = 176594 -}; - -class go_mausoleum_door : public GameObjectScript -{ -public: - go_mausoleum_door() : GameObjectScript("go_mausoleum_door") { } - - bool OnGossipHello(Player* player, GameObject* /*go*/) - { - if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) - return false; - - if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f)) - { - pTrigger->SetGoState(GO_STATE_READY); - player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); - return false; - } - - return false; - } -}; - -class go_mausoleum_trigger : public GameObjectScript -{ -public: - go_mausoleum_trigger() : GameObjectScript("go_mausoleum_trigger") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) - return false; - - if (GameObject* pDoor = player->FindNearestGameObject(GO_DOOR, 30.0f)) - { - go->SetGoState(GO_STATE_ACTIVE); - pDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - return true; - } - - return false; - } -}; - -void AddSC_tirisfal_glades() -{ - new npc_calvin_montague(); - new go_mausoleum_door(); - new go_mausoleum_trigger(); -} diff --git a/src/server/scripts/EasternKingdoms/undercity.cpp b/src/server/scripts/EasternKingdoms/undercity.cpp deleted file mode 100644 index 2c3017a2f1a..00000000000 --- a/src/server/scripts/EasternKingdoms/undercity.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Undercity -SD%Complete: 95 -SDComment: Quest support: 6628, 9180(post-event). -SDCategory: Undercity -EndScriptData */ - -/* ContentData -npc_lady_sylvanas_windrunner -npc_highborne_lamenter -npc_parqual_fintallas -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_lady_sylvanas_windrunner -######*/ - -enum Sylvanas -{ - QUEST_JOURNEY_TO_UNDERCITY = 9180, - EMOTE_LAMENT_END = 0, - SAY_LAMENT_END = 1, - - SOUND_CREDIT = 10896, - ENTRY_HIGHBORNE_LAMENTER = 21628, - ENTRY_HIGHBORNE_BUNNY = 21641, - - SPELL_HIGHBORNE_AURA = 37090, - SPELL_SYLVANAS_CAST = 36568, - SPELL_RIBBON_OF_SOULS = 34432, // the real one to use might be 37099 - - // Combat spells - SPELL_BLACK_ARROW = 59712, - SPELL_FADE = 20672, - SPELL_FADE_BLINK = 29211, - SPELL_MULTI_SHOT = 59713, - SPELL_SHOT = 59710, - SPELL_SUMMON_SKELETON = 59711 -}; - -float HighborneLoc[4][3]= -{ - {1285.41f, 312.47f, 0.51f}, - {1286.96f, 310.40f, 1.00f}, - {1289.66f, 309.66f, 1.52f}, - {1292.51f, 310.50f, 1.99f}, -}; - -#define HIGHBORNE_LOC_Y -61.00f -#define HIGHBORNE_LOC_Y_NEW -55.50f - -class npc_lady_sylvanas_windrunner : public CreatureScript -{ -public: - npc_lady_sylvanas_windrunner() : CreatureScript("npc_lady_sylvanas_windrunner") { } - - bool OnQuestReward(Player* /*player*/, Creature* creature, const Quest *_Quest, uint32 /*slot*/) - { - if (_Quest->GetQuestId() == QUEST_JOURNEY_TO_UNDERCITY) - { - CAST_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->LamentEvent = true; - CAST_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->DoPlaySoundToSet(creature, SOUND_CREDIT); - creature->CastSpell(creature, SPELL_SYLVANAS_CAST, false); - - for (uint8 i = 0; i < 4; ++i) - creature->SummonCreature(ENTRY_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lady_sylvanas_windrunnerAI (creature); - } - - struct npc_lady_sylvanas_windrunnerAI : public ScriptedAI - { - npc_lady_sylvanas_windrunnerAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 LamentEventTimer; - bool LamentEvent; - uint64 targetGUID; - - uint32 FadeTimer; - uint32 SummonSkeletonTimer; - uint32 BlackArrowTimer; - uint32 ShotTimer; - uint32 MultiShotTimer; - - void Reset() - { - LamentEventTimer = 5000; - LamentEvent = false; - targetGUID = 0; - - FadeTimer = 30000; - SummonSkeletonTimer = 20000; - BlackArrowTimer = 15000; - ShotTimer = 8000; - MultiShotTimer = 10000; - } - - void EnterCombat(Unit* /*who*/) {} - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == ENTRY_HIGHBORNE_BUNNY) - { - if (Creature* target = Unit::GetCreature(*summoned, targetGUID)) - { - target->MonsterMoveWithSpeed(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0); - target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f); - summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false); - } - - summoned->SetDisableGravity(true); - targetGUID = summoned->GetGUID(); - } - } - - void UpdateAI(const uint32 diff) - { - if (LamentEvent) - { - if (LamentEventTimer <= diff) - { - DoSummon(ENTRY_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN); - - LamentEventTimer = 2000; - if (!me->HasAura(SPELL_SYLVANAS_CAST)) - { - Talk(SAY_LAMENT_END); - Talk(EMOTE_LAMENT_END); - LamentEvent = false; - } - } else LamentEventTimer -= diff; - } - - if (!UpdateVictim()) - return; - - // Combat spells - - if (FadeTimer <= diff) - { - DoCast(me, SPELL_FADE); - // add a blink to simulate a stealthed movement and reappearing elsewhere - DoCast(me, SPELL_FADE_BLINK); - FadeTimer = 30000 + rand()%5000; - // if the victim is out of melee range she cast multi shot - if (Unit* victim = me->getVictim()) - if (me->GetDistance(victim) > 10.0f) - DoCast(victim, SPELL_MULTI_SHOT); - } else FadeTimer -= diff; - - if (SummonSkeletonTimer <= diff) - { - DoCast(me, SPELL_SUMMON_SKELETON); - SummonSkeletonTimer = 20000 + rand()%10000; - } else SummonSkeletonTimer -= diff; - - if (BlackArrowTimer <= diff) - { - if (Unit* victim = me->getVictim()) - { - DoCast(victim, SPELL_BLACK_ARROW); - BlackArrowTimer = 15000 + rand()%5000; - } - } else BlackArrowTimer -= diff; - - if (ShotTimer <= diff) - { - if (Unit* victim = me->getVictim()) - { - DoCast(victim, SPELL_SHOT); - ShotTimer = 8000 + rand()%2000; - } - } else ShotTimer -= diff; - - if (MultiShotTimer <= diff) - { - if (Unit* victim = me->getVictim()) - { - DoCast(victim, SPELL_MULTI_SHOT); - MultiShotTimer = 10000 + rand()%3000; - } - } else MultiShotTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_highborne_lamenter -######*/ - -class npc_highborne_lamenter : public CreatureScript -{ -public: - npc_highborne_lamenter() : CreatureScript("npc_highborne_lamenter") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_highborne_lamenterAI (creature); - } - - struct npc_highborne_lamenterAI : public ScriptedAI - { - npc_highborne_lamenterAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 EventMoveTimer; - uint32 EventCastTimer; - bool EventMove; - bool EventCast; - - void Reset() - { - EventMoveTimer = 10000; - EventCastTimer = 17500; - EventMove = true; - EventCast = true; - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (EventMove) - { - if (EventMoveTimer <= diff) - { - me->SetDisableGravity(true); - me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetDistance(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW) / (5000 * 0.001f)); - me->SetPosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation()); - EventMove = false; - } else EventMoveTimer -= diff; - } - if (EventCast) - { - if (EventCastTimer <= diff) - { - DoCast(me, SPELL_HIGHBORNE_AURA); - EventCast = false; - } else EventCastTimer -= diff; - } - } - }; -}; - -/*###### -## npc_parqual_fintallas -######*/ - -#define SPELL_MARK_OF_SHAME 6767 - -#define GOSSIP_HPF1 "Gul'dan" -#define GOSSIP_HPF2 "Kel'Thuzad" -#define GOSSIP_HPF3 "Ner'zhul" - -class npc_parqual_fintallas : public CreatureScript -{ -public: - npc_parqual_fintallas() : CreatureScript("npc_parqual_fintallas") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_MARK_OF_SHAME, false); - } - if (action == GOSSIP_ACTION_INFO_DEF+2) - { - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(6628); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(6628) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_MARK_OF_SHAME)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HPF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HPF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HPF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(5822, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(5821, creature->GetGUID()); - - return true; - } -}; - -/*###### -## AddSC -######*/ - -void AddSC_undercity() -{ - new npc_lady_sylvanas_windrunner(); - new npc_highborne_lamenter(); - new npc_parqual_fintallas(); -} diff --git a/src/server/scripts/EasternKingdoms/western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/western_plaguelands.cpp deleted file mode 100644 index ee22b766154..00000000000 --- a/src/server/scripts/EasternKingdoms/western_plaguelands.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Western_Plaguelands -SD%Complete: 90 -SDComment: Quest support: 5097, 5098, 5216, 5219, 5222, 5225, 5229, 5231, 5233, 5235. To obtain Vitreous Focuser (could use more spesifics about gossip items) -SDCategory: Western Plaguelands -EndScriptData */ - -/* ContentData -npcs_dithers_and_arbington -npc_myranda_the_hag -npc_the_scourge_cauldron -npc_andorhal_tower -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npcs_dithers_and_arbington -######*/ - -#define GOSSIP_HDA1 "What does the Felstone Field Cauldron need?" -#define GOSSIP_HDA2 "What does the Dalson's Tears Cauldron need?" -#define GOSSIP_HDA3 "What does the Writhing Haunt Cauldron need?" -#define GOSSIP_HDA4 "What does the Gahrron's Withering Cauldron need?" - -#define GOSSIP_SDA1 "Thanks, i need a Vitreous Focuser" - -class npcs_dithers_and_arbington : public CreatureScript -{ -public: - npcs_dithers_and_arbington() : CreatureScript("npcs_dithers_and_arbington") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(3980, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(3981, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(3982, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(3983, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 17529, false); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - if (player->GetQuestRewardStatus(5237) || player->GetQuestRewardStatus(5238)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(3985, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_myranda_the_hag -######*/ - -enum eMyranda -{ - QUEST_SUBTERFUGE = 5862, - QUEST_IN_DREAMS = 5944, - SPELL_SCARLET_ILLUSION = 17961 -}; - -#define GOSSIP_ITEM_ILLUSION "I am ready for the illusion, Myranda." - -class npc_myranda_the_hag : public CreatureScript -{ -public: - npc_myranda_the_hag() : CreatureScript("npc_myranda_the_hag") { } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_SCARLET_ILLUSION, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_SUBTERFUGE) == QUEST_STATUS_COMPLETE && - !player->GetQuestRewardStatus(QUEST_IN_DREAMS) && !player->HasAura(SPELL_SCARLET_ILLUSION)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ILLUSION, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(4773, creature->GetGUID()); - return true; - } - else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_the_scourge_cauldron -######*/ - -class npc_the_scourge_cauldron : public CreatureScript -{ -public: - npc_the_scourge_cauldron() : CreatureScript("npc_the_scourge_cauldron") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_the_scourge_cauldronAI (creature); - } - - struct npc_the_scourge_cauldronAI : public ScriptedAI - { - npc_the_scourge_cauldronAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - - void EnterCombat(Unit* /*who*/) {} - - void DoDie() - { - //summoner dies here - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - //override any database `spawntimesecs` to prevent duplicated summons - uint32 rTime = me->GetRespawnDelay(); - if (rTime<600) - me->SetRespawnDelay(600); - } - - void MoveInLineOfSight(Unit* who) - { - if (!who || who->GetTypeId() != TYPEID_PLAYER) - return; - - if (who->GetTypeId() == TYPEID_PLAYER) - { - switch (me->GetAreaId()) - { - case 199: //felstone - if (CAST_PLR(who)->GetQuestStatus(5216) == QUEST_STATUS_INCOMPLETE || - CAST_PLR(who)->GetQuestStatus(5229) == QUEST_STATUS_INCOMPLETE) - { - me->SummonCreature(11075, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); - DoDie(); - } - break; - case 200: //dalson - if (CAST_PLR(who)->GetQuestStatus(5219) == QUEST_STATUS_INCOMPLETE || - CAST_PLR(who)->GetQuestStatus(5231) == QUEST_STATUS_INCOMPLETE) - { - me->SummonCreature(11077, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); - DoDie(); - } - break; - case 201: //gahrron - if (CAST_PLR(who)->GetQuestStatus(5225) == QUEST_STATUS_INCOMPLETE || - CAST_PLR(who)->GetQuestStatus(5235) == QUEST_STATUS_INCOMPLETE) - { - me->SummonCreature(11078, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); - DoDie(); - } - break; - case 202: //writhing - if (CAST_PLR(who)->GetQuestStatus(5222) == QUEST_STATUS_INCOMPLETE || - CAST_PLR(who)->GetQuestStatus(5233) == QUEST_STATUS_INCOMPLETE) - { - me->SummonCreature(11076, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); - DoDie(); - } - break; - } - } - } - }; -}; - -/*###### -## npcs_andorhal_tower -######*/ - -enum eAndorhalTower -{ - GO_BEACON_TORCH = 176093 -}; - -class npc_andorhal_tower : public CreatureScript -{ -public: - npc_andorhal_tower() : CreatureScript("npc_andorhal_tower") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_andorhal_towerAI (creature); - } - - struct npc_andorhal_towerAI : public Scripted_NoMovementAI - { - npc_andorhal_towerAI(Creature* creature) : Scripted_NoMovementAI(creature) {} - - void MoveInLineOfSight(Unit* who) - { - if (!who || who->GetTypeId() != TYPEID_PLAYER) - return; - - if (me->FindNearestGameObject(GO_BEACON_TORCH, 10.0f)) - CAST_PLR(who)->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - } - }; -}; - -/*###### -## npc_anchorite_truuen -######*/ - -enum eTruuen -{ - NPC_GHOST_UTHER = 17233, - NPC_THEL_DANIS = 1854, - NPC_GHOUL = 1791, //ambush - - QUEST_TOMB_LIGHTBRINGER = 9446, - - SAY_WP_0 = 0, //Beware! We are attacked! - SAY_WP_1 = 1, //It must be the purity of the Mark of the Lightbringer that is drawing forth the Scourge to attack us. We must proceed with caution lest we be overwhelmed! - SAY_WP_2 = 2, //This land truly needs to be cleansed by the Light! Let us continue on to the tomb. It isn't far now... - SAY_WP_3 = 0, //Be welcome, friends! - SAY_WP_4 = 0, //Thank you for coming here in remembrance of me. Your efforts in recovering that symbol, while unnecessary, are certainly touching to an old man's heart. - SAY_WP_5 = 1, //Please, rise my friend. Keep the Blessing as a symbol of the strength of the Light and how heroes long gone might once again rise in each of us to inspire. - SAY_WP_6 = 2 //Thank you my friend for making this possible. This is a day that I shall never forget! I think I will stay a while. Please return to High Priestess MacDonnell at the camp. I know that she'll be keenly interested to know of what has transpired here. -}; - -class npc_anchorite_truuen : public CreatureScript -{ -public: - npc_anchorite_truuen() : CreatureScript("npc_anchorite_truuen") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - npc_escortAI* pEscortAI = CAST_AI(npc_anchorite_truuen::npc_anchorite_truuenAI, creature->AI()); - - if (quest->GetQuestId() == QUEST_TOMB_LIGHTBRINGER) - pEscortAI->Start(true, true, player->GetGUID()); - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_anchorite_truuenAI(creature); - } - - struct npc_anchorite_truuenAI : public npc_escortAI - { - npc_anchorite_truuenAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 m_uiChatTimer; - - uint64 UghostGUID; - uint64 TheldanisGUID; - - Creature* Ughost; - Creature* Theldanis; - - void Reset() - { - m_uiChatTimer = 7000; - } - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == NPC_GHOUL) - summoned->AI()->AttackStart(me); - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - - switch (waypointId) - { - case 8: - Talk(SAY_WP_0); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+7.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+5.0f, me->GetPositionY()+5.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - break; - case 9: - Talk(SAY_WP_1); - break; - case 14: - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+7.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+5.0f, me->GetPositionY()+5.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+10.0f, me->GetPositionY()+10.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - me->SummonCreature(NPC_GHOUL, me->GetPositionX()+8.0f, me->GetPositionY()+8.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); - break; - case 15: - Talk(SAY_WP_2); - case 21: - Theldanis = GetClosestCreatureWithEntry(me, NPC_THEL_DANIS, 150); - if (Theldanis) - Theldanis->AI()->Talk(SAY_WP_3); - break; - case 22: - break; - case 23: - Ughost = me->SummonCreature(NPC_GHOST_UTHER, 971.86f, -1825.42f, 81.99f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - if (Ughost) - { - Ughost->SetDisableGravity(true); - Ughost->AI()->Talk(SAY_WP_4, me->GetGUID()); - } - m_uiChatTimer = 4000; - break; - case 24: - if (Ughost) - Ughost->AI()->Talk(SAY_WP_5, me->GetGUID()); - m_uiChatTimer = 4000; - break; - case 25: - if (Ughost) - Ughost->AI()->Talk(SAY_WP_6, me->GetGUID()); - m_uiChatTimer = 4000; - break; - case 26: - if (player) - player->GroupEventHappens(QUEST_TOMB_LIGHTBRINGER, me); - break; - } - } - - void EnterCombat(Unit* /*who*/){} - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_TOMB_LIGHTBRINGER); - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - DoMeleeAttackIfReady(); - if (HasEscortState(STATE_ESCORT_ESCORTING)) - m_uiChatTimer = 6000; - } - }; -}; - -/*###### -## -######*/ - -void AddSC_western_plaguelands() -{ - new npcs_dithers_and_arbington(); - new npc_myranda_the_hag(); - new npc_the_scourge_cauldron(); - new npc_andorhal_tower(); - new npc_anchorite_truuen(); -} diff --git a/src/server/scripts/EasternKingdoms/westfall.cpp b/src/server/scripts/EasternKingdoms/westfall.cpp deleted file mode 100644 index 1b93cf1be71..00000000000 --- a/src/server/scripts/EasternKingdoms/westfall.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Westfall -SD%Complete: 90 -SDComment: Quest support: 155, 1651 -SDCategory: Westfall -EndScriptData */ - -/* ContentData -npc_daphne_stilwell -npc_defias_traitor -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_daphne_stilwell -######*/ - -enum eEnums -{ - SAY_DS_START = 0, - SAY_DS_DOWN_1 = 1, - SAY_DS_DOWN_2 = 2, - SAY_DS_DOWN_3 = 3, - SAY_DS_PROLOGUE = 4, - - SPELL_SHOOT = 6660, - QUEST_TOME_VALOR = 1651, - NPC_DEFIAS_RAIDER = 6180, - EQUIP_ID_RIFLE = 2511 -}; - -class npc_daphne_stilwell : public CreatureScript -{ -public: - npc_daphne_stilwell() : CreatureScript("npc_daphne_stilwell") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_TOME_VALOR) - { - creature->AI()->Talk(SAY_DS_START); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_daphne_stilwell::npc_daphne_stilwellAI, creature->AI())) - pEscortAI->Start(true, true, player->GetGUID()); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_daphne_stilwellAI(creature); - } - - struct npc_daphne_stilwellAI : public npc_escortAI - { - npc_daphne_stilwellAI(Creature* creature) : npc_escortAI(creature) {} - - uint32 uiWPHolder; - uint32 uiShootTimer; - - void Reset() - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - switch (uiWPHolder) - { - case 7: - Talk(SAY_DS_DOWN_1); - break; - case 8: - Talk(SAY_DS_DOWN_2); - break; - case 9: - Talk(SAY_DS_DOWN_3); - break; - } - } - else - uiWPHolder = 0; - - uiShootTimer = 0; - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - uiWPHolder = waypointId; - - switch (waypointId) - { - case 4: - SetEquipmentSlots(false, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE, EQUIP_ID_RIFLE); - me->SetSheath(SHEATH_STATE_RANGED); - me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING_NO_SHEATHE); - break; - case 7: - me->SummonCreature(NPC_DEFIAS_RAIDER, -11450.836f, 1569.755f, 54.267f, 4.230f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.697f, 1569.124f, 54.421f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.237f, 1568.307f, 54.620f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 8: - me->SetSheath(SHEATH_STATE_RANGED); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11450.836f, 1569.755f, 54.267f, 4.230f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.697f, 1569.124f, 54.421f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.237f, 1568.307f, 54.620f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.037f, 1570.213f, 54.961f, 4.283f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 9: - me->SetSheath(SHEATH_STATE_RANGED); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11450.836f, 1569.755f, 54.267f, 4.230f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.697f, 1569.124f, 54.421f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.237f, 1568.307f, 54.620f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.037f, 1570.213f, 54.961f, 4.283f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.018f, 1570.738f, 54.828f, 4.220f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 10: - SetRun(false); - break; - case 11: - Talk(SAY_DS_PROLOGUE); - break; - case 13: - SetEquipmentSlots(true); - me->SetSheath(SHEATH_STATE_UNARMED); - me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING_NO_SHEATHE); - break; - case 17: - player->GroupEventHappens(QUEST_TOME_VALOR, me); - break; - } - } - - void AttackStart(Unit* who) - { - if (!who) - return; - - if (me->Attack(who, false)) - { - me->AddThreat(who, 0.0f); - me->SetInCombatWith(who); - who->SetInCombatWith(me); - - me->GetMotionMaster()->MoveChase(who, 30.0f); - } - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void Update(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - if (uiShootTimer <= diff) - { - uiShootTimer = 1500; - - if (!me->IsWithinDist(me->getVictim(), ATTACK_DISTANCE)) - DoCast(me->getVictim(), SPELL_SHOOT); - } else uiShootTimer -= diff; - } - }; -}; - -/*###### -## npc_defias_traitor -######*/ -enum DefiasSays -{ - SAY_START = 0, - SAY_PROGRESS = 1, - SAY_END = 2, - SAY_AGGRO = 3 -}; - - -#define QUEST_DEFIAS_BROTHERHOOD 155 - -class npc_defias_traitor : public CreatureScript -{ -public: - npc_defias_traitor() : CreatureScript("npc_defias_traitor") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_DEFIAS_BROTHERHOOD) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_defias_traitor::npc_defias_traitorAI, creature->AI())) - pEscortAI->Start(true, true, player->GetGUID()); - - creature->AI()->Talk(SAY_START, player->GetGUID()); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_defias_traitorAI(creature); - } - - struct npc_defias_traitorAI : public npc_escortAI - { - npc_defias_traitorAI(Creature* creature) : npc_escortAI(creature) { Reset(); } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 35: - SetRun(false); - break; - case 36: - Talk(SAY_PROGRESS, player->GetGUID()); - break; - case 44: - Talk(SAY_END, player->GetGUID()); - player->GroupEventHappens(QUEST_DEFIAS_BROTHERHOOD, me); - break; - } - } - - void EnterCombat(Unit* who) - { - Talk(SAY_AGGRO, who->GetGUID()); - } - - void Reset() {} - }; -}; - -void AddSC_westfall() -{ - new npc_daphne_stilwell(); - new npc_defias_traitor(); -} diff --git a/src/server/scripts/EasternKingdoms/wetlands.cpp b/src/server/scripts/EasternKingdoms/wetlands.cpp deleted file mode 100644 index c8a1fc2b2b4..00000000000 --- a/src/server/scripts/EasternKingdoms/wetlands.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Wetlands -SD%Complete: 80 -SDComment: Quest support: 1249 -SDCategory: Wetlands -EndScriptData */ - -/* ContentData -npc_mikhail -npc_tapoke_slim_jahn -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_tapoke_slim_jahn -######*/ - -enum eTapokeSlim -{ - QUEST_MISSING_DIPLO_PT11 = 1249, - FACTION_ENEMY = 168, - SPELL_STEALTH = 1785, - SPELL_CALL_FRIENDS = 16457, //summons 1x friend - NPC_SLIMS_FRIEND = 4971, - NPC_TAPOKE_SLIM_JAHN = 4962 -}; - -class npc_tapoke_slim_jahn : public CreatureScript -{ -public: - npc_tapoke_slim_jahn() : CreatureScript("npc_tapoke_slim_jahn") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_tapoke_slim_jahnAI(creature); - } - - struct npc_tapoke_slim_jahnAI : public npc_escortAI - { - npc_tapoke_slim_jahnAI(Creature* creature) : npc_escortAI(creature) { } - - bool IsFriendSummoned; - - void Reset() - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - IsFriendSummoned = false; - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 2: - if (me->HasStealthAura()) - me->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); - SetRun(); - me->setFaction(FACTION_ENEMY); - break; - } - } - - void EnterCombat(Unit* /*who*/) - { - if (HasEscortState(STATE_ESCORT_ESCORTING) && !IsFriendSummoned && GetPlayerForEscort()) - { - for (uint8 i = 0; i < 3; ++i) - DoCast(me, SPELL_CALL_FRIENDS, true); - - IsFriendSummoned = true; - } - } - - void JustSummoned(Creature* summoned) - { - if (Player* player = GetPlayerForEscort()) - summoned->AI()->AttackStart(player); - } - - void AttackedBy(Unit* pAttacker) - { - if (me->getVictim()) - return; - - if (me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage) - { - if (HealthBelowPct(20)) - { - if (Player* player = GetPlayerForEscort()) - { - if (player->GetTypeId() == TYPEID_PLAYER) - CAST_PLR(player)->GroupEventHappens(QUEST_MISSING_DIPLO_PT11, me); - - uiDamage = 0; - - me->RestoreFaction(); - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(true); - - SetRun(false); - } - } - } - }; -}; - -/*###### -## npc_mikhail -######*/ - -class npc_mikhail : public CreatureScript -{ -public: - npc_mikhail() : CreatureScript("npc_mikhail") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT11) - { - Creature* pSlim = creature->FindNearestCreature(NPC_TAPOKE_SLIM_JAHN, 25.0f); - - if (!pSlim) - return false; - - if (!pSlim->HasStealthAura()) - pSlim->CastSpell(pSlim, SPELL_STEALTH, true); - - if (npc_tapoke_slim_jahn::npc_tapoke_slim_jahnAI* pEscortAI = CAST_AI(npc_tapoke_slim_jahn::npc_tapoke_slim_jahnAI, pSlim->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return false; - } -}; - -/*###### -## AddSC -######*/ - -void AddSC_wetlands() -{ - new npc_tapoke_slim_jahn(); - new npc_mikhail(); -} diff --git a/src/server/scripts/EasternKingdoms/zone_alterac_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_alterac_mountains.cpp new file mode 100644 index 00000000000..9b9af494554 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_alterac_mountains.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Alterac_Mountains +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Alterac Mountains +EndScriptData */ + +/* ContentData +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" + +/*void AddSC_alterac_mountains() +{ + Script* newscript; +}*/ diff --git a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp new file mode 100644 index 00000000000..d638a435936 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Arathi Highlands +SD%Complete: 100 +SDComment: Quest support: 665 +SDCategory: Arathi Highlands +EndScriptData */ + +/* ContentData +npc_professor_phizzlethorpe +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_professor_phizzlethorpe +######*/ + +enum eEnums +{ + SAY_PROGRESS_1 = 0, + SAY_PROGRESS_2 = 1, + SAY_PROGRESS_3 = 2, + EMOTE_PROGRESS_4 = 3, + SAY_AGGRO = 4, + SAY_PROGRESS_5 = 5, + SAY_PROGRESS_6 = 6, + SAY_PROGRESS_7 = 7, + EMOTE_PROGRESS_8 = 8, + SAY_PROGRESS_9 = 9, + + QUEST_SUNKEN_TREASURE = 665, + MOB_VENGEFUL_SURGE = 2776 +}; + +class npc_professor_phizzlethorpe : public CreatureScript +{ + public: + + npc_professor_phizzlethorpe() + : CreatureScript("npc_professor_phizzlethorpe") + { + } + + struct npc_professor_phizzlethorpeAI : public npc_escortAI + { + npc_professor_phizzlethorpeAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 4: + Talk(SAY_PROGRESS_2, player->GetGUID()); + break; + case 5: + Talk(SAY_PROGRESS_3, player->GetGUID()); + break; + case 8: + Talk(EMOTE_PROGRESS_4); + break; + case 9: + me->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); + me->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0); + break; + case 10: + Talk(SAY_PROGRESS_5, player->GetGUID()); + break; + case 11: + Talk(SAY_PROGRESS_6, player->GetGUID()); + SetRun(); + break; + case 19: + Talk(SAY_PROGRESS_7, player->GetGUID()); + break; + case 20: + Talk(EMOTE_PROGRESS_8); + Talk(SAY_PROGRESS_9, player->GetGUID()); + player->GroupEventHappens(QUEST_SUNKEN_TREASURE, me); + break; + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void EnterCombat(Unit* /*who*/) + { + Talk(SAY_AGGRO); + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_professor_phizzlethorpeAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_SUNKEN_TREASURE) + { + creature->AI()->Talk(SAY_PROGRESS_1, player->GetGUID()); + if (npc_escortAI* pEscortAI = CAST_AI(npc_professor_phizzlethorpeAI, (creature->AI()))) + pEscortAI->Start(false, false, player->GetGUID(), quest); + + creature->setFaction(113); + } + return true; + } +}; + +void AddSC_arathi_highlands() +{ + new npc_professor_phizzlethorpe(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp b/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp new file mode 100644 index 00000000000..4f76edf4406 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_blasted_lands.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Blasted_Lands +SD%Complete: 90 +SDComment: Quest support: 3628. Teleporter to Rise of the Defiler missing group support. +SDCategory: Blasted Lands +EndScriptData */ + +/* ContentData +npc_deathly_usher +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npc_deathly_usher +######*/ + +#define GOSSIP_ITEM_USHER "I wish to to visit the Rise of the Defiler." + +#define SPELL_TELEPORT_SINGLE 12885 +#define SPELL_TELEPORT_SINGLE_IN_GROUP 13142 +#define SPELL_TELEPORT_GROUP 27686 + +class npc_deathly_usher : public CreatureScript +{ +public: + npc_deathly_usher() : CreatureScript("npc_deathly_usher") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_TELEPORT_SINGLE, true); + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(3628) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(10757)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_USHER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +void AddSC_blasted_lands() +{ + new npc_deathly_usher(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp new file mode 100644 index 00000000000..b6899c534e4 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Burning_Steppes +SD%Complete: 100 +SDComment: Quest support: 4224, 4866 +SDCategory: Burning Steppes +EndScriptData */ + +/* ContentData +npc_ragged_john +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npc_ragged_john +######*/ + +#define GOSSIP_HELLO "Official buisness, John. I need some information about Marsha Windsor. Tell me about the last time you saw him." +#define GOSSIP_SELECT1 "So what did you do?" +#define GOSSIP_SELECT2 "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'." +#define GOSSIP_SELECT3 "Ironfoe?" +#define GOSSIP_SELECT4 "Interesting... continue John." +#define GOSSIP_SELECT5 "So that's how Windsor died..." +#define GOSSIP_SELECT6 "So how did he die?" +#define GOSSIP_SELECT7 "Ok so where the hell is he? Wait a minute! Are you drunk?" +#define GOSSIP_SELECT8 "WHY is he in Blackrock Depths?" +#define GOSSIP_SELECT9 "300? So the Dark Irons killed him and dragged him into the Depths?" +#define GOSSIP_SELECT10 "Ahh... Ironfoe" +#define GOSSIP_SELECT11 "Thanks, Ragged John. Your story was very uplifting and informative" + +class npc_ragged_john : public CreatureScript +{ +public: + npc_ragged_john() : CreatureScript("npc_ragged_john") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(2714, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(2715, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(2716, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(2717, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + player->SEND_GOSSIP_MENU(2718, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + player->SEND_GOSSIP_MENU(2719, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); + player->SEND_GOSSIP_MENU(2720, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); + player->SEND_GOSSIP_MENU(2721, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+8: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); + player->SEND_GOSSIP_MENU(2722, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+9: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); + player->SEND_GOSSIP_MENU(2723, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+10: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); + player->SEND_GOSSIP_MENU(2725, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+11: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(4224); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(4224) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(2713, creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ragged_johnAI (creature); + } + + struct npc_ragged_johnAI : public ScriptedAI + { + npc_ragged_johnAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + + void MoveInLineOfSight(Unit* who) + { + if (who->HasAura(16468)) + { + if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 15) && who->isInAccessiblePlaceFor(me)) + { + DoCast(who, 16472); + CAST_PLR(who)->AreaExploredOrEventHappens(4866); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void EnterCombat(Unit* /*who*/) {} + }; +}; + +void AddSC_burning_steppes() +{ + new npc_ragged_john(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_duskwood.cpp b/src/server/scripts/EasternKingdoms/zone_duskwood.cpp new file mode 100644 index 00000000000..1ce83d31a63 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_duskwood.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Duskwood +SD%Complete: 100 +SDComment: Quest Support:8735 +SDCategory: Duskwood +EndScriptData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" + +enum Yells +{ + YELL_TWILIGHTCORRUPTOR_RESPAWN = 0, + YELL_TWILIGHTCORRUPTOR_AGGRO = 1, + YELL_TWILIGHTCORRUPTOR_KILL = 2, +}; + + +/*###### +# at_twilight_grove +######*/ + +class at_twilight_grove : public AreaTriggerScript +{ +public: + at_twilight_grove() : AreaTriggerScript("at_twilight_grove") { } + + bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) + { + if (player->HasQuestForItem(21149)) + { + if (Unit* TCorrupter = player->SummonCreature(15625, -10328.16f, -489.57f, 49.95f, 0, TEMPSUMMON_MANUAL_DESPAWN, 60000)) + { + TCorrupter->setFaction(14); + TCorrupter->SetMaxHealth(832750); + } + if (Creature* CorrupterSpeaker = player->SummonCreature(1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()-1, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) + { + CorrupterSpeaker->SetName("Twilight Corrupter"); + CorrupterSpeaker->SetVisible(true); + CorrupterSpeaker->AI()->Talk(YELL_TWILIGHTCORRUPTOR_RESPAWN, player->GetGUID()); + } + } + return false; + }; +}; + +/*###### +# boss_twilight_corrupter +######*/ + +#define SPELL_SOUL_CORRUPTION 25805 +#define SPELL_CREATURE_OF_NIGHTMARE 25806 +#define SPELL_LEVEL_UP 24312 + +class boss_twilight_corrupter : public CreatureScript +{ +public: + boss_twilight_corrupter() : CreatureScript("boss_twilight_corrupter") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_twilight_corrupterAI (creature); + } + + struct boss_twilight_corrupterAI : public ScriptedAI + { + boss_twilight_corrupterAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 SoulCorruption_Timer; + uint32 CreatureOfNightmare_Timer; + uint8 KillCount; + + void Reset() + { + SoulCorruption_Timer = 15000; + CreatureOfNightmare_Timer = 30000; + KillCount = 0; + } + void EnterCombat(Unit* /*who*/) + { + Talk(YELL_TWILIGHTCORRUPTOR_AGGRO); + } + + void KilledUnit(Unit* victim) + { + if (victim->GetTypeId() == TYPEID_PLAYER) + { + ++KillCount; + Talk(YELL_TWILIGHTCORRUPTOR_KILL, victim->GetGUID()); + + if (KillCount == 3) + { + DoCast(me, SPELL_LEVEL_UP, true); + KillCount = 0; + } + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + if (SoulCorruption_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_SOUL_CORRUPTION); + SoulCorruption_Timer = rand()%4000+15000; //gotta confirm Timers + } else SoulCorruption_Timer-=diff; + + if (CreatureOfNightmare_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_CREATURE_OF_NIGHTMARE); + CreatureOfNightmare_Timer = 45000; //gotta confirm Timers + } else CreatureOfNightmare_Timer-=diff; + DoMeleeAttackIfReady(); + }; + }; +}; + +void AddSC_duskwood() +{ + new boss_twilight_corrupter(); + new at_twilight_grove(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp new file mode 100644 index 00000000000..a2522fd9495 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_eastern_plaguelands.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Eastern_Plaguelands +SD%Complete: 100 +SDComment: Quest support: 5211, 5742. Special vendor Augustus the Touched +SDCategory: Eastern Plaguelands +EndScriptData */ + +/* ContentData +mobs_ghoul_flayer +npc_augustus_the_touched +npc_darrowshire_spirit +npc_tirion_fordring +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" +#include "WorldSession.h" + +class mobs_ghoul_flayer : public CreatureScript +{ +public: + mobs_ghoul_flayer() : CreatureScript("mobs_ghoul_flayer") { } + + struct mobs_ghoul_flayerAI : public ScriptedAI + { + mobs_ghoul_flayerAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() {} + + void EnterCombat(Unit* /*who*/) {} + + void JustDied(Unit* killer) + { + if (killer->GetTypeId() == TYPEID_PLAYER) + me->SummonCreature(11064, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new mobs_ghoul_flayerAI (creature); + } +}; + +/*###### +## npc_augustus_the_touched +######*/ + +class npc_augustus_the_touched : public CreatureScript +{ +public: + npc_augustus_the_touched() : CreatureScript("npc_augustus_the_touched") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor() && player->GetQuestRewardStatus(6164)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_darrowshire_spirit +######*/ + +#define SPELL_SPIRIT_SPAWNIN 17321 + +class npc_darrowshire_spirit : public CreatureScript +{ +public: + npc_darrowshire_spirit() : CreatureScript("npc_darrowshire_spirit") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + player->SEND_GOSSIP_MENU(3873, creature->GetGUID()); + player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_darrowshire_spiritAI (creature); + } + + struct npc_darrowshire_spiritAI : public ScriptedAI + { + npc_darrowshire_spiritAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + DoCast(me, SPELL_SPIRIT_SPAWNIN); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + } + + void EnterCombat(Unit* /*who*/) {} + }; +}; + +/*###### +## npc_tirion_fordring +######*/ + +#define GOSSIP_HELLO "I am ready to hear your tale, Tirion." +#define GOSSIP_SELECT1 "Thank you, Tirion. What of your identity?" +#define GOSSIP_SELECT2 "That is terrible." +#define GOSSIP_SELECT3 "I will, Tirion." + +class npc_tirion_fordring : public CreatureScript +{ +public: + npc_tirion_fordring() : CreatureScript("npc_tirion_fordring") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(4493, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(4494, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(4495, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(5742); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(5742) == QUEST_STATUS_INCOMPLETE && player->getStandState() == UNIT_STAND_STATE_SIT) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +void AddSC_eastern_plaguelands() +{ + new mobs_ghoul_flayer(); + new npc_augustus_the_touched(); + new npc_darrowshire_spirit(); + new npc_tirion_fordring(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp b/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp new file mode 100644 index 00000000000..432768a51de --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_eversong_woods.cpp @@ -0,0 +1,634 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Eversong_Woods +SD%Complete: 100 +SDComment: Quest support: 8483, 8488, 8490, 9686 +SDCategory: Eversong Woods +EndScriptData */ + +/* ContentData +npc_prospector_anvilward +npc_apprentice_mirveda +npc_infused_crystal +npc_kelerun_bloodmourn +go_harbinger_second_trial +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## Quest 9686 Second Trial +######*/ + +enum SeconTrial +{ + QUEST_SECOND_TRIAL = 9686, + OFFSET_NEXT_ATTACK = 750, +}; + +enum eSpells +{ + SPELL_FLASH_OF_LIGHT = 19939, + SPELL_SEAL_OF_JUSTICE = 20164, + SPELL_JUDGEMENT_OF_LIGHT = 20271, + SPELL_SEAL_OF_COMMAND = 20375, +}; + +enum eNpc +{ + MASTER_KELERUN_BLOODMOURN = 17807, + CHAMPION_BLOODWRATH = 17809, + CHAMPION_LIGHTREND = 17810, + CHAMPION_SWIFTBLADE = 17811, + CHAMPION_SUNSTRIKER = 17812, +}; + +enum eFaction +{ + FACTION_HOSTILE = 45, + FACTION_FRIENDLY = 7, +}; + +enum eSays +{ + TEXT_SECOND_TRIAL_1 = 0, + TEXT_SECOND_TRIAL_2 = 1, + TEXT_SECOND_TRIAL_3 = 2, + TEXT_SECOND_TRIAL_4 = 3, +}; + +struct Locations +{ + float x, y, z, o; +}; + +static Locations SpawnPosition[]= +{ + {5.3f, -11.8f, 0.361f, 4.2f}, + {11.2f, -29.17f, 0.361f, 2.7f}, + {-5.7f, -34.85f, 0.361f, 1.09f}, + {-11.9f, -18, 0.361f, 5.87f} +}; + +static uint32 PaladinEntry[] = {CHAMPION_BLOODWRATH, CHAMPION_LIGHTREND, CHAMPION_SWIFTBLADE, CHAMPION_SUNSTRIKER}; + +/*###### +## npc_second_trial_paladin +######*/ + +class npc_second_trial_paladin : public CreatureScript +{ +public: + npc_second_trial_paladin() : CreatureScript("npc_second_trial_paladin") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_secondTrialAI (creature); + } + + struct npc_secondTrialAI : public ScriptedAI + { + npc_secondTrialAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 timer; + uint8 questPhase; + uint64 summonerGuid; + + bool spellFlashLight; + bool spellJustice; + bool spellJudLight; + bool spellCommand; + + uint32 timerFlashLight; + uint32 timerJustice; + uint32 timerJudLight; + uint32 timerCommand; + + void Reset() + { + timer = 2000; + questPhase = 0; + summonerGuid = 0; + + me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_KNEEL); + me->setFaction(FACTION_FRIENDLY); + + spellFlashLight = false; + spellJustice = false; + spellJudLight = false; + spellCommand = false; + + switch (me->GetEntry()) + { + case CHAMPION_BLOODWRATH: + spellFlashLight = true; + timerFlashLight = 3225; + break; + case CHAMPION_LIGHTREND: + spellJustice = true; + timerJustice = 500; + break; + case CHAMPION_SWIFTBLADE: + spellJudLight = false; // Misses Script Effect // http://www.wowhead.com/?spell=20271 + timerJudLight = 500; + break; + case CHAMPION_SUNSTRIKER: + spellFlashLight = true; + spellJudLight = false; // Misses Script Effect // http://www.wowhead.com/?spell=20271 + spellCommand = false; // Misses Dummy // http://www.wowhead.com/?spell=20375 + timerFlashLight = 3225; + timerJudLight = 500; + timerCommand = 1500; + break; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (questPhase == 1) + { + if (timer <= diff) + { + me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); + me->setFaction(FACTION_HOSTILE); + questPhase = 0; + + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) + { + me->AddThreat(target, 5000000.0f); + AttackStart(target); + } + } + else + timer -= diff; + } + + if (!UpdateVictim()) + return; + + // healer + if (spellFlashLight && HealthBelowPct(70)) + { + if (timerFlashLight <= diff) + { + DoCast(me, SPELL_FLASH_OF_LIGHT); + timerFlashLight = 3225 + rand()%3225; + } + else + timerFlashLight -= diff; + } + + if (spellJustice) + { + if (timerJustice <= diff) + { + DoCast(me, SPELL_SEAL_OF_JUSTICE); + timerJustice = urand(10000, 20000); + } + else + timerJustice -= diff; + } + + if (spellJudLight) + { + if (timerJudLight <= diff) + { + DoCast(me, SPELL_JUDGEMENT_OF_LIGHT); + timerJudLight = urand(10000, 20000); + } + else + timerJudLight -= diff; + } + + if (spellCommand) + { + if (timerCommand <= diff) + { + DoCast(me, SPELL_SEAL_OF_COMMAND); + timerCommand = urand(20000, 40000); + } + else + timerCommand -= diff; + } + + DoMeleeAttackIfReady(); + } + + void Activate(uint64 summonerguid) + { + questPhase = 1; + summonerGuid = summonerguid; + } + + void KilledUnit(Unit* Killed) + { + if (Killed->GetTypeId() == TYPEID_PLAYER) + if (CAST_PLR(Killed)->GetQuestStatus(QUEST_SECOND_TRIAL) == QUEST_STATUS_INCOMPLETE) + CAST_PLR(Killed)->FailQuest(QUEST_SECOND_TRIAL); + } + + void JustDied(Unit* killer); + }; +}; + +/*###### +## npc_second_trial_controller +######*/ + +class npc_second_trial_controller : public CreatureScript +{ +public: + npc_second_trial_controller() : CreatureScript("npc_second_trial_controller") { } + + bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest) + { + // One Player exclusive quest, wait for user go activation + if (quest->GetQuestId() == QUEST_SECOND_TRIAL) + CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, creature->AI())->questPhase = 1; + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + // quest only available if not already started + // Quest_template flag is set to : QUEST_FLAGS_EVENT + // Escort quests or any other event-driven quests. If player in party, all players that can accept this quest will receive confirmation box to accept quest. + // !not sure if this really works! + + if (CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, creature->AI())->questPhase == 0) + { + player->PrepareQuestMenu(creature->GetGUID()); + player->SendPreparedQuest(creature->GetGUID()); + } + + player->SEND_GOSSIP_MENU(creature->GetEntry(), creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new master_kelerun_bloodmournAI (creature); + } + + struct master_kelerun_bloodmournAI : public ScriptedAI + { + master_kelerun_bloodmournAI(Creature* creature) : ScriptedAI(creature) {} + + uint8 questPhase; + uint8 paladinPhase; + uint32 timer; + + uint64 paladinGuid[4]; + + void Reset() + { + questPhase = 0; + timer = 60000; + paladinPhase = 0; + for (uint8 i = 0; i < 4; ++i) + paladinGuid[i] = 0; + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + // Quest accepted but object not activated, object despawned (if in sync 1 minute!) + if (questPhase == 1) + { + if (timer <= diff) + Reset(); + else + timer -= diff; + } + // fight the 4 paladin mobs phase + else if (questPhase == 2) + { + if (timer <= diff) + { + if (Creature* paladinSpawn = Unit::GetCreature((*me), paladinGuid[paladinPhase])) + { + CAST_AI(npc_second_trial_paladin::npc_secondTrialAI, paladinSpawn->AI())->Activate(me->GetGUID()); + + switch (paladinPhase) + { + case 0: + Talk(TEXT_SECOND_TRIAL_1); + break; + case 1: + Talk(TEXT_SECOND_TRIAL_2); + break; + case 2: + Talk(TEXT_SECOND_TRIAL_3); + break; + case 3: + Talk(TEXT_SECOND_TRIAL_4); + break; + } + } + else + Reset(); + + questPhase = 4; + timer = OFFSET_NEXT_ATTACK; + } + else + timer -= diff; + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + + void StartEvent() + { + if (questPhase == 1) + { // no player check, quest can be finished as group, so no complex PlayerGUID/group search code + for (uint8 i = 0; i < 4; ++i) + if (Creature* summoned = DoSpawnCreature(PaladinEntry[i], SpawnPosition[i].x, SpawnPosition[i].y, SpawnPosition[i].z, SpawnPosition[i].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 180000)) + paladinGuid[i] = summoned->GetGUID(); + + timer = OFFSET_NEXT_ATTACK; + questPhase = 2; + } + } + + void SecondTrialKill() + { + if (questPhase > 0) + { + ++paladinPhase; + + if (paladinPhase < 4) + questPhase = 2; + else + Reset(); // Quest Complete, QuestComplete handler is + } + } + + void SummonedCreatureDespawn(Creature* /*c*/) {} + }; +}; + +void npc_second_trial_paladin::npc_secondTrialAI::JustDied(Unit* Killer) +{ + if (Killer->GetTypeId() == TYPEID_PLAYER) + { + if (Creature* summoner = Unit::GetCreature((*me), summonerGuid)) + CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, summoner->AI())->SecondTrialKill(); + + // last kill quest complete for group + if (me->GetEntry() == CHAMPION_SUNSTRIKER) + { + if (Killer->GetTypeId() == TYPEID_PLAYER) + Killer->ToPlayer()->GroupEventHappens(QUEST_SECOND_TRIAL, Killer); + } + } +} + +/*###### +## go_second_trial +######*/ +class go_second_trial : public GameObjectScript +{ +public: + go_second_trial() : GameObjectScript("go_second_trial") { } + + bool OnGossipHello(Player* /*player*/, GameObject* go) + { + // find spawn :: master_kelerun_bloodmourn + if (Creature* creature = go->FindNearestCreature(MASTER_KELERUN_BLOODMOURN, 30.0f)) + CAST_AI(npc_second_trial_controller::master_kelerun_bloodmournAI, creature->AI())->StartEvent(); + + return true; + } +}; + +/*###### +## npc_apprentice_mirveda +######*/ + +#define QUEST_UNEXPECTED_RESULT 8488 +#define MOB_GHARZUL 15958 +#define MOB_ANGERSHADE 15656 + +class npc_apprentice_mirveda : public CreatureScript +{ +public: + npc_apprentice_mirveda() : CreatureScript("npc_apprentice_mirveda") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_UNEXPECTED_RESULT) + { + CAST_AI(npc_apprentice_mirveda::npc_apprentice_mirvedaAI, creature->AI())->Summon = true; + CAST_AI(npc_apprentice_mirveda::npc_apprentice_mirvedaAI, creature->AI())->PlayerGUID = player->GetGUID(); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_apprentice_mirvedaAI (creature); + } + + struct npc_apprentice_mirvedaAI : public ScriptedAI + { + npc_apprentice_mirvedaAI(Creature* creature) : ScriptedAI(creature), Summons(me) {} + + uint32 KillCount; + uint64 PlayerGUID; + bool Summon; + SummonList Summons; + + void Reset() + { + KillCount = 0; + PlayerGUID = 0; + Summons.DespawnAll(); + Summon = false; + } + + void EnterCombat(Unit* /*who*/){} + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + Summons.Summon(summoned); + } + + void SummonedCreatureDespawn(Creature* summoned) + { + Summons.Despawn(summoned); + ++KillCount; + } + + void JustDied(Unit* /*killer*/) + { + if (PlayerGUID) + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + player->FailQuest(QUEST_UNEXPECTED_RESULT); + } + + void UpdateAI(const uint32 /*diff*/) + { + if (KillCount >= 3 && PlayerGUID) + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + player->CompleteQuest(QUEST_UNEXPECTED_RESULT); + + if (Summon) + { + me->SummonCreature(MOB_GHARZUL, 8745, -7134.32f, 35.22f, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000); + me->SummonCreature(MOB_ANGERSHADE, 8745, -7134.32f, 35.22f, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000); + me->SummonCreature(MOB_ANGERSHADE, 8745, -7134.32f, 35.22f, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000); + Summon = false; + } + } + }; +}; + +/*###### +## npc_infused_crystal +######*/ + +enum InfusedCrystal +{ + MOB_ENRAGED_WRAITH = 17086, + EMOTE = 0, + QUEST_POWERING_OUR_DEFENSES = 8490 +}; + +struct Location +{ + float x, y, z; +}; + +static Location SpawnLocations[] = +{ + {8270.68f, -7188.53f, 139.619f}, + {8284.27f, -7187.78f, 139.603f}, + {8297.43f, -7193.53f, 139.603f}, + {8303.5f, -7201.96f, 139.577f}, + {8273.22f, -7241.82f, 139.382f}, + {8254.89f, -7222.12f, 139.603f}, + {8278.51f, -7242.13f, 139.162f}, + {8267.97f, -7239.17f, 139.517f} +}; + +class npc_infused_crystal : public CreatureScript +{ +public: + npc_infused_crystal() : CreatureScript("npc_infused_crystal") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_infused_crystalAI (creature); + } + + struct npc_infused_crystalAI : public Scripted_NoMovementAI + { + npc_infused_crystalAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + + uint32 EndTimer; + uint32 WaveTimer; + bool Completed; + bool Progress; + uint64 PlayerGUID; + + void Reset() + { + EndTimer = 0; + Completed = false; + Progress = false; + PlayerGUID = 0; + WaveTimer = 0; + } + + void MoveInLineOfSight(Unit* who) + { + if (!Progress && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 10.0f)) + { + if (CAST_PLR(who)->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) == QUEST_STATUS_INCOMPLETE) + { + PlayerGUID = who->GetGUID(); + WaveTimer = 1000; + EndTimer = 60000; + Progress = true; + } + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void JustDied(Unit* /*killer*/) + { + if (PlayerGUID && !Completed) + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + CAST_PLR(player)->FailQuest(QUEST_POWERING_OUR_DEFENSES); + } + + void UpdateAI(const uint32 diff) + { + if (EndTimer < diff && Progress) + { + Talk(EMOTE); + Completed = true; + if (PlayerGUID) + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + CAST_PLR(player)->CompleteQuest(QUEST_POWERING_OUR_DEFENSES); + + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + me->RemoveCorpse(); + } else EndTimer -= diff; + + if (WaveTimer < diff && !Completed && Progress) + { + uint32 ran1 = rand()%8; + uint32 ran2 = rand()%8; + uint32 ran3 = rand()%8; + me->SummonCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran1].x, SpawnLocations[ran1].y, SpawnLocations[ran1].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); + me->SummonCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran2].x, SpawnLocations[ran2].y, SpawnLocations[ran2].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); + me->SummonCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran3].x, SpawnLocations[ran3].y, SpawnLocations[ran3].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); + WaveTimer = 30000; + } else WaveTimer -= diff; + } + }; +}; + +void AddSC_eversong_woods() +{ + new npc_second_trial_controller(); + new npc_second_trial_paladin(); + new go_second_trial(); + new npc_apprentice_mirveda(); + new npc_infused_crystal(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp new file mode 100644 index 00000000000..9e00ceb2aa5 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Ghostlands +SD%Complete: 100 +SDComment: Quest support: 9692, 9212. Obtain Budd's Guise of Zul'aman. Vendor Rathis Tomber +SDCategory: Ghostlands +EndScriptData */ + +/* ContentData +npc_blood_knight_dawnstar +npc_budd_nedreck +npc_rathis_tomber +npc_ranger_lilatha +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npc_budd_nedreck +######*/ + +#define GOSSIP_HBN "You gave the crew disguises?" + +class npc_budd_nedreck : public CreatureScript +{ +public: + npc_budd_nedreck() : CreatureScript("npc_budd_nedreck") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, 42540, false); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(11166) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_rathis_tomber +######*/ + +class npc_rathis_tomber : public CreatureScript +{ +public: + npc_rathis_tomber() : CreatureScript("npc_rathis_tomber") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor() && player->GetQuestRewardStatus(9152)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(8432, creature->GetGUID()); + }else + player->SEND_GOSSIP_MENU(8431, creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_ranger_lilatha +######*/ + +enum eEnums +{ + SAY_START = 0, + SAY_PROGRESS1 = 1, + SAY_PROGRESS2 = 2, + SAY_PROGRESS3 = 3, + SAY_END1 = 4, + SAY_END2 = 5, + SAY_CAPTAIN_ANSWER = 0, + + QUEST_ESCAPE_FROM_THE_CATACOMBS = 9212, + GO_CAGE = 181152, + NPC_CAPTAIN_HELIOS = 16220, + FACTION_SMOON_E = 1603 +}; + +class npc_ranger_lilatha : public CreatureScript +{ +public: + npc_ranger_lilatha() : CreatureScript("npc_ranger_lilatha") { } + + struct npc_ranger_lilathaAI : public npc_escortAI + { + npc_ranger_lilathaAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 0: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) + Cage->SetGoState(GO_STATE_ACTIVE); + Talk(SAY_START, player->GetGUID()); + break; + case 5: + Talk(SAY_PROGRESS1, player->GetGUID()); + break; + case 11: + Talk(SAY_PROGRESS2, player->GetGUID()); + me->SetOrientation(4.762841f); + break; + case 18: + { + Talk(SAY_PROGRESS3, player->GetGUID()); + Creature* Summ1 = me->SummonCreature(16342, 7627.083984f, -7532.538086f, 152.128616f, 1.082733f, TEMPSUMMON_DEAD_DESPAWN, 0); + Creature* Summ2 = me->SummonCreature(16343, 7620.432129f, -7532.550293f, 152.454865f, 0.827478f, TEMPSUMMON_DEAD_DESPAWN, 0); + if (Summ1 && Summ2) + { + Summ1->Attack(me, true); + Summ2->Attack(player, true); + } + me->AI()->AttackStart(Summ1); + } + break; + case 19: + me->SetWalk(false); + break; + case 25: + me->SetWalk(true); + break; + case 30: + if (player->GetTypeId() == TYPEID_PLAYER) + CAST_PLR(player)->GroupEventHappens(QUEST_ESCAPE_FROM_THE_CATACOMBS, me); + break; + case 32: + me->SetOrientation(2.978281f); + Talk(SAY_END1, player->GetGUID()); + break; + case 33: + me->SetOrientation(5.858011f); + Talk(SAY_END2, player->GetGUID()); + Creature* CaptainHelios = me->FindNearestCreature(NPC_CAPTAIN_HELIOS, 50); + if (CaptainHelios) + CaptainHelios->AI()->Talk(SAY_CAPTAIN_ANSWER, player->GetGUID()); + break; + } + } + + void Reset() + { + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) + Cage->SetGoState(GO_STATE_READY); + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPE_FROM_THE_CATACOMBS) + { + creature->setFaction(113); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_ranger_lilatha::npc_ranger_lilathaAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ranger_lilathaAI(creature); + } + +}; + +void AddSC_ghostlands() +{ + new npc_budd_nedreck(); + new npc_rathis_tomber(); + new npc_ranger_lilatha(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp new file mode 100644 index 00000000000..ffd31937677 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Hinterlands +SD%Complete: 100 +SDComment: Quest support: 863, 2742 +SDCategory: The Hinterlands +EndScriptData */ + +/* ContentData +npc_00x09hl +npc_rinji +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_00x09hl +######*/ + +enum eOOX +{ + SAY_OOX_START = 0, + SAY_OOX_AGGRO = 1, + SAY_OOX_AMBUSH = 3, + SAY_OOX_AMBUSH_REPLY = 4, + SAY_OOX_END = 5, + + QUEST_RESQUE_OOX_09 = 836, + + NPC_MARAUDING_OWL = 7808, + NPC_VILE_AMBUSHER = 7809, + + FACTION_ESCORTEE_A = 774, + FACTION_ESCORTEE_H = 775 +}; + +class npc_00x09hl : public CreatureScript +{ +public: + npc_00x09hl() : CreatureScript("npc_00x09hl") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_RESQUE_OOX_09) + { + creature->SetStandState(UNIT_STAND_STATE_STAND); + + if (player->GetTeam() == ALLIANCE) + creature->setFaction(FACTION_ESCORTEE_A); + else if (player->GetTeam() == HORDE) + creature->setFaction(FACTION_ESCORTEE_H); + + creature->AI()->Talk(SAY_OOX_START, player->GetGUID()); + + if (npc_00x09hlAI* pEscortAI = CAST_AI(npc_00x09hl::npc_00x09hlAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_00x09hlAI(creature); + } + + struct npc_00x09hlAI : public npc_escortAI + { + npc_00x09hlAI(Creature* creature) : npc_escortAI(creature) { } + + void Reset() { } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 26: + Talk(SAY_OOX_AMBUSH); + break; + case 43: + Talk(SAY_OOX_AMBUSH); + break; + case 64: + Talk(SAY_OOX_END); + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_RESQUE_OOX_09, me); + break; + } + } + + void WaypointStart(uint32 uiPointId) + { + switch (uiPointId) + { + case 27: + for (uint8 i = 0; i < 3; ++i) + { + const Position src = {147.927444f, -3851.513428f, 130.893f, 0}; + Position dst; + me->GetRandomPoint(src, 7.0f, dst); + DoSummon(NPC_MARAUDING_OWL, dst, 25000, TEMPSUMMON_CORPSE_TIMED_DESPAWN); + } + break; + case 44: + for (uint8 i = 0; i < 3; ++i) + { + const Position src = {-141.151581f, -4291.213867f, 120.130f, 0}; + Position dst; + me->GetRandomPoint(src, 7.0f, dst); + me->SummonCreature(NPC_VILE_AMBUSHER, dst, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 25000); + } + break; + } + } + + void EnterCombat(Unit* who) + { + if (who->GetEntry() == NPC_MARAUDING_OWL || who->GetEntry() == NPC_VILE_AMBUSHER) + return; + + Talk(SAY_OOX_AGGRO); + } + + void JustSummoned(Creature* summoned) + { + summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + } + }; +}; + +/*###### +## npc_rinji +######*/ + +enum eRinji +{ + SAY_RIN_BY_OUTRUNNER = 0, + + SAY_RIN_FREE = 0, //from here + SAY_RIN_HELP = 1, + SAY_RIN_COMPLETE = 2, + SAY_RIN_PROGRESS_1 = 3, + SAY_RIN_PROGRESS_2 = 4, + + QUEST_RINJI_TRAPPED = 2742, + NPC_RANGER = 2694, + NPC_OUTRUNNER = 2691, + GO_RINJI_CAGE = 142036 +}; + +struct Location +{ + float m_fX, m_fY, m_fZ; +}; + +Location m_afAmbushSpawn[] = +{ + {191.296204f, -2839.329346f, 107.388f}, + {70.972466f, -2848.674805f, 109.459f} +}; + +Location m_afAmbushMoveTo[] = +{ + {166.630386f, -2824.780273f, 108.153f}, + {70.886589f, -2874.335449f, 116.675f} +}; + +class npc_rinji : public CreatureScript +{ +public: + npc_rinji() : CreatureScript("npc_rinji") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_RINJI_TRAPPED) + { + if (GameObject* go = creature->FindNearestGameObject(GO_RINJI_CAGE, INTERACTION_DISTANCE)) + go->UseDoorOrButton(); + + if (npc_rinjiAI* pEscortAI = CAST_AI(npc_rinji::npc_rinjiAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_rinjiAI(creature); + } + + struct npc_rinjiAI : public npc_escortAI + { + npc_rinjiAI(Creature* creature) : npc_escortAI(creature) + { + m_bIsByOutrunner = false; + m_iSpawnId = 0; + } + + bool m_bIsByOutrunner; + uint32 m_uiPostEventCount; + uint32 m_uiPostEventTimer; + int m_iSpawnId; + + void Reset() + { + m_uiPostEventCount = 0; + m_uiPostEventTimer = 3000; + } + + void JustRespawned() + { + m_bIsByOutrunner = false; + m_iSpawnId = 0; + + npc_escortAI::JustRespawned(); + } + + void EnterCombat(Unit* who) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (who->GetEntry() == NPC_OUTRUNNER && !m_bIsByOutrunner) + { + if (Creature* talker = who->ToCreature()) + talker->AI()->Talk(SAY_RIN_BY_OUTRUNNER); + m_bIsByOutrunner = true; + } + + if (rand()%4) + return; + + //only if attacked and escorter is not in combat? + Talk(SAY_RIN_HELP); + } + } + + void DoSpawnAmbush(bool bFirst) + { + if (!bFirst) + m_iSpawnId = 1; + + me->SummonCreature(NPC_RANGER, + m_afAmbushSpawn[m_iSpawnId].m_fX, m_afAmbushSpawn[m_iSpawnId].m_fY, m_afAmbushSpawn[m_iSpawnId].m_fZ, 0.0f, + TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); + + for (int i = 0; i < 2; ++i) + { + me->SummonCreature(NPC_OUTRUNNER, + m_afAmbushSpawn[m_iSpawnId].m_fX, m_afAmbushSpawn[m_iSpawnId].m_fY, m_afAmbushSpawn[m_iSpawnId].m_fZ, 0.0f, + TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); + } + } + + void JustSummoned(Creature* summoned) + { + summoned->SetWalk(false); + summoned->GetMotionMaster()->MovePoint(0, m_afAmbushMoveTo[m_iSpawnId].m_fX, m_afAmbushMoveTo[m_iSpawnId].m_fY, m_afAmbushMoveTo[m_iSpawnId].m_fZ); + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 1: + Talk(SAY_RIN_FREE, player->GetGUID()); + break; + case 7: + DoSpawnAmbush(true); + break; + case 13: + DoSpawnAmbush(false); + break; + case 17: + Talk(SAY_RIN_COMPLETE, player->GetGUID()); + player->GroupEventHappens(QUEST_RINJI_TRAPPED, me); + SetRun(); + m_uiPostEventCount = 1; + break; + } + } + + void UpdateEscortAI(const uint32 uiDiff) + { + //Check if we have a current target + if (!UpdateVictim()) + { + if (HasEscortState(STATE_ESCORT_ESCORTING) && m_uiPostEventCount) + { + if (m_uiPostEventTimer <= uiDiff) + { + m_uiPostEventTimer = 3000; + + if (Player* player = GetPlayerForEscort()) + { + switch (m_uiPostEventCount) + { + case 1: + Talk(SAY_RIN_PROGRESS_1, player->GetGUID()); + ++m_uiPostEventCount; + break; + case 2: + Talk(SAY_RIN_PROGRESS_2, player->GetGUID()); + m_uiPostEventCount = 0; + break; + } + } + else + { + me->DespawnOrUnsummon(); + return; + } + } + else + m_uiPostEventTimer -= uiDiff; + } + + return; + } + + DoMeleeAttackIfReady(); + } + }; +}; + +void AddSC_hinterlands() +{ + new npc_00x09hl(); + new npc_rinji(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_ironforge.cpp b/src/server/scripts/EasternKingdoms/zone_ironforge.cpp new file mode 100644 index 00000000000..f9e8d4d16c6 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_ironforge.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Ironforge +SD%Complete: 100 +SDComment: Quest support: 3702 +SDCategory: Ironforge +EndScriptData */ + +/* ContentData +npc_royal_historian_archesonus +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npc_royal_historian_archesonus +######*/ + +#define GOSSIP_ITEM_ROYAL "I am ready to listen" +#define GOSSIP_ITEM_ROYAL_1 "That is tragic. How did this happen?" +#define GOSSIP_ITEM_ROYAL_2 "Interesting, continue please." +#define GOSSIP_ITEM_ROYAL_3 "Unbelievable! How dare they??" +#define GOSSIP_ITEM_ROYAL_4 "Of course I will help!" + +class npc_royal_historian_archesonus : public CreatureScript +{ +public: + npc_royal_historian_archesonus() : CreatureScript("npc_royal_historian_archesonus") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(2236, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(2237, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(2238, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(2239, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(3702); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(3702) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ROYAL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->SEND_GOSSIP_MENU(2235, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +void AddSC_ironforge() +{ + new npc_royal_historian_archesonus(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp new file mode 100644 index 00000000000..bfd4d24cec6 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Isle_of_Queldanas +SD%Complete: 100 +SDComment: Quest support: 11524, 11525, 11532, 11533, 11542, 11543, 11541 +SDCategory: Isle Of Quel'Danas +EndScriptData */ + +/* ContentData +npc_converted_sentry +npc_greengill_slave +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" +#include "Pet.h" +#include "SpellInfo.h" + +/*###### +## npc_converted_sentry +######*/ +enum ConvertedSentry +{ + SAY_CONVERTED = 0, + + SPELL_CONVERT_CREDIT = 45009 +}; + + +class npc_converted_sentry : public CreatureScript +{ +public: + npc_converted_sentry() : CreatureScript("npc_converted_sentry") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_converted_sentryAI (creature); + } + + struct npc_converted_sentryAI : public ScriptedAI + { + npc_converted_sentryAI(Creature* creature) : ScriptedAI(creature) {} + + bool Credit; + uint32 Timer; + + void Reset() + { + Credit = false; + Timer = 2500; + } + + void MoveInLineOfSight(Unit* /*who*/) {} + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (!Credit) + { + if (Timer <= diff) + { + Talk(SAY_CONVERTED); + + DoCast(me, SPELL_CONVERT_CREDIT); + if (me->isPet()) + me->ToPet()->SetDuration(7500); + Credit = true; + } else Timer -= diff; + } + } + }; +}; + +/*###### +## npc_greengill_slave +######*/ + +#define ENRAGE 45111 +#define ORB 45109 +#define QUESTG 11541 +#define DM 25060 + +class npc_greengill_slave : public CreatureScript +{ +public: + npc_greengill_slave() : CreatureScript("npc_greengill_slave") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_greengill_slaveAI(creature); + } + + struct npc_greengill_slaveAI : public ScriptedAI + { + npc_greengill_slaveAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + + void EnterCombat(Unit* /*who*/){} + + void Reset() + { + PlayerGUID = 0; + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (!caster) + return; + + if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == ORB && !me->HasAura(ENRAGE)) + { + PlayerGUID = caster->GetGUID(); + if (PlayerGUID) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->GetQuestStatus(QUESTG) == QUEST_STATUS_INCOMPLETE) + DoCast(player, 45110, true); + } + DoCast(me, ENRAGE); + Unit* Myrmidon = me->FindNearestCreature(DM, 70); + if (Myrmidon) + { + me->AddThreat(Myrmidon, 100000.0f); + AttackStart(Myrmidon); + } + } + } + + void UpdateAI(const uint32 /*diff*/) + { + DoMeleeAttackIfReady(); + } + }; +}; + +void AddSC_isle_of_queldanas() +{ + new npc_converted_sentry(); + new npc_greengill_slave(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp new file mode 100644 index 00000000000..30f12718d64 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Loch_Modan +SD%Complete: 100 +SDComment: Quest support: 3181 +SDCategory: Loch Modan +EndScriptData */ + +/* ContentData +npc_mountaineer_pebblebitty +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npc_mountaineer_pebblebitty +######*/ + +#define GOSSIP_MP "Open the gate please, i need to get to Searing Gorge" + +#define GOSSIP_MP1 "But i need to get there, now open the gate!" +#define GOSSIP_MP2 "Ok, so what is this other way?" +#define GOSSIP_MP3 "Doesn't matter, i'm invulnerable." +#define GOSSIP_MP4 "Yes..." +#define GOSSIP_MP5 "Ok, i'll try to remember that." +#define GOSSIP_MP6 "A key? Ok!" + +class npc_mountaineer_pebblebitty : public CreatureScript +{ +public: + npc_mountaineer_pebblebitty() : CreatureScript("npc_mountaineer_pebblebitty") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(1833, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(1834, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(1835, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + player->SEND_GOSSIP_MENU(1836, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + player->SEND_GOSSIP_MENU(1837, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); + player->SEND_GOSSIP_MENU(1838, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->CLOSE_GOSSIP_MENU(); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (!player->GetQuestRewardStatus(3181) == 1) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +void AddSC_loch_modan() +{ + new npc_mountaineer_pebblebitty(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp new file mode 100644 index 00000000000..5ff95f83f25 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* Script Data Start +SDName: Redridge Mountains +SD%Complete: 100% +SDComment: Support for quest 219. +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +enum eCorporalKeeshan +{ + QUEST_MISSING_IN_ACTION = 219, + + SAY_CORPORAL_1 = 0, + SAY_CORPORAL_2 = 1, + SAY_CORPORAL_3 = 2, + SAY_CORPORAL_4 = 3, + SAY_CORPORAL_5 = 4, + + SPELL_MOCKING_BLOW = 21008, + SPELL_SHIELD_BASH = 11972, +}; + +class npc_corporal_keeshan : public CreatureScript +{ +public: + npc_corporal_keeshan() : CreatureScript("npc_corporal_keeshan") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_MISSING_IN_ACTION) + { + CAST_AI(npc_corporal_keeshan::npc_corporal_keeshanAI, creature->AI())->Start(true, false, player->GetGUID(), quest); + creature->AI()->Talk(SAY_CORPORAL_1); + } + + return false; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_corporal_keeshanAI(creature); + } + + struct npc_corporal_keeshanAI : public npc_escortAI + { + npc_corporal_keeshanAI(Creature* creature) : npc_escortAI(creature) {} + + uint32 uiPhase; + uint32 uiTimer; + uint32 uiMockingBlowTimer; + uint32 uiShieldBashTimer; + + void Reset() + { + uiTimer = 0; + uiPhase = 0; + uiMockingBlowTimer = 5000; + uiShieldBashTimer = 8000; + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + if (waypointId >= 65 && me->GetUnitMovementFlags() == MOVEMENTFLAG_WALKING) + me->SetWalk(false); + + switch (waypointId) + { + case 39: + SetEscortPaused(true); + uiTimer = 2000; + uiPhase = 1; + break; + case 65: + me->SetWalk(false); + break; + case 115: + player->AreaExploredOrEventHappens(QUEST_MISSING_IN_ACTION); + uiTimer = 2000; + uiPhase = 4; + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (HasEscortState(STATE_ESCORT_NONE)) + return; + + npc_escortAI::UpdateAI(uiDiff); + + if (uiPhase) + { + if (uiTimer <= uiDiff) + { + switch (uiPhase) + { + case 1: + me->SetStandState(UNIT_STAND_STATE_SIT); + uiTimer = 1000; + uiPhase = 2; + break; + case 2: + Talk(SAY_CORPORAL_2); + uiTimer = 15000; + uiPhase = 3; + break; + case 3: + Talk(SAY_CORPORAL_3); + me->SetStandState(UNIT_STAND_STATE_STAND); + SetEscortPaused(false); + uiTimer = 0; + uiPhase = 0; + break; + case 4: + Talk(SAY_CORPORAL_4); + uiTimer = 2500; + uiPhase = 5; + case 5: + Talk(SAY_CORPORAL_5); + uiTimer = 0; + uiPhase = 0; + } + } else uiTimer -= uiDiff; + } + + if (!UpdateVictim()) + return; + + if (uiMockingBlowTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_MOCKING_BLOW); + uiMockingBlowTimer = 5000; + } else uiMockingBlowTimer -= uiDiff; + + if (uiShieldBashTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_MOCKING_BLOW); + uiShieldBashTimer = 8000; + } else uiShieldBashTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + }; +}; + +void AddSC_redridge_mountains() +{ + new npc_corporal_keeshan(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_silvermoon_city.cpp b/src/server/scripts/EasternKingdoms/zone_silvermoon_city.cpp new file mode 100644 index 00000000000..e750faefbf5 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_silvermoon_city.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Silvermoon_City +SD%Complete: 100 +SDComment: Quest support: 9685 +SDCategory: Silvermoon City +EndScriptData */ + +/* ContentData +npc_blood_knight_stillblade +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" +#include "SpellInfo.h" + +/*####### +# npc_blood_knight_stillblade +#######*/ +enum eStillbladeData +{ + SAY_HEAL = 0, + + QUEST_REDEEMING_THE_DEAD = 9685, + SPELL_SHIMMERING_VESSEL = 31225, + SPELL_REVIVE_SELF = 32343, +}; + +class npc_blood_knight_stillblade : public CreatureScript +{ +public: + npc_blood_knight_stillblade() : CreatureScript("npc_blood_knight_stillblade") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_blood_knight_stillbladeAI (creature); + } + + struct npc_blood_knight_stillbladeAI : public ScriptedAI + { + npc_blood_knight_stillbladeAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 lifeTimer; + bool spellHit; + + void Reset() + { + lifeTimer = 120000; + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 7); // lay down + spellHit = false; + } + + void EnterCombat(Unit* /*who*/) + { + } + + void MoveInLineOfSight(Unit* /*who*/) + { + } + + void UpdateAI(const uint32 diff) + { + if (me->IsStandState()) + { + if (lifeTimer <= diff) + me->AI()->EnterEvadeMode(); + else + lifeTimer -= diff; + } + } + + void SpellHit(Unit* Hitter, const SpellInfo* Spellkind) + { + if ((Spellkind->Id == SPELL_SHIMMERING_VESSEL) && !spellHit && + (Hitter->GetTypeId() == TYPEID_PLAYER) && (CAST_PLR(Hitter)->IsActiveQuest(QUEST_REDEEMING_THE_DEAD))) + { + CAST_PLR(Hitter)->AreaExploredOrEventHappens(QUEST_REDEEMING_THE_DEAD); + DoCast(me, SPELL_REVIVE_SELF); + me->SetStandState(UNIT_STAND_STATE_STAND); + me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); + //me->RemoveAllAuras(); + Talk(SAY_HEAL); + spellHit = true; + } + } + }; +}; + +void AddSC_silvermoon_city() +{ + new npc_blood_knight_stillblade(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp new file mode 100644 index 00000000000..290f7fa6882 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp @@ -0,0 +1,327 @@ + /* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Silverpine_Forest +SD%Complete: 100 +SDComment: Quest support: 435, 452 +SDCategory: Silverpine Forest +EndScriptData */ + +/* ContentData +npc_deathstalker_erland +pyrewood_ambush +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_deathstalker_erland +######*/ + +enum eErland +{ + SAY_QUESTACCEPT = 0, + SAY_START = 1, + SAY_AGGRO = 2, + SAY_PROGRESS = 3, + SAY_LAST = 4, + + SAY_RANE = 0, + SAY_RANE_ANSWER = 5, + SAY_MOVE_QUINN = 6, + + SAY_QUINN = 7, + SAY_QUINN_ANSWER = 0, + SAY_BYE = 8, + + QUEST_ESCORTING = 435, + NPC_RANE = 1950, + NPC_QUINN = 1951 +}; + +class npc_deathstalker_erland : public CreatureScript +{ +public: + npc_deathstalker_erland() : CreatureScript("npc_deathstalker_erland") { } + + struct npc_deathstalker_erlandAI : public npc_escortAI + { + npc_deathstalker_erlandAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 1: + Talk(SAY_START, player->GetGUID()); + break; + case 10: + Talk(SAY_PROGRESS); + break; + case 13: + Talk(SAY_LAST, player->GetGUID()); + player->GroupEventHappens(QUEST_ESCORTING, me); + break; + case 15: + if (Creature* rane = me->FindNearestCreature(NPC_RANE, 20.0f)) + rane->AI()->Talk(SAY_RANE); + break; + case 16: + Talk(SAY_RANE_ANSWER); + break; + case 17: + Talk(SAY_MOVE_QUINN); + break; + case 24: + Talk(SAY_QUINN); + break; + case 25: + if (Creature* quinn = me->FindNearestCreature(NPC_QUINN, 20.0f)) + quinn->AI()->Talk(SAY_QUINN_ANSWER); + break; + case 26: + Talk(SAY_BYE); + break; + } + } + + void Reset() {} + + void EnterCombat(Unit* who) + { + Talk(SAY_AGGRO, who->GetGUID()); + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCORTING) + { + creature->AI()->Talk(SAY_QUESTACCEPT, player->GetGUID()); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_deathstalker_erland::npc_deathstalker_erlandAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_deathstalker_erlandAI(creature); + } +}; + +/*###### +## pyrewood_ambush +#######*/ + +#define QUEST_PYREWOOD_AMBUSH 452 + +#define NPCSAY_INIT "Get ready, they'll be arriving any minute..." //not blizzlike +#define NPCSAY_END "Thanks for your help!" //not blizzlike + +static float PyrewoodSpawnPoints[3][4] = +{ + //pos_x pos_y pos_z orien + //outside + /* + {-400.85f, 1513.64f, 18.67f, 0}, + {-397.32f, 1514.12f, 18.67f, 0}, + {-397.44f, 1511.09f, 18.67f, 0}, + */ + //door + {-396.17f, 1505.86f, 19.77f, 0}, + {-396.91f, 1505.77f, 19.77f, 0}, + {-397.94f, 1504.74f, 19.77f, 0}, +}; + +#define WAIT_SECS 6000 + +class pyrewood_ambush : public CreatureScript +{ +public: + pyrewood_ambush() : CreatureScript("pyrewood_ambush") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest *quest) + { + if (quest->GetQuestId() == QUEST_PYREWOOD_AMBUSH && !CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress) + { + CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress = true; + CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->Phase = 0; + CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->KillCount = 0; + CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->PlayerGUID = player->GetGUID(); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new pyrewood_ambushAI (creature); + } + + struct pyrewood_ambushAI : public ScriptedAI + { + pyrewood_ambushAI(Creature* creature) : ScriptedAI(creature), Summons(me) + { + QuestInProgress = false; + } + + uint32 Phase; + int8 KillCount; + uint32 WaitTimer; + uint64 PlayerGUID; + SummonList Summons; + + bool QuestInProgress; + + void Reset() + { + WaitTimer = WAIT_SECS; + + if (!QuestInProgress) //fix reset values (see UpdateVictim) + { + Phase = 0; + KillCount = 0; + PlayerGUID = 0; + Summons.DespawnAll(); + } + } + + void EnterCombat(Unit* /*who*/){} + + void JustSummoned(Creature* summoned) + { + Summons.Summon(summoned); + ++KillCount; + } + + void SummonedCreatureDespawn(Creature* summoned) + { + Summons.Despawn(summoned); + --KillCount; + } + + void SummonCreatureWithRandomTarget(uint32 creatureId, int position) + { + if (Creature* summoned = me->SummonCreature(creatureId, PyrewoodSpawnPoints[position][0], PyrewoodSpawnPoints[position][1], PyrewoodSpawnPoints[position][2], PyrewoodSpawnPoints[position][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000)) + { + Unit* target = NULL; + if (PlayerGUID) + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + if (player->isAlive() && RAND(0, 1)) + target = player; + + if (!target) + target = me; + + summoned->setFaction(168); + summoned->AddThreat(target, 32.0f); + summoned->AI()->AttackStart(target); + } + } + + void JustDied(Unit* /*killer*/) + { + if (PlayerGUID) + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + if (player->GetQuestStatus(QUEST_PYREWOOD_AMBUSH) == QUEST_STATUS_INCOMPLETE) + player->FailQuest(QUEST_PYREWOOD_AMBUSH); + } + + void UpdateAI(const uint32 diff) + { + //sLog->outInfo(LOG_FILTER_TSCR, "DEBUG: p(%i) k(%i) d(%u) W(%i)", Phase, KillCount, diff, WaitTimer); + + if (!QuestInProgress) + return; + + if (KillCount && Phase < 6) + { + if (!UpdateVictim()) //reset() on target Despawn... + return; + + DoMeleeAttackIfReady(); + return; + } + + switch (Phase) + { + case 0: + if (WaitTimer == WAIT_SECS) + me->MonsterSay(NPCSAY_INIT, LANG_UNIVERSAL, 0); //no blizzlike + + if (WaitTimer <= diff) + { + WaitTimer -= diff; + return; + } + break; + case 1: + SummonCreatureWithRandomTarget(2060, 1); + break; + case 2: + SummonCreatureWithRandomTarget(2061, 2); + SummonCreatureWithRandomTarget(2062, 0); + break; + case 3: + SummonCreatureWithRandomTarget(2063, 1); + SummonCreatureWithRandomTarget(2064, 2); + SummonCreatureWithRandomTarget(2065, 0); + break; + case 4: + SummonCreatureWithRandomTarget(2066, 1); + SummonCreatureWithRandomTarget(2067, 0); + SummonCreatureWithRandomTarget(2068, 2); + break; + case 5: //end + if (PlayerGUID) + { + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + { + me->MonsterSay(NPCSAY_END, LANG_UNIVERSAL, 0); //not blizzlike + player->GroupEventHappens(QUEST_PYREWOOD_AMBUSH, me); + } + } + QuestInProgress = false; + Reset(); + break; + } + ++Phase; //prepare next phase + } + }; +}; + +/*###### +## AddSC +######*/ + +void AddSC_silverpine_forest() +{ + new npc_deathstalker_erland(); + new pyrewood_ambush(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp new file mode 100644 index 00000000000..e81567a1a7a --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp @@ -0,0 +1,647 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Stormwind_City +SD%Complete: 100 +SDComment: Quest support: 1640, 1447, 4185, 11223, 434. +SDCategory: Stormwind City +EndScriptData */ + +/* ContentData +npc_archmage_malin +npc_bartleby +npc_lady_katrana_prestor +npc_tyrion +npc_tyrion_spybot +npc_marzon_silent_blade +npc_lord_gregor_lescovar +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_archmage_malin +######*/ + +#define GOSSIP_ITEM_MALIN "Can you send me to Theramore? I have an urgent message for Lady Jaina from Highlord Bolvar." + +class npc_archmage_malin : public CreatureScript +{ +public: + npc_archmage_malin() : CreatureScript("npc_archmage_malin") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, 42711, true); + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(11223) == QUEST_STATUS_COMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MALIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_bartleby +######*/ + +enum eBartleby +{ + FACTION_ENEMY = 168, + QUEST_BEAT = 1640 +}; + +class npc_bartleby : public CreatureScript +{ +public: + npc_bartleby() : CreatureScript("npc_bartleby") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_BEAT) + { + creature->setFaction(FACTION_ENEMY); + creature->AI()->AttackStart(player); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_bartlebyAI(creature); + } + + struct npc_bartlebyAI : public ScriptedAI + { + npc_bartlebyAI(Creature* creature) : ScriptedAI(creature) + { + m_uiNormalFaction = creature->getFaction(); + } + + uint32 m_uiNormalFaction; + + void Reset() + { + if (me->getFaction() != m_uiNormalFaction) + me->setFaction(m_uiNormalFaction); + } + + void AttackedBy(Unit* pAttacker) + { + if (me->getVictim()) + return; + + if (me->IsFriendlyTo(pAttacker)) + return; + + AttackStart(pAttacker); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) + { + //Take 0 damage + uiDamage = 0; + + if (pDoneBy->GetTypeId() == TYPEID_PLAYER) + CAST_PLR(pDoneBy)->AreaExploredOrEventHappens(QUEST_BEAT); + EnterEvadeMode(); + } + } + }; +}; + +/*###### +## npc_lady_katrana_prestor +######*/ + +#define GOSSIP_ITEM_KAT_1 "Pardon the intrusion, Lady Prestor, but Highlord Bolvar suggested that I seek your advice." +#define GOSSIP_ITEM_KAT_2 "My apologies, Lady Prestor." +#define GOSSIP_ITEM_KAT_3 "Begging your pardon, Lady Prestor. That was not my intent." +#define GOSSIP_ITEM_KAT_4 "Thank you for your time, Lady Prestor." + +class npc_lady_katrana_prestor : public CreatureScript +{ +public: + npc_lady_katrana_prestor() : CreatureScript("npc_lady_katrana_prestor") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(2694, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(2695, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(2696, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(4185); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(4185) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(2693, creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_lord_gregor_lescovar +######*/ + +enum eLordGregorLescovar +{ + SAY_GUARD_2 = 0, + SAY_LESCOVAR_2 = 0, + SAY_LESCOVAR_3 = 1, + SAY_LESCOVAR_4 = 2, + SAY_MARZON_1 = 0, + SAY_MARZON_2 = 1, + SAY_TYRION_2 = 1, + + NPC_STORMWIND_ROYAL = 1756, + NPC_MARZON_BLADE = 1755, + NPC_TYRION = 7766, + + QUEST_THE_ATTACK = 434 +}; + +class npc_lord_gregor_lescovar : public CreatureScript +{ +public: + npc_lord_gregor_lescovar() : CreatureScript("npc_lord_gregor_lescovar") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lord_gregor_lescovarAI(creature); + } + + struct npc_lord_gregor_lescovarAI : public npc_escortAI + { + npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) + { + creature->RestoreFaction(); + } + + uint32 uiTimer; + uint32 uiPhase; + + uint64 MarzonGUID; + + void Reset() + { + uiTimer = 0; + uiPhase = 0; + + MarzonGUID = 0; + } + + void EnterEvadeMode() + { + me->DisappearAndDie(); + + if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) + { + if (pMarzon->isAlive()) + pMarzon->DisappearAndDie(); + } + } + + void EnterCombat(Unit* who) + { + if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) + { + if (pMarzon->isAlive() && !pMarzon->isInCombat()) + pMarzon->AI()->AttackStart(who); + } + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 14: + SetEscortPaused(true); + Talk(SAY_LESCOVAR_2); + uiTimer = 3000; + uiPhase = 1; + break; + case 16: + SetEscortPaused(true); + if (Creature* pMarzon = me->SummonCreature(NPC_MARZON_BLADE, -8411.360352f, 480.069733f, 123.760895f, 4.941504f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) + { + pMarzon->GetMotionMaster()->MovePoint(0, -8408.000977f, 468.611450f, 123.759903f); + MarzonGUID = pMarzon->GetGUID(); + } + uiTimer = 2000; + uiPhase = 4; + break; + } + } + //TO-DO: We don't have movemaps, also we can't make 2 npcs walks to one point propperly (and we can not use escort ai, because they are 2 different spawns and with same entry), because of it we make them, disappear. + void DoGuardsDisappearAndDie() + { + std::list GuardList; + me->GetCreatureListWithEntryInGrid(GuardList, NPC_STORMWIND_ROYAL, 8.0f); + if (!GuardList.empty()) + { + for (std::list::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr) + { + if (Creature* pGuard = *itr) + pGuard->DisappearAndDie(); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (uiPhase) + { + if (uiTimer <= uiDiff) + { + switch (uiPhase) + { + case 1: + if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 8.0f, true)) + pGuard->AI()->Talk(SAY_GUARD_2); + uiTimer = 3000; + uiPhase = 2; + break; + case 2: + DoGuardsDisappearAndDie(); + uiTimer = 2000; + uiPhase = 3; + break; + case 3: + SetEscortPaused(false); + uiTimer = 0; + uiPhase = 0; + break; + case 4: + Talk(SAY_LESCOVAR_3); + uiTimer = 0; + uiPhase = 0; + break; + case 5: + if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) + pMarzon->AI()->Talk(SAY_MARZON_1); + uiTimer = 3000; + uiPhase = 6; + break; + case 6: + Talk(SAY_LESCOVAR_4); + if (Player* player = GetPlayerForEscort()) + player->AreaExploredOrEventHappens(QUEST_THE_ATTACK); + uiTimer = 2000; + uiPhase = 7; + break; + case 7: + if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 20.0f, true)) + pTyrion->AI()->Talk(SAY_TYRION_2); + if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID)) + pMarzon->setFaction(14); + me->setFaction(14); + uiTimer = 0; + uiPhase = 0; + break; + } + } else uiTimer -= uiDiff; + } + npc_escortAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_marzon_silent_blade +######*/ + +class npc_marzon_silent_blade : public CreatureScript +{ +public: + npc_marzon_silent_blade() : CreatureScript("npc_marzon_silent_blade") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_marzon_silent_bladeAI(creature); + } + + struct npc_marzon_silent_bladeAI : public ScriptedAI + { + npc_marzon_silent_bladeAI(Creature* creature) : ScriptedAI(creature) + { + me->SetWalk(true); + } + + void Reset() + { + me->RestoreFaction(); + } + + void EnterCombat(Unit* who) + { + Talk(SAY_MARZON_2); + + if (me->isSummon()) + { + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + { + if (summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive() && !summoner->isInCombat()) + summoner->ToCreature()->AI()->AttackStart(who); + } + } + } + + void EnterEvadeMode() + { + me->DisappearAndDie(); + + if (me->isSummon()) + { + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + { + if (summoner->GetTypeId() == TYPEID_UNIT && summoner->isAlive()) + summoner->ToCreature()->DisappearAndDie(); + } + } + } + + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + + if (me->isSummon()) + { + Unit* summoner = me->ToTempSummon()->GetSummoner(); + if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAIEnabled) + { + npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI* ai = + CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, summoner->GetAI()); + if (ai) + { + ai->uiTimer = 2000; + ai->uiPhase = 5; + } + //me->ChangeOrient(0.0f, summoner); + } + } + } + + void UpdateAI(const uint32 /*diff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_tyrion_spybot +######*/ + +enum eTyrionSpybot +{ + SAY_QUEST_ACCEPT_ATTACK = 0, + SAY_SPYBOT_1 = 1, + SAY_SPYBOT_2 = 2, + SAY_SPYBOT_3 = 3, + SAY_SPYBOT_4 = 4, + SAY_TYRION_1 = 0, + SAY_GUARD_1 = 1, + SAY_LESCOVAR_1 = 3, + + NPC_PRIESTESS_TYRIONA = 7779, + NPC_LORD_GREGOR_LESCOVAR = 1754, +}; + +class npc_tyrion_spybot : public CreatureScript +{ +public: + npc_tyrion_spybot() : CreatureScript("npc_tyrion_spybot") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tyrion_spybotAI(creature); + } + + struct npc_tyrion_spybotAI : public npc_escortAI + { + npc_tyrion_spybotAI(Creature* creature) : npc_escortAI(creature) {} + + uint32 uiTimer; + uint32 uiPhase; + + void Reset() + { + uiTimer = 0; + uiPhase = 0; + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 1: + SetEscortPaused(true); + uiTimer = 2000; + uiPhase = 1; + break; + case 5: + SetEscortPaused(true); + Talk(SAY_SPYBOT_1); + uiTimer = 2000; + uiPhase = 5; + break; + case 17: + SetEscortPaused(true); + Talk(SAY_SPYBOT_3); + uiTimer = 3000; + uiPhase = 8; + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (uiPhase) + { + if (uiTimer <= uiDiff) + { + switch (uiPhase) + { + case 1: + Talk(SAY_QUEST_ACCEPT_ATTACK); + uiTimer = 3000; + uiPhase = 2; + break; + case 2: + if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 10.0f)) + pTyrion->AI()->Talk(SAY_TYRION_1); + uiTimer = 3000; + uiPhase = 3; + break; + case 3: + me->UpdateEntry(NPC_PRIESTESS_TYRIONA, ALLIANCE); + uiTimer = 2000; + uiPhase = 4; + break; + case 4: + SetEscortPaused(false); + uiPhase = 0; + uiTimer = 0; + break; + case 5: + if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 10.0f, true)) + pGuard->AI()->Talk(SAY_GUARD_1); + uiTimer = 3000; + uiPhase = 6; + break; + case 6: + Talk(SAY_SPYBOT_2); + uiTimer = 3000; + uiPhase = 7; + break; + case 7: + SetEscortPaused(false); + uiTimer = 0; + uiPhase = 0; + break; + case 8: + if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f)) + pLescovar->AI()->Talk(SAY_LESCOVAR_1); + uiTimer = 3000; + uiPhase = 9; + break; + case 9: + Talk(SAY_SPYBOT_4); + uiTimer = 3000; + uiPhase = 10; + break; + case 10: + if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f)) + { + if (Player* player = GetPlayerForEscort()) + { + CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->Start(false, false, player->GetGUID()); + CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->SetMaxPlayerDistance(200.0f); + } + } + me->DisappearAndDie(); + uiTimer = 0; + uiPhase = 0; + break; + } + } else uiTimer -= uiDiff; + } + npc_escortAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_tyrion +######*/ + +enum eTyrion +{ + NPC_TYRION_SPYBOT = 8856 +}; + +class npc_tyrion : public CreatureScript +{ +public: + npc_tyrion() : CreatureScript("npc_tyrion") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_THE_ATTACK) + { + if (Creature* pSpybot = creature->FindNearestCreature(NPC_TYRION_SPYBOT, 5.0f, true)) + { + CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->Start(false, false, player->GetGUID()); + CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->SetMaxPlayerDistance(200.0f); + } + return true; + } + return false; + } +}; + +void AddSC_stormwind_city() +{ + new npc_archmage_malin(); + new npc_bartleby(); + new npc_lady_katrana_prestor(); + new npc_tyrion(); + new npc_tyrion_spybot(); + new npc_lord_gregor_lescovar(); + new npc_marzon_silent_blade(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp new file mode 100644 index 00000000000..6e14ef840a3 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Stranglethorn_Vale +SD%Complete: 100 +SDComment: Quest support: 592 +SDCategory: Stranglethorn Vale +EndScriptData */ + +/* ContentData +mob_yenniku +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" +#include "SpellInfo.h" + +/*###### +## mob_yenniku +######*/ + +class mob_yenniku : public CreatureScript +{ +public: + mob_yenniku() : CreatureScript("mob_yenniku") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_yennikuAI (creature); + } + + struct mob_yennikuAI : public ScriptedAI + { + mob_yennikuAI(Creature* creature) : ScriptedAI(creature) + { + bReset = false; + } + + uint32 Reset_Timer; + bool bReset; + + void Reset() + { + Reset_Timer = 0; + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (caster->GetTypeId() == TYPEID_PLAYER) + { + //Yenniku's Release + if (!bReset && CAST_PLR(caster)->GetQuestStatus(592) == QUEST_STATUS_INCOMPLETE && spell->Id == 3607) + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN); + me->CombatStop(); //stop combat + me->DeleteThreatList(); //unsure of this + me->setFaction(83); //horde generic + + bReset = true; + Reset_Timer = 60000; + } + } + return; + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (bReset) + { + if (Reset_Timer <= diff) + { + EnterEvadeMode(); + bReset = false; + me->setFaction(28); //troll, bloodscalp + return; + } + else Reset_Timer -= diff; + + if (me->isInCombat() && me->getVictim()) + { + if (me->getVictim()->GetTypeId() == TYPEID_PLAYER) + { + Unit* victim = me->getVictim(); + if (CAST_PLR(victim)->GetTeam() == HORDE) + { + me->CombatStop(); + me->DeleteThreatList(); + } + } + } + } + + //Return since we have no target + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## +######*/ + +void AddSC_stranglethorn_vale() +{ + new mob_yenniku(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp new file mode 100644 index 00000000000..f686de5d88f --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_galen_goodward +######*/ + +enum Galen +{ + QUEST_GALENS_ESCAPE = 1393, + + GO_GALENS_CAGE = 37118, + + SAY_PERIODIC = 0, + SAY_QUEST_ACCEPTED = 1, + SAY_ATTACKED = 2, + SAY_QUEST_COMPLETE = 3, + EMOTE_WHISPER = 4, + EMOTE_DISAPPEAR = 5, +}; + +class npc_galen_goodward : public CreatureScript +{ +public: + + npc_galen_goodward() : CreatureScript("npc_galen_goodward") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_GALENS_ESCAPE) + { + CAST_AI(npc_galen_goodward::npc_galen_goodwardAI, creature->AI())->Start(false, false, player->GetGUID()); + creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE); + creature->AI()->Talk(SAY_QUEST_ACCEPTED); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_galen_goodwardAI(creature); + } + + struct npc_galen_goodwardAI : public npc_escortAI + { + npc_galen_goodwardAI(Creature* creature) : npc_escortAI(creature) + { + m_uiGalensCageGUID = 0; + Reset(); + } + + uint64 m_uiGalensCageGUID; + uint32 m_uiPeriodicSay; + + void Reset() + { + m_uiPeriodicSay = 6000; + } + + void EnterCombat(Unit* who) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + Talk(SAY_ATTACKED, who->GetGUID()); + } + + void WaypointStart(uint32 uiPointId) + { + switch (uiPointId) + { + case 0: + { + GameObject* pCage = NULL; + if (m_uiGalensCageGUID) + pCage = me->GetMap()->GetGameObject(m_uiGalensCageGUID); + else + pCage = GetClosestGameObjectWithEntry(me, GO_GALENS_CAGE, INTERACTION_DISTANCE); + if (pCage) + { + pCage->UseDoorOrButton(); + m_uiGalensCageGUID = pCage->GetGUID(); + } + break; + } + case 21: + Talk(EMOTE_DISAPPEAR); + break; + } + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 0: + if (GameObject* pCage = me->GetMap()->GetGameObject(m_uiGalensCageGUID)) + pCage->ResetDoorOrButton(); + break; + case 20: + if (Player* player = GetPlayerForEscort()) + { + me->SetFacingToObject(player); + Talk(SAY_QUEST_COMPLETE, player->GetGUID()); + Talk(EMOTE_WHISPER, player->GetGUID()); + player->GroupEventHappens(QUEST_GALENS_ESCAPE, me); + } + SetRun(true); + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (HasEscortState(STATE_ESCORT_NONE)) + return; + + if (m_uiPeriodicSay < uiDiff) + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + Talk(SAY_PERIODIC); + m_uiPeriodicSay = 15000; + } + else + m_uiPeriodicSay -= uiDiff; + + DoMeleeAttackIfReady(); + } + }; +}; + +void AddSC_swamp_of_sorrows() +{ + new npc_galen_goodward(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp new file mode 100644 index 00000000000..f36220dec0f --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Tirisfal_Glades +SD%Complete: 100 +SDComment: Quest support: 590, 1819 +SDCategory: Tirisfal Glades +EndScriptData */ + +/* ContentData +npc_calvin_montague +go_mausoleum_door +go_mausoleum_trigger +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" + +/*###### +## npc_calvin_montague +######*/ + +enum Calvin +{ + SAY_COMPLETE = 0, + SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct) + QUEST_590 = 590, + FACTION_HOSTILE = 168 +}; + +class npc_calvin_montague : public CreatureScript +{ +public: + npc_calvin_montague() : CreatureScript("npc_calvin_montague") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_590) + { + creature->setFaction(FACTION_HOSTILE); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + CAST_AI(npc_calvin_montague::npc_calvin_montagueAI, creature->AI())->AttackStart(player); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_calvin_montagueAI (creature); + } + + struct npc_calvin_montagueAI : public ScriptedAI + { + npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) { } + + uint32 m_uiPhase; + uint32 m_uiPhaseTimer; + uint64 m_uiPlayerGUID; + + void Reset() + { + m_uiPhase = 0; + m_uiPhaseTimer = 5000; + m_uiPlayerGUID = 0; + + me->RestoreFaction(); + + if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)) + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + } + + void EnterCombat(Unit* /*who*/) {} + + void AttackedBy(Unit* pAttacker) + { + if (me->getVictim() || me->IsFriendlyTo(pAttacker)) + return; + + AttackStart(pAttacker); + } + + void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) + { + if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage)) + { + uiDamage = 0; + + me->RestoreFaction(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->CombatStop(true); + + m_uiPhase = 1; + + if (pDoneBy->GetTypeId() == TYPEID_PLAYER) + m_uiPlayerGUID = pDoneBy->GetGUID(); + } + } + + void UpdateAI(uint32 const diff) + { + if (m_uiPhase) + { + if (m_uiPhaseTimer <= diff) + m_uiPhaseTimer = 7500; + else + { + m_uiPhaseTimer -= diff; + return; + } + + switch (m_uiPhase) + { + case 1: + Talk(SAY_COMPLETE); + ++m_uiPhase; + break; + case 2: + if (Player* player = Unit::GetPlayer(*me, m_uiPlayerGUID)) + player->AreaExploredOrEventHappens(QUEST_590); + + DoCast(me, SPELL_DRINK, true); + ++m_uiPhase; + break; + case 3: + EnterEvadeMode(); + break; + } + + return; + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## go_mausoleum_door +## go_mausoleum_trigger +######*/ + +enum eMausoleum +{ + QUEST_ULAG = 1819, + NPC_ULAG = 6390, + GO_TRIGGER = 104593, + GO_DOOR = 176594 +}; + +class go_mausoleum_door : public GameObjectScript +{ +public: + go_mausoleum_door() : GameObjectScript("go_mausoleum_door") { } + + bool OnGossipHello(Player* player, GameObject* /*go*/) + { + if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) + return false; + + if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f)) + { + pTrigger->SetGoState(GO_STATE_READY); + player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); + return false; + } + + return false; + } +}; + +class go_mausoleum_trigger : public GameObjectScript +{ +public: + go_mausoleum_trigger() : GameObjectScript("go_mausoleum_trigger") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE) + return false; + + if (GameObject* pDoor = player->FindNearestGameObject(GO_DOOR, 30.0f)) + { + go->SetGoState(GO_STATE_ACTIVE); + pDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); + return true; + } + + return false; + } +}; + +void AddSC_tirisfal_glades() +{ + new npc_calvin_montague(); + new go_mausoleum_door(); + new go_mausoleum_trigger(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp new file mode 100644 index 00000000000..2c3017a2f1a --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Undercity +SD%Complete: 95 +SDComment: Quest support: 6628, 9180(post-event). +SDCategory: Undercity +EndScriptData */ + +/* ContentData +npc_lady_sylvanas_windrunner +npc_highborne_lamenter +npc_parqual_fintallas +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npc_lady_sylvanas_windrunner +######*/ + +enum Sylvanas +{ + QUEST_JOURNEY_TO_UNDERCITY = 9180, + EMOTE_LAMENT_END = 0, + SAY_LAMENT_END = 1, + + SOUND_CREDIT = 10896, + ENTRY_HIGHBORNE_LAMENTER = 21628, + ENTRY_HIGHBORNE_BUNNY = 21641, + + SPELL_HIGHBORNE_AURA = 37090, + SPELL_SYLVANAS_CAST = 36568, + SPELL_RIBBON_OF_SOULS = 34432, // the real one to use might be 37099 + + // Combat spells + SPELL_BLACK_ARROW = 59712, + SPELL_FADE = 20672, + SPELL_FADE_BLINK = 29211, + SPELL_MULTI_SHOT = 59713, + SPELL_SHOT = 59710, + SPELL_SUMMON_SKELETON = 59711 +}; + +float HighborneLoc[4][3]= +{ + {1285.41f, 312.47f, 0.51f}, + {1286.96f, 310.40f, 1.00f}, + {1289.66f, 309.66f, 1.52f}, + {1292.51f, 310.50f, 1.99f}, +}; + +#define HIGHBORNE_LOC_Y -61.00f +#define HIGHBORNE_LOC_Y_NEW -55.50f + +class npc_lady_sylvanas_windrunner : public CreatureScript +{ +public: + npc_lady_sylvanas_windrunner() : CreatureScript("npc_lady_sylvanas_windrunner") { } + + bool OnQuestReward(Player* /*player*/, Creature* creature, const Quest *_Quest, uint32 /*slot*/) + { + if (_Quest->GetQuestId() == QUEST_JOURNEY_TO_UNDERCITY) + { + CAST_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->LamentEvent = true; + CAST_AI(npc_lady_sylvanas_windrunner::npc_lady_sylvanas_windrunnerAI, creature->AI())->DoPlaySoundToSet(creature, SOUND_CREDIT); + creature->CastSpell(creature, SPELL_SYLVANAS_CAST, false); + + for (uint8 i = 0; i < 4; ++i) + creature->SummonCreature(ENTRY_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lady_sylvanas_windrunnerAI (creature); + } + + struct npc_lady_sylvanas_windrunnerAI : public ScriptedAI + { + npc_lady_sylvanas_windrunnerAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 LamentEventTimer; + bool LamentEvent; + uint64 targetGUID; + + uint32 FadeTimer; + uint32 SummonSkeletonTimer; + uint32 BlackArrowTimer; + uint32 ShotTimer; + uint32 MultiShotTimer; + + void Reset() + { + LamentEventTimer = 5000; + LamentEvent = false; + targetGUID = 0; + + FadeTimer = 30000; + SummonSkeletonTimer = 20000; + BlackArrowTimer = 15000; + ShotTimer = 8000; + MultiShotTimer = 10000; + } + + void EnterCombat(Unit* /*who*/) {} + + void JustSummoned(Creature* summoned) + { + if (summoned->GetEntry() == ENTRY_HIGHBORNE_BUNNY) + { + if (Creature* target = Unit::GetCreature(*summoned, targetGUID)) + { + target->MonsterMoveWithSpeed(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0); + target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f); + summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false); + } + + summoned->SetDisableGravity(true); + targetGUID = summoned->GetGUID(); + } + } + + void UpdateAI(const uint32 diff) + { + if (LamentEvent) + { + if (LamentEventTimer <= diff) + { + DoSummon(ENTRY_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN); + + LamentEventTimer = 2000; + if (!me->HasAura(SPELL_SYLVANAS_CAST)) + { + Talk(SAY_LAMENT_END); + Talk(EMOTE_LAMENT_END); + LamentEvent = false; + } + } else LamentEventTimer -= diff; + } + + if (!UpdateVictim()) + return; + + // Combat spells + + if (FadeTimer <= diff) + { + DoCast(me, SPELL_FADE); + // add a blink to simulate a stealthed movement and reappearing elsewhere + DoCast(me, SPELL_FADE_BLINK); + FadeTimer = 30000 + rand()%5000; + // if the victim is out of melee range she cast multi shot + if (Unit* victim = me->getVictim()) + if (me->GetDistance(victim) > 10.0f) + DoCast(victim, SPELL_MULTI_SHOT); + } else FadeTimer -= diff; + + if (SummonSkeletonTimer <= diff) + { + DoCast(me, SPELL_SUMMON_SKELETON); + SummonSkeletonTimer = 20000 + rand()%10000; + } else SummonSkeletonTimer -= diff; + + if (BlackArrowTimer <= diff) + { + if (Unit* victim = me->getVictim()) + { + DoCast(victim, SPELL_BLACK_ARROW); + BlackArrowTimer = 15000 + rand()%5000; + } + } else BlackArrowTimer -= diff; + + if (ShotTimer <= diff) + { + if (Unit* victim = me->getVictim()) + { + DoCast(victim, SPELL_SHOT); + ShotTimer = 8000 + rand()%2000; + } + } else ShotTimer -= diff; + + if (MultiShotTimer <= diff) + { + if (Unit* victim = me->getVictim()) + { + DoCast(victim, SPELL_MULTI_SHOT); + MultiShotTimer = 10000 + rand()%3000; + } + } else MultiShotTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_highborne_lamenter +######*/ + +class npc_highborne_lamenter : public CreatureScript +{ +public: + npc_highborne_lamenter() : CreatureScript("npc_highborne_lamenter") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_highborne_lamenterAI (creature); + } + + struct npc_highborne_lamenterAI : public ScriptedAI + { + npc_highborne_lamenterAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 EventMoveTimer; + uint32 EventCastTimer; + bool EventMove; + bool EventCast; + + void Reset() + { + EventMoveTimer = 10000; + EventCastTimer = 17500; + EventMove = true; + EventCast = true; + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (EventMove) + { + if (EventMoveTimer <= diff) + { + me->SetDisableGravity(true); + me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetDistance(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW) / (5000 * 0.001f)); + me->SetPosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation()); + EventMove = false; + } else EventMoveTimer -= diff; + } + if (EventCast) + { + if (EventCastTimer <= diff) + { + DoCast(me, SPELL_HIGHBORNE_AURA); + EventCast = false; + } else EventCastTimer -= diff; + } + } + }; +}; + +/*###### +## npc_parqual_fintallas +######*/ + +#define SPELL_MARK_OF_SHAME 6767 + +#define GOSSIP_HPF1 "Gul'dan" +#define GOSSIP_HPF2 "Kel'Thuzad" +#define GOSSIP_HPF3 "Ner'zhul" + +class npc_parqual_fintallas : public CreatureScript +{ +public: + npc_parqual_fintallas() : CreatureScript("npc_parqual_fintallas") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_MARK_OF_SHAME, false); + } + if (action == GOSSIP_ACTION_INFO_DEF+2) + { + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(6628); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(6628) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_MARK_OF_SHAME)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HPF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HPF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HPF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(5822, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(5821, creature->GetGUID()); + + return true; + } +}; + +/*###### +## AddSC +######*/ + +void AddSC_undercity() +{ + new npc_lady_sylvanas_windrunner(); + new npc_highborne_lamenter(); + new npc_parqual_fintallas(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp new file mode 100644 index 00000000000..ee22b766154 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_western_plaguelands.cpp @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Western_Plaguelands +SD%Complete: 90 +SDComment: Quest support: 5097, 5098, 5216, 5219, 5222, 5225, 5229, 5231, 5233, 5235. To obtain Vitreous Focuser (could use more spesifics about gossip items) +SDCategory: Western Plaguelands +EndScriptData */ + +/* ContentData +npcs_dithers_and_arbington +npc_myranda_the_hag +npc_the_scourge_cauldron +npc_andorhal_tower +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npcs_dithers_and_arbington +######*/ + +#define GOSSIP_HDA1 "What does the Felstone Field Cauldron need?" +#define GOSSIP_HDA2 "What does the Dalson's Tears Cauldron need?" +#define GOSSIP_HDA3 "What does the Writhing Haunt Cauldron need?" +#define GOSSIP_HDA4 "What does the Gahrron's Withering Cauldron need?" + +#define GOSSIP_SDA1 "Thanks, i need a Vitreous Focuser" + +class npcs_dithers_and_arbington : public CreatureScript +{ +public: + npcs_dithers_and_arbington() : CreatureScript("npcs_dithers_and_arbington") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_TRADE: + player->GetSession()->SendListInventory(creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(3980, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(3981, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(3982, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(3983, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, 17529, false); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + if (player->GetQuestRewardStatus(5237) || player->GetQuestRewardStatus(5238)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HDA4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(3985, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_myranda_the_hag +######*/ + +enum eMyranda +{ + QUEST_SUBTERFUGE = 5862, + QUEST_IN_DREAMS = 5944, + SPELL_SCARLET_ILLUSION = 17961 +}; + +#define GOSSIP_ITEM_ILLUSION "I am ready for the illusion, Myranda." + +class npc_myranda_the_hag : public CreatureScript +{ +public: + npc_myranda_the_hag() : CreatureScript("npc_myranda_the_hag") { } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF + 1) + { + player->CLOSE_GOSSIP_MENU(); + player->CastSpell(player, SPELL_SCARLET_ILLUSION, false); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_SUBTERFUGE) == QUEST_STATUS_COMPLETE && + !player->GetQuestRewardStatus(QUEST_IN_DREAMS) && !player->HasAura(SPELL_SCARLET_ILLUSION)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ILLUSION, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(4773, creature->GetGUID()); + return true; + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_the_scourge_cauldron +######*/ + +class npc_the_scourge_cauldron : public CreatureScript +{ +public: + npc_the_scourge_cauldron() : CreatureScript("npc_the_scourge_cauldron") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_the_scourge_cauldronAI (creature); + } + + struct npc_the_scourge_cauldronAI : public ScriptedAI + { + npc_the_scourge_cauldronAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + + void EnterCombat(Unit* /*who*/) {} + + void DoDie() + { + //summoner dies here + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + //override any database `spawntimesecs` to prevent duplicated summons + uint32 rTime = me->GetRespawnDelay(); + if (rTime<600) + me->SetRespawnDelay(600); + } + + void MoveInLineOfSight(Unit* who) + { + if (!who || who->GetTypeId() != TYPEID_PLAYER) + return; + + if (who->GetTypeId() == TYPEID_PLAYER) + { + switch (me->GetAreaId()) + { + case 199: //felstone + if (CAST_PLR(who)->GetQuestStatus(5216) == QUEST_STATUS_INCOMPLETE || + CAST_PLR(who)->GetQuestStatus(5229) == QUEST_STATUS_INCOMPLETE) + { + me->SummonCreature(11075, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + DoDie(); + } + break; + case 200: //dalson + if (CAST_PLR(who)->GetQuestStatus(5219) == QUEST_STATUS_INCOMPLETE || + CAST_PLR(who)->GetQuestStatus(5231) == QUEST_STATUS_INCOMPLETE) + { + me->SummonCreature(11077, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + DoDie(); + } + break; + case 201: //gahrron + if (CAST_PLR(who)->GetQuestStatus(5225) == QUEST_STATUS_INCOMPLETE || + CAST_PLR(who)->GetQuestStatus(5235) == QUEST_STATUS_INCOMPLETE) + { + me->SummonCreature(11078, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + DoDie(); + } + break; + case 202: //writhing + if (CAST_PLR(who)->GetQuestStatus(5222) == QUEST_STATUS_INCOMPLETE || + CAST_PLR(who)->GetQuestStatus(5233) == QUEST_STATUS_INCOMPLETE) + { + me->SummonCreature(11076, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + DoDie(); + } + break; + } + } + } + }; +}; + +/*###### +## npcs_andorhal_tower +######*/ + +enum eAndorhalTower +{ + GO_BEACON_TORCH = 176093 +}; + +class npc_andorhal_tower : public CreatureScript +{ +public: + npc_andorhal_tower() : CreatureScript("npc_andorhal_tower") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_andorhal_towerAI (creature); + } + + struct npc_andorhal_towerAI : public Scripted_NoMovementAI + { + npc_andorhal_towerAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + + void MoveInLineOfSight(Unit* who) + { + if (!who || who->GetTypeId() != TYPEID_PLAYER) + return; + + if (me->FindNearestGameObject(GO_BEACON_TORCH, 10.0f)) + CAST_PLR(who)->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); + } + }; +}; + +/*###### +## npc_anchorite_truuen +######*/ + +enum eTruuen +{ + NPC_GHOST_UTHER = 17233, + NPC_THEL_DANIS = 1854, + NPC_GHOUL = 1791, //ambush + + QUEST_TOMB_LIGHTBRINGER = 9446, + + SAY_WP_0 = 0, //Beware! We are attacked! + SAY_WP_1 = 1, //It must be the purity of the Mark of the Lightbringer that is drawing forth the Scourge to attack us. We must proceed with caution lest we be overwhelmed! + SAY_WP_2 = 2, //This land truly needs to be cleansed by the Light! Let us continue on to the tomb. It isn't far now... + SAY_WP_3 = 0, //Be welcome, friends! + SAY_WP_4 = 0, //Thank you for coming here in remembrance of me. Your efforts in recovering that symbol, while unnecessary, are certainly touching to an old man's heart. + SAY_WP_5 = 1, //Please, rise my friend. Keep the Blessing as a symbol of the strength of the Light and how heroes long gone might once again rise in each of us to inspire. + SAY_WP_6 = 2 //Thank you my friend for making this possible. This is a day that I shall never forget! I think I will stay a while. Please return to High Priestess MacDonnell at the camp. I know that she'll be keenly interested to know of what has transpired here. +}; + +class npc_anchorite_truuen : public CreatureScript +{ +public: + npc_anchorite_truuen() : CreatureScript("npc_anchorite_truuen") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + npc_escortAI* pEscortAI = CAST_AI(npc_anchorite_truuen::npc_anchorite_truuenAI, creature->AI()); + + if (quest->GetQuestId() == QUEST_TOMB_LIGHTBRINGER) + pEscortAI->Start(true, true, player->GetGUID()); + return false; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_anchorite_truuenAI(creature); + } + + struct npc_anchorite_truuenAI : public npc_escortAI + { + npc_anchorite_truuenAI(Creature* creature) : npc_escortAI(creature) { } + + uint32 m_uiChatTimer; + + uint64 UghostGUID; + uint64 TheldanisGUID; + + Creature* Ughost; + Creature* Theldanis; + + void Reset() + { + m_uiChatTimer = 7000; + } + + void JustSummoned(Creature* summoned) + { + if (summoned->GetEntry() == NPC_GHOUL) + summoned->AI()->AttackStart(me); + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + + switch (waypointId) + { + case 8: + Talk(SAY_WP_0); + me->SummonCreature(NPC_GHOUL, me->GetPositionX()+7.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); + me->SummonCreature(NPC_GHOUL, me->GetPositionX()+5.0f, me->GetPositionY()+5.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); + break; + case 9: + Talk(SAY_WP_1); + break; + case 14: + me->SummonCreature(NPC_GHOUL, me->GetPositionX()+7.0f, me->GetPositionY()+7.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); + me->SummonCreature(NPC_GHOUL, me->GetPositionX()+5.0f, me->GetPositionY()+5.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); + me->SummonCreature(NPC_GHOUL, me->GetPositionX()+10.0f, me->GetPositionY()+10.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); + me->SummonCreature(NPC_GHOUL, me->GetPositionX()+8.0f, me->GetPositionY()+8.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 90000); + break; + case 15: + Talk(SAY_WP_2); + case 21: + Theldanis = GetClosestCreatureWithEntry(me, NPC_THEL_DANIS, 150); + if (Theldanis) + Theldanis->AI()->Talk(SAY_WP_3); + break; + case 22: + break; + case 23: + Ughost = me->SummonCreature(NPC_GHOST_UTHER, 971.86f, -1825.42f, 81.99f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + if (Ughost) + { + Ughost->SetDisableGravity(true); + Ughost->AI()->Talk(SAY_WP_4, me->GetGUID()); + } + m_uiChatTimer = 4000; + break; + case 24: + if (Ughost) + Ughost->AI()->Talk(SAY_WP_5, me->GetGUID()); + m_uiChatTimer = 4000; + break; + case 25: + if (Ughost) + Ughost->AI()->Talk(SAY_WP_6, me->GetGUID()); + m_uiChatTimer = 4000; + break; + case 26: + if (player) + player->GroupEventHappens(QUEST_TOMB_LIGHTBRINGER, me); + break; + } + } + + void EnterCombat(Unit* /*who*/){} + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_TOMB_LIGHTBRINGER); + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + DoMeleeAttackIfReady(); + if (HasEscortState(STATE_ESCORT_ESCORTING)) + m_uiChatTimer = 6000; + } + }; +}; + +/*###### +## +######*/ + +void AddSC_western_plaguelands() +{ + new npcs_dithers_and_arbington(); + new npc_myranda_the_hag(); + new npc_the_scourge_cauldron(); + new npc_andorhal_tower(); + new npc_anchorite_truuen(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_westfall.cpp b/src/server/scripts/EasternKingdoms/zone_westfall.cpp new file mode 100644 index 00000000000..1b93cf1be71 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_westfall.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Westfall +SD%Complete: 90 +SDComment: Quest support: 155, 1651 +SDCategory: Westfall +EndScriptData */ + +/* ContentData +npc_daphne_stilwell +npc_defias_traitor +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_daphne_stilwell +######*/ + +enum eEnums +{ + SAY_DS_START = 0, + SAY_DS_DOWN_1 = 1, + SAY_DS_DOWN_2 = 2, + SAY_DS_DOWN_3 = 3, + SAY_DS_PROLOGUE = 4, + + SPELL_SHOOT = 6660, + QUEST_TOME_VALOR = 1651, + NPC_DEFIAS_RAIDER = 6180, + EQUIP_ID_RIFLE = 2511 +}; + +class npc_daphne_stilwell : public CreatureScript +{ +public: + npc_daphne_stilwell() : CreatureScript("npc_daphne_stilwell") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_TOME_VALOR) + { + creature->AI()->Talk(SAY_DS_START); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_daphne_stilwell::npc_daphne_stilwellAI, creature->AI())) + pEscortAI->Start(true, true, player->GetGUID()); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_daphne_stilwellAI(creature); + } + + struct npc_daphne_stilwellAI : public npc_escortAI + { + npc_daphne_stilwellAI(Creature* creature) : npc_escortAI(creature) {} + + uint32 uiWPHolder; + uint32 uiShootTimer; + + void Reset() + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + { + switch (uiWPHolder) + { + case 7: + Talk(SAY_DS_DOWN_1); + break; + case 8: + Talk(SAY_DS_DOWN_2); + break; + case 9: + Talk(SAY_DS_DOWN_3); + break; + } + } + else + uiWPHolder = 0; + + uiShootTimer = 0; + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + uiWPHolder = waypointId; + + switch (waypointId) + { + case 4: + SetEquipmentSlots(false, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE, EQUIP_ID_RIFLE); + me->SetSheath(SHEATH_STATE_RANGED); + me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING_NO_SHEATHE); + break; + case 7: + me->SummonCreature(NPC_DEFIAS_RAIDER, -11450.836f, 1569.755f, 54.267f, 4.230f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.697f, 1569.124f, 54.421f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.237f, 1568.307f, 54.620f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 8: + me->SetSheath(SHEATH_STATE_RANGED); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11450.836f, 1569.755f, 54.267f, 4.230f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.697f, 1569.124f, 54.421f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.237f, 1568.307f, 54.620f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.037f, 1570.213f, 54.961f, 4.283f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 9: + me->SetSheath(SHEATH_STATE_RANGED); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11450.836f, 1569.755f, 54.267f, 4.230f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.697f, 1569.124f, 54.421f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.237f, 1568.307f, 54.620f, 4.206f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11448.037f, 1570.213f, 54.961f, 4.283f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_DEFIAS_RAIDER, -11449.018f, 1570.738f, 54.828f, 4.220f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 10: + SetRun(false); + break; + case 11: + Talk(SAY_DS_PROLOGUE); + break; + case 13: + SetEquipmentSlots(true); + me->SetSheath(SHEATH_STATE_UNARMED); + me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING_NO_SHEATHE); + break; + case 17: + player->GroupEventHappens(QUEST_TOME_VALOR, me); + break; + } + } + + void AttackStart(Unit* who) + { + if (!who) + return; + + if (me->Attack(who, false)) + { + me->AddThreat(who, 0.0f); + me->SetInCombatWith(who); + who->SetInCombatWith(me); + + me->GetMotionMaster()->MoveChase(who, 30.0f); + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void Update(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + + if (!UpdateVictim()) + return; + + if (uiShootTimer <= diff) + { + uiShootTimer = 1500; + + if (!me->IsWithinDist(me->getVictim(), ATTACK_DISTANCE)) + DoCast(me->getVictim(), SPELL_SHOOT); + } else uiShootTimer -= diff; + } + }; +}; + +/*###### +## npc_defias_traitor +######*/ +enum DefiasSays +{ + SAY_START = 0, + SAY_PROGRESS = 1, + SAY_END = 2, + SAY_AGGRO = 3 +}; + + +#define QUEST_DEFIAS_BROTHERHOOD 155 + +class npc_defias_traitor : public CreatureScript +{ +public: + npc_defias_traitor() : CreatureScript("npc_defias_traitor") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_DEFIAS_BROTHERHOOD) + { + if (npc_escortAI* pEscortAI = CAST_AI(npc_defias_traitor::npc_defias_traitorAI, creature->AI())) + pEscortAI->Start(true, true, player->GetGUID()); + + creature->AI()->Talk(SAY_START, player->GetGUID()); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_defias_traitorAI(creature); + } + + struct npc_defias_traitorAI : public npc_escortAI + { + npc_defias_traitorAI(Creature* creature) : npc_escortAI(creature) { Reset(); } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 35: + SetRun(false); + break; + case 36: + Talk(SAY_PROGRESS, player->GetGUID()); + break; + case 44: + Talk(SAY_END, player->GetGUID()); + player->GroupEventHappens(QUEST_DEFIAS_BROTHERHOOD, me); + break; + } + } + + void EnterCombat(Unit* who) + { + Talk(SAY_AGGRO, who->GetGUID()); + } + + void Reset() {} + }; +}; + +void AddSC_westfall() +{ + new npc_daphne_stilwell(); + new npc_defias_traitor(); +} diff --git a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp new file mode 100644 index 00000000000..c8a1fc2b2b4 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Wetlands +SD%Complete: 80 +SDComment: Quest support: 1249 +SDCategory: Wetlands +EndScriptData */ + +/* ContentData +npc_mikhail +npc_tapoke_slim_jahn +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_tapoke_slim_jahn +######*/ + +enum eTapokeSlim +{ + QUEST_MISSING_DIPLO_PT11 = 1249, + FACTION_ENEMY = 168, + SPELL_STEALTH = 1785, + SPELL_CALL_FRIENDS = 16457, //summons 1x friend + NPC_SLIMS_FRIEND = 4971, + NPC_TAPOKE_SLIM_JAHN = 4962 +}; + +class npc_tapoke_slim_jahn : public CreatureScript +{ +public: + npc_tapoke_slim_jahn() : CreatureScript("npc_tapoke_slim_jahn") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tapoke_slim_jahnAI(creature); + } + + struct npc_tapoke_slim_jahnAI : public npc_escortAI + { + npc_tapoke_slim_jahnAI(Creature* creature) : npc_escortAI(creature) { } + + bool IsFriendSummoned; + + void Reset() + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + IsFriendSummoned = false; + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 2: + if (me->HasStealthAura()) + me->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); + SetRun(); + me->setFaction(FACTION_ENEMY); + break; + } + } + + void EnterCombat(Unit* /*who*/) + { + if (HasEscortState(STATE_ESCORT_ESCORTING) && !IsFriendSummoned && GetPlayerForEscort()) + { + for (uint8 i = 0; i < 3; ++i) + DoCast(me, SPELL_CALL_FRIENDS, true); + + IsFriendSummoned = true; + } + } + + void JustSummoned(Creature* summoned) + { + if (Player* player = GetPlayerForEscort()) + summoned->AI()->AttackStart(player); + } + + void AttackedBy(Unit* pAttacker) + { + if (me->getVictim()) + return; + + if (me->IsFriendlyTo(pAttacker)) + return; + + AttackStart(pAttacker); + } + + void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage) + { + if (HealthBelowPct(20)) + { + if (Player* player = GetPlayerForEscort()) + { + if (player->GetTypeId() == TYPEID_PLAYER) + CAST_PLR(player)->GroupEventHappens(QUEST_MISSING_DIPLO_PT11, me); + + uiDamage = 0; + + me->RestoreFaction(); + me->RemoveAllAuras(); + me->DeleteThreatList(); + me->CombatStop(true); + + SetRun(false); + } + } + } + }; +}; + +/*###### +## npc_mikhail +######*/ + +class npc_mikhail : public CreatureScript +{ +public: + npc_mikhail() : CreatureScript("npc_mikhail") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT11) + { + Creature* pSlim = creature->FindNearestCreature(NPC_TAPOKE_SLIM_JAHN, 25.0f); + + if (!pSlim) + return false; + + if (!pSlim->HasStealthAura()) + pSlim->CastSpell(pSlim, SPELL_STEALTH, true); + + if (npc_tapoke_slim_jahn::npc_tapoke_slim_jahnAI* pEscortAI = CAST_AI(npc_tapoke_slim_jahn::npc_tapoke_slim_jahnAI, pSlim->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return false; + } +}; + +/*###### +## AddSC +######*/ + +void AddSC_wetlands() +{ + new npc_tapoke_slim_jahn(); + new npc_mikhail(); +} diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index ee091c96309..5c44cd7ef27 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -10,9 +10,9 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} - Kalimdor/stonetalon_mountains.cpp - Kalimdor/silithus.cpp - Kalimdor/moonglade.cpp + Kalimdor/zone_stonetalon_mountains.cpp + Kalimdor/zone_silithus.cpp + Kalimdor/zone_moonglade.cpp Kalimdor/RazorfenDowns/razorfen_downs.cpp Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp @@ -58,10 +58,10 @@ set(scripts_STAT_SRCS Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp Kalimdor/BlackfathomDeeps/blackfathom_deeps.h - Kalimdor/azuremyst_isle.cpp - Kalimdor/orgrimmar.cpp - Kalimdor/desolace.cpp - Kalimdor/feralas.cpp + Kalimdor/zone_azuremyst_isle.cpp + Kalimdor/zone_orgrimmar.cpp + Kalimdor/zone_desolace.cpp + Kalimdor/zone_feralas.cpp Kalimdor/Maraudon/boss_princess_theradras.cpp Kalimdor/Maraudon/boss_landslide.cpp Kalimdor/Maraudon/boss_celebras_the_cursed.cpp @@ -78,7 +78,7 @@ set(scripts_STAT_SRCS Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp - Kalimdor/darkshore.cpp + Kalimdor/zone_darkshore.cpp Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp @@ -87,27 +87,27 @@ set(scripts_STAT_SRCS Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp - Kalimdor/mulgore.cpp - Kalimdor/bloodmyst_isle.cpp - Kalimdor/thunder_bluff.cpp - Kalimdor/azshara.cpp + Kalimdor/zone_mulgore.cpp + Kalimdor/zone_bloodmyst_isle.cpp + Kalimdor/zone_thunder_bluff.cpp + Kalimdor/zone_azshara.cpp Kalimdor/RazorfenKraul/razorfen_kraul.h Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp Kalimdor/RazorfenKraul/razorfen_kraul.cpp - Kalimdor/the_barrens.cpp - Kalimdor/ungoro_crater.cpp + Kalimdor/zone_the_barrens.cpp + Kalimdor/zone_ungoro_crater.cpp Kalimdor/WailingCaverns/wailing_caverns.h Kalimdor/WailingCaverns/instance_wailing_caverns.cpp Kalimdor/WailingCaverns/wailing_caverns.cpp - Kalimdor/durotar.cpp - Kalimdor/felwood.cpp + Kalimdor/zone_durotar.cpp + Kalimdor/zone_felwood.cpp Kalimdor/boss_azuregos.cpp - Kalimdor/tanaris.cpp - Kalimdor/dustwallow_marsh.cpp - Kalimdor/winterspring.cpp - Kalimdor/thousand_needles.cpp - Kalimdor/ashenvale.cpp - Kalimdor/teldrassil.cpp + Kalimdor/zone_tanaris.cpp + Kalimdor/zone_dustwallow_marsh.cpp + Kalimdor/zone_winterspring.cpp + Kalimdor/zone_thousand_needles.cpp + Kalimdor/zone_ashenvale.cpp + Kalimdor/zone_teldrassil.cpp Kalimdor/OnyxiasLair/boss_onyxia.cpp Kalimdor/OnyxiasLair/onyxias_lair.h Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp deleted file mode 100644 index 94c68a1d3ec..00000000000 --- a/src/server/scripts/Kalimdor/ashenvale.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Ashenvale -SD%Complete: 70 -SDComment: Quest support: 6544, 6482 -SDCategory: Ashenvale Forest -EndScriptData */ - -/* ContentData -npc_torek -npc_ruul_snowhoof -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*#### -# npc_torek -####*/ - -enum TorekSays -{ - SAY_READY = 0, - SAY_MOVE = 1, - SAY_PREPARE = 2, - SAY_WIN = 3, - SAY_END = 4, -}; - -enum TorekSpells -{ - SPELL_REND = 11977, - SPELL_THUNDERCLAP = 8078, -}; - -enum TorekMisc -{ - QUEST_TOREK_ASSULT = 6544, - - ENTRY_SPLINTERTREE_RAIDER = 12859, - ENTRY_DURIEL = 12860, - ENTRY_SILVERWING_SENTINEL = 12896, - ENTRY_SILVERWING_WARRIOR = 12897, -}; - -class npc_torek : public CreatureScript -{ - public: - - npc_torek() : CreatureScript("npc_torek") - { - } - - struct npc_torekAI : public npc_escortAI - { - npc_torekAI(Creature* creature) : npc_escortAI(creature) {} - - uint32 Rend_Timer; - uint32 Thunderclap_Timer; - bool Completed; - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 1: - Talk(SAY_MOVE, player->GetGUID()); - break; - case 8: - Talk(SAY_PREPARE, player->GetGUID()); - break; - case 19: - //TODO: verify location and creatures amount. - me->SummonCreature(ENTRY_DURIEL, 1776.73f, -2049.06f, 109.83f, 1.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(ENTRY_SILVERWING_SENTINEL, 1774.64f, -2049.41f, 109.83f, 1.40f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(ENTRY_SILVERWING_WARRIOR, 1778.73f, -2049.50f, 109.83f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 20: - Talk(SAY_WIN, player->GetGUID()); - Completed = true; - player->GroupEventHappens(QUEST_TOREK_ASSULT, me); - break; - case 21: - Talk(SAY_END, player->GetGUID()); - break; - } - } - } - - void Reset() - { - Rend_Timer = 5000; - Thunderclap_Timer = 8000; - Completed = false; - } - - void EnterCombat(Unit* /*who*/) - { - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - if (Rend_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_REND); - Rend_Timer = 20000; - } else Rend_Timer -= diff; - - if (Thunderclap_Timer <= diff) - { - DoCast(me, SPELL_THUNDERCLAP); - Thunderclap_Timer = 30000; - } else Thunderclap_Timer -= diff; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_torekAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_TOREK_ASSULT) - { - //TODO: find companions, make them follow Torek, at any time (possibly done by core/database in future?) - creature->AI()->Talk(SAY_READY, player->GetGUID()); - creature->setFaction(113); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_torekAI, creature->AI())) - pEscortAI->Start(true, true, player->GetGUID()); - } - - return true; - } -}; - -/*#### -# npc_ruul_snowhoof -####*/ - -enum RuulSnowhoof -{ - NPC_THISTLEFUR_URSA = 3921, - NPC_THISTLEFUR_TOTEMIC = 3922, - NPC_THISTLEFUR_PATHFINDER = 3926, - - QUEST_FREEDOM_TO_RUUL = 6482, - - GO_CAGE = 178147 -}; - -Position const RuulSnowhoofSummonsCoord[6] = -{ - {3449.218018f, -587.825073f, 174.978867f, 4.714445f}, - {3446.384521f, -587.830872f, 175.186279f, 4.714445f}, - {3444.218994f, -587.835327f, 175.380600f, 4.714445f}, - {3508.344482f, -492.024261f, 186.929031f, 4.145029f}, - {3506.265625f, -490.531006f, 186.740128f, 4.239277f}, - {3503.682373f, -489.393799f, 186.629684f, 4.349232f} -}; - -class npc_ruul_snowhoof : public CreatureScript -{ - public: - npc_ruul_snowhoof() : CreatureScript("npc_ruul_snowhoof") { } - - struct npc_ruul_snowhoofAI : public npc_escortAI - { - npc_ruul_snowhoofAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 0: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) - Cage->SetGoState(GO_STATE_ACTIVE); - break; - case 13: - me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[0], TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[1], TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[2], TEMPSUMMON_DEAD_DESPAWN, 60000); - break; - case 19: - me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[3], TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[4], TEMPSUMMON_DEAD_DESPAWN, 60000); - me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[5], TEMPSUMMON_DEAD_DESPAWN, 60000); - break; - case 21: - player->GroupEventHappens(QUEST_FREEDOM_TO_RUUL, me); - break; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void Reset() - { - if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) - Cage->SetGoState(GO_STATE_READY); - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ruul_snowhoofAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL) - { - creature->setFaction(113); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_ruul_snowhoofAI, (creature->AI()))) - pEscortAI->Start(true, false, player->GetGUID()); - } - - return true; - } -}; - -enum Muglash -{ - SAY_MUG_START1 = 0, - SAY_MUG_START2 = 1, - SAY_MUG_BRAZIER = 2, - SAY_MUG_BRAZIER_WAIT = 3, - SAY_MUG_ON_GUARD = 4, - SAY_MUG_REST = 5, - SAY_MUG_DONE = 6, - SAY_MUG_GRATITUDE = 7, - SAY_MUG_PATROL = 8, - SAY_MUG_RETURN = 9, - - QUEST_VORSHA = 6641, - - GO_NAGA_BRAZIER = 178247, - - NPC_WRATH_RIDER = 3713, - NPC_WRATH_SORCERESS = 3717, - NPC_WRATH_RAZORTAIL = 3712, - - NPC_WRATH_PRIESTESS = 3944, - NPC_WRATH_MYRMIDON = 3711, - NPC_WRATH_SEAWITCH = 3715, - - NPC_VORSHA = 12940, - NPC_MUGLASH = 12717 -}; - -Position const FirstNagaCoord[3] = -{ - {3603.504150f, 1122.631104f, 1.635f, 0.0f}, // rider - {3589.293945f, 1148.664063f, 5.565f, 0.0f}, // sorceress - {3609.925537f, 1168.759521f, -1.168f, 0.0f} // razortail -}; - -Position const SecondNagaCoord[3] = -{ - {3609.925537f, 1168.759521f, -1.168f, 0.0f}, // witch - {3645.652100f, 1139.425415f, 1.322f, 0.0f}, // priest - {3583.602051f, 1128.405762f, 2.347f, 0.0f} // myrmidon -}; - -Position const VorshaCoord = {3633.056885f, 1172.924072f, -5.388f, 0.0f}; - -class npc_muglash : public CreatureScript -{ - public: - npc_muglash() : CreatureScript("npc_muglash") { } - - struct npc_muglashAI : public npc_escortAI - { - npc_muglashAI(Creature* creature) : npc_escortAI(creature) { } - - uint8 WaveId; - uint32 EventTimer; - bool IsBrazierExtinguished; - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 0: - Talk(SAY_MUG_START2, player->GetGUID()); - break; - case 24: - Talk(SAY_MUG_BRAZIER, player->GetGUID()); - - if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_NAGA_BRAZIER, INTERACTION_DISTANCE*2)) - { - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - SetEscortPaused(true); - } - break; - case 25: - Talk(SAY_MUG_GRATITUDE); - player->GroupEventHappens(QUEST_VORSHA, me); - break; - case 26: - Talk(SAY_MUG_PATROL); - break; - case 27: - Talk(SAY_MUG_RETURN); - break; - } - } - } - - void EnterCombat(Unit* /*who*/) - { - if (Player* player = GetPlayerForEscort()) - if (HasEscortState(STATE_ESCORT_PAUSED)) - { - if (urand(0, 1)) - Talk(SAY_MUG_ON_GUARD, player->GetGUID()); - return; - } - } - - void Reset() - { - EventTimer = 10000; - WaveId = 0; - IsBrazierExtinguished = false; - } - - void JustDied(Unit* /*killer*/) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_VORSHA); - } - - void DoWaveSummon() - { - switch (WaveId) - { - case 1: - me->SummonCreature(NPC_WRATH_RIDER, FirstNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_SORCERESS, FirstNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_RAZORTAIL, FirstNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - break; - case 2: - me->SummonCreature(NPC_WRATH_PRIESTESS, SecondNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_MYRMIDON, SecondNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - me->SummonCreature(NPC_WRATH_SEAWITCH, SecondNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - break; - case 3: - me->SummonCreature(NPC_VORSHA, VorshaCoord, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - break; - case 4: - SetEscortPaused(false); - Talk(SAY_MUG_DONE); - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (!me->getVictim()) - { - if (HasEscortState(STATE_ESCORT_PAUSED) && IsBrazierExtinguished) - { - if (EventTimer < uiDiff) - { - ++WaveId; - DoWaveSummon(); - EventTimer = 10000; - } - else - EventTimer -= uiDiff; - } - return; - } - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_muglashAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_VORSHA) - { - if (npc_muglashAI* pEscortAI = CAST_AI(npc_muglashAI, creature->AI())) - { - creature->AI()->Talk(SAY_MUG_START1); - creature->setFaction(113); - - pEscortAI->Start(true, false, player->GetGUID()); - } - } - return true; - } -}; - -class go_naga_brazier : public GameObjectScript -{ - public: - go_naga_brazier() : GameObjectScript("go_naga_brazier") { } - - bool OnGossipHello(Player* /*player*/, GameObject* go) - { - if (Creature* creature = GetClosestCreatureWithEntry(go, NPC_MUGLASH, INTERACTION_DISTANCE*2)) - { - if (npc_muglash::npc_muglashAI* pEscortAI = CAST_AI(npc_muglash::npc_muglashAI, creature->AI())) - { - creature->AI()->Talk(SAY_MUG_BRAZIER_WAIT); - - pEscortAI->IsBrazierExtinguished = true; - return false; - } - } - - return true; - } -}; - -void AddSC_ashenvale() -{ - new npc_torek(); - new npc_ruul_snowhoof(); - new npc_muglash(); - new go_naga_brazier(); -} diff --git a/src/server/scripts/Kalimdor/azshara.cpp b/src/server/scripts/Kalimdor/azshara.cpp deleted file mode 100644 index 44f7e1e8172..00000000000 --- a/src/server/scripts/Kalimdor/azshara.cpp +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Azshara -SD%Complete: 90 -SDComment: Quest support: 2744, 3141, 9364, 10994 -SDCategory: Azshara -EndScriptData */ - -/* ContentData -mobs_spitelashes -npc_loramus_thalipedes -mob_rizzle_sprysprocket -mob_depth_charge -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "SpellInfo.h" -#include "WorldSession.h" - -/*###### -## mobs_spitelashes -######*/ - -class mobs_spitelashes : public CreatureScript -{ -public: - mobs_spitelashes() : CreatureScript("mobs_spitelashes") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mobs_spitelashesAI (creature); - } - - struct mobs_spitelashesAI : public ScriptedAI - { - mobs_spitelashesAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 morphtimer; - bool spellhit; - - void Reset() - { - morphtimer = 0; - spellhit = false; - } - - void EnterCombat(Unit* /*who*/) { } - - void SpellHit(Unit* Hitter, const SpellInfo* Spellkind) - { - if (!spellhit && - Hitter->GetTypeId() == TYPEID_PLAYER && - CAST_PLR(Hitter)->GetQuestStatus(9364) == QUEST_STATUS_INCOMPLETE && - (Spellkind->Id == 118 || Spellkind->Id == 12824 || Spellkind->Id == 12825 || Spellkind->Id == 12826)) - { - spellhit=true; - DoCast(me, 29124); //become a sheep - } - } - - void UpdateAI(const uint32 diff) - { - // we mustn't remove the Creature in the same round in which we cast the summon spell, otherwise there will be no summons - if (spellhit && morphtimer >= 5000) - { - me->DespawnOrUnsummon(); - return; - } - // walk 5 seconds before summoning - if (spellhit && morphtimer<5000) - { - morphtimer+=diff; - if (morphtimer >= 5000) - { - DoCast(me, 28406); //summon copies - DoCast(me, 6924); //visual explosion - } - } - if (!UpdateVictim()) - return; - - //TODO: add abilities for the different creatures - DoMeleeAttackIfReady(); - } - }; - -}; - -/*###### -## npc_loramus_thalipedes -######*/ - -#define GOSSIP_HELLO_LT1 "Can you help me?" -#define GOSSIP_HELLO_LT2 "Tell me your story" -#define GOSSIP_SELECT_LT1 "Please continue" -#define GOSSIP_SELECT_LT2 "I do not understand" -#define GOSSIP_SELECT_LT3 "Indeed" -#define GOSSIP_SELECT_LT4 "I will do this with or your help, Loramus" -#define GOSSIP_SELECT_LT5 "Yes" - -class npc_loramus_thalipedes : public CreatureScript -{ -public: - npc_loramus_thalipedes() : CreatureScript("npc_loramus_thalipedes") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(2744); - break; - - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21); - player->SEND_GOSSIP_MENU(1813, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+21: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22); - player->SEND_GOSSIP_MENU(1814, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+22: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23); - player->SEND_GOSSIP_MENU(1815, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+23: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24); - player->SEND_GOSSIP_MENU(1816, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+24: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25); - player->SEND_GOSSIP_MENU(1817, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+25: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(3141); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(2744) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - if (player->GetQuestStatus(3141) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*#### -# mob_rizzle_sprysprocket -####*/ - -enum RizzleSprysprocketData -{ - QUEST_CHASING_THE_MOONSTONE = 10994, - - MOB_DEPTH_CHARGE = 23025, - - SPELL_RIZZLE_BLACKJACK = 39865, - SPELL_RIZZLE_ESCAPE = 39871, - SPELL_RIZZLE_FROST_GRENADE = 40525, - SPELL_DEPTH_CHARGE_TRAP = 38576, - SPELL_PERIODIC_DEPTH_CHARGE = 39912, - SPELL_GIVE_SOUTHFURY_MOONSTONE = 39886, - - SAY_RIZZLE_START = 0, - SAY_RIZZLE_GRENADE = 1, - SAY_RIZZLE_FINAL = 2, - MSG_ESCAPE_NOTICE = 3 -}; - -#define GOSSIP_GET_MOONSTONE "Hand over the Southfury moonstone and I'll let you go." - -Position const WPs[58] = -{ - {3691.97f, -3962.41f, 35.9118f, 3.67f}, - {3675.02f, -3960.49f, 35.9118f, 3.67f}, - {3653.19f, -3958.33f, 33.9118f, 3.59f}, - {3621.12f, -3958.51f, 29.9118f, 3.48f}, - {3604.86f, -3963, 29.9118f, 3.48f}, - {3569.94f, -3970.25f, 29.9118f, 3.44f}, - {3541.03f, -3975.64f, 29.9118f, 3.41f}, - {3510.84f, -3978.71f, 29.9118f, 3.41f}, - {3472.7f, -3997.07f, 29.9118f, 3.35f}, - {3439.15f, -4014.55f, 29.9118f, 3.29f}, - {3412.8f, -4025.87f, 29.9118f, 3.25f}, - {3384.95f, -4038.04f, 29.9118f, 3.24f}, - {3346.77f, -4052.93f, 29.9118f, 3.22f}, - {3299.56f, -4071.59f, 29.9118f, 3.20f}, - {3261.22f, -4080.38f, 30.9118f, 3.19f}, - {3220.68f, -4083.09f, 31.9118f, 3.18f}, - {3187.11f, -4070.45f, 33.9118f, 3.16f}, - {3162.78f, -4062.75f, 33.9118f, 3.15f}, - {3136.09f, -4050.32f, 33.9118f, 3.07f}, - {3119.47f, -4044.51f, 36.0363f, 3.07f}, - {3098.95f, -4019.8f, 33.9118f, 3.07f}, - {3073.07f, -4011.42f, 33.9118f, 3.07f}, - {3051.71f, -3993.37f, 33.9118f, 3.02f}, - {3027.52f, -3978.6f, 33.9118f, 3.00f}, - {3003.78f, -3960.14f, 33.9118f, 2.98f}, - {2977.99f, -3941.98f, 31.9118f, 2.96f}, - {2964.57f, -3932.07f, 30.9118f, 2.96f}, - {2947.9f, -3921.31f, 29.9118f, 2.96f}, - {2924.91f, -3910.8f, 29.9118f, 2.94f}, - {2903.04f, -3896.42f, 29.9118f, 2.93f}, - {2884.75f, -3874.03f, 29.9118f, 2.90f}, - {2868.19f, -3851.48f, 29.9118f, 2.82f}, - {2854.62f, -3819.72f, 29.9118f, 2.80f}, - {2825.53f, -3790.4f, 29.9118f, 2.744f}, - {2804.31f, -3773.05f, 29.9118f, 2.71f}, - {2769.78f, -3763.57f, 29.9118f, 2.70f}, - {2727.23f, -3745.92f, 30.9118f, 2.69f}, - {2680.12f, -3737.49f, 30.9118f, 2.67f}, - {2647.62f, -3739.94f, 30.9118f, 2.66f}, - {2616.6f, -3745.75f, 30.9118f, 2.64f}, - {2589.38f, -3731.97f, 30.9118f, 2.61f}, - {2562.94f, -3722.35f, 31.9118f, 2.56f}, - {2521.05f, -3716.6f, 31.9118f, 2.55f}, - {2485.26f, -3706.67f, 31.9118f, 2.51f}, - {2458.93f, -3696.67f, 31.9118f, 2.51f}, - {2432, -3692.03f, 31.9118f, 2.46f}, - {2399.59f, -3681.97f, 31.9118f, 2.45f}, - {2357.75f, -3666.6f, 31.9118f, 2.44f}, - {2311.99f, -3656.88f, 31.9118f, 2.94f}, - {2263.41f, -3649.55f, 31.9118f, 3.02f}, - {2209.05f, -3641.76f, 31.9118f, 2.99f}, - {2164.83f, -3637.64f, 31.9118f, 3.15f}, - {2122.42f, -3639, 31.9118f, 3.21f}, - {2075.73f, -3643.59f, 31.9118f, 3.22f}, - {2033.59f, -3649.52f, 31.9118f, 3.42f}, - {1985.22f, -3662.99f, 31.9118f, 3.42f}, - {1927.09f, -3679.56f, 33.9118f, 3.42f}, - {1873.57f, -3695.32f, 33.9118f, 3.44f} -}; - -class mob_rizzle_sprysprocket : public CreatureScript -{ -public: - mob_rizzle_sprysprocket() : CreatureScript("mob_rizzle_sprysprocket") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1 && player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_GIVE_SOUTHFURY_MOONSTONE, true); - CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->MustDieTimer = 3000; - CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->MustDie = true; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) != QUEST_STATUS_INCOMPLETE) - return true; - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GET_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(10811, creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_rizzle_sprysprocketAI (creature); - } - - struct mob_rizzle_sprysprocketAI : public ScriptedAI - { - mob_rizzle_sprysprocketAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 SpellEscapeTimer; - uint32 TeleportTimer; - uint32 CheckTimer; - uint32 GrenadeTimer; - uint32 MustDieTimer; - uint32 CurrWP; - - uint64 PlayerGUID; - - bool MustDie; - bool Escape; - bool ContinueWP; - bool Reached; - - void Reset() - { - SpellEscapeTimer = 1300; - TeleportTimer = 3500; - CheckTimer = 10000; - GrenadeTimer = 30000; - MustDieTimer = 3000; - CurrWP = 0; - - PlayerGUID = 0; - - MustDie = false; - Escape = false; - ContinueWP = false; - Reached = false; - } - - void UpdateAI(const uint32 diff) - { - if (MustDie) - { - if (MustDieTimer <= diff) - { - me->DespawnOrUnsummon(); - return; - } else MustDieTimer -= diff; - } - - if (!Escape) - { - if (!PlayerGUID) - return; - - if (SpellEscapeTimer <= diff) - { - DoCast(me, SPELL_RIZZLE_ESCAPE, false); - SpellEscapeTimer = 10000; - } else SpellEscapeTimer -= diff; - - if (TeleportTimer <= diff) - { - // temp solution - unit can't be teleported by core using spelleffect 5, only players - DoTeleportTo(3706.39f, -3969.15f, 35.9118f); - - //begin swimming and summon depth charges - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (!player) - return; - - Talk(MSG_ESCAPE_NOTICE, player->GetGUID()); - DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE); - me->SetUnitMovementFlags(MOVEMENTFLAG_HOVER | MOVEMENTFLAG_SWIMMING); - me->SetSpeed(MOVE_RUN, 0.85f, true); - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); - Escape = true; - } else TeleportTimer -= diff; - - return; - } - - if (ContinueWP) - { - me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); - ContinueWP = false; - } - - if (GrenadeTimer <= diff) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player) - { - Talk(SAY_RIZZLE_GRENADE, player->GetGUID()); - DoCast(player, SPELL_RIZZLE_FROST_GRENADE, true); - } - GrenadeTimer = 30000; - } else GrenadeTimer -= diff; - - if (CheckTimer <= diff) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (!player) - { - me->DespawnOrUnsummon(); - return; - } - - if (me->IsWithinDist(player, 10) && me->GetPositionX() > player->GetPositionX() && !Reached) - { - Talk(SAY_RIZZLE_FINAL); - me->SetUInt32Value(UNIT_NPC_FLAGS, 1); - me->setFaction(35); - me->GetMotionMaster()->MoveIdle(); - me->RemoveAurasDueToSpell(SPELL_PERIODIC_DEPTH_CHARGE); - Reached = true; - } - - CheckTimer = 1000; - } else CheckTimer -= diff; - - } - - void SendText(int32 iTextEntry, Player* player) - { - LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); - const char* text = sObjectMgr->GetTrinityString(iTextEntry, loc_idx); - sWorld->SendServerMessage(SERVER_MSG_STRING, text, player); - } - - void AttackStart(Unit* who) - { - if (!who || PlayerGUID) - return; - - if (who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) - { - PlayerGUID = who->GetGUID(); - Talk(SAY_RIZZLE_START); - DoCast(who, SPELL_RIZZLE_BLACKJACK, false); - return; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id == 57) - { - me->DespawnOrUnsummon(); - return; - } - - ++CurrWP; - ContinueWP = true; - } - }; -}; - -/*#### -# mob_depth_charge -####*/ -class mob_depth_charge : public CreatureScript -{ -public: - mob_depth_charge() : CreatureScript("mob_depth_charge") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_depth_chargeAI (creature); - } - - struct mob_depth_chargeAI : public ScriptedAI - { - mob_depth_chargeAI(Creature* creature) : ScriptedAI(creature) {} - - bool WeMustDie; - uint32 WeMustDieTimer; - - void Reset() - { - me->SetUnitMovementFlags(MOVEMENTFLAG_HOVER | MOVEMENTFLAG_SWIMMING); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - WeMustDie = false; - WeMustDieTimer = 1000; - } - - void UpdateAI(const uint32 diff) - { - if (WeMustDie) - { - if (WeMustDieTimer <= diff) - me->DespawnOrUnsummon(); - else - WeMustDieTimer -= diff; - } - return; - } - - void MoveInLineOfSight(Unit* who) - { - if (!who) - return; - - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 5)) - { - DoCast(who, SPELL_DEPTH_CHARGE_TRAP); - WeMustDie = true; - return; - } - } - - void AttackStart(Unit* /*who*/) {} - - void EnterCombat(Unit* /*who*/) {} - }; -}; - -void AddSC_azshara() -{ - new mobs_spitelashes(); - new npc_loramus_thalipedes(); - new mob_rizzle_sprysprocket(); - new mob_depth_charge(); -} diff --git a/src/server/scripts/Kalimdor/azuremyst_isle.cpp b/src/server/scripts/Kalimdor/azuremyst_isle.cpp deleted file mode 100644 index 4b03cd65cad..00000000000 --- a/src/server/scripts/Kalimdor/azuremyst_isle.cpp +++ /dev/null @@ -1,770 +0,0 @@ - /* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Azuremyst_Isle -SD%Complete: 75 -SDComment: Quest support: 9283, 9537, 9582, 9554, 9531, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582. -SDCategory: Azuremyst Isle -EndScriptData */ - -/* ContentData -npc_draenei_survivor -npc_engineer_spark_overgrind -npc_injured_draenei -npc_magwin -npc_geezle -go_ravager_cage -npc_death_ravager -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" -#include "Cell.h" -#include "CellImpl.h" -#include "GridNotifiers.h" - -/*###### -## npc_draenei_survivor -######*/ - -enum draeneiSurvivor -{ - SAY_HEAL = 0, - - SAY_HELP = 1, - - SPELL_IRRIDATION = 35046, - SPELL_STUNNED = 28630 -}; - -class npc_draenei_survivor : public CreatureScript -{ -public: - npc_draenei_survivor() : CreatureScript("npc_draenei_survivor") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_draenei_survivorAI (creature); - } - - struct npc_draenei_survivorAI : public ScriptedAI - { - npc_draenei_survivorAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 pCaster; - - uint32 SayThanksTimer; - uint32 RunAwayTimer; - uint32 SayHelpTimer; - - bool CanSayHelp; - - void Reset() - { - pCaster = 0; - - SayThanksTimer = 0; - RunAwayTimer = 0; - SayHelpTimer = 10000; - - CanSayHelp = true; - - DoCast(me, SPELL_IRRIDATION, true); - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - me->SetHealth(me->CountPctFromMaxHealth(10)); - me->SetStandState(UNIT_STAND_STATE_SLEEP); - } - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* who) - { - if (CanSayHelp && who->GetTypeId() == TYPEID_PLAYER && me->IsFriendlyTo(who) && me->IsWithinDistInMap(who, 25.0f)) - { - //Random switch between 4 texts - Talk(SAY_HELP, who->GetGUID()); - - SayHelpTimer = 20000; - CanSayHelp = false; - } - } - - void SpellHit(Unit* Caster, const SpellInfo* Spell) - { - if (Spell->SpellFamilyFlags[2] & 0x080000000) - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - me->SetStandState(UNIT_STAND_STATE_STAND); - - DoCast(me, SPELL_STUNNED, true); - - pCaster = Caster->GetGUID(); - - SayThanksTimer = 5000; - } - } - - void UpdateAI(const uint32 diff) - { - if (SayThanksTimer) - { - if (SayThanksTimer <= diff) - { - me->RemoveAurasDueToSpell(SPELL_IRRIDATION); - - if (Player* player = Unit::GetPlayer(*me, pCaster)) - { - Talk(SAY_HEAL, player->GetGUID()); - - player->TalkedToCreature(me->GetEntry(), me->GetGUID()); - } - - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(0, -4115.053711f, -13754.831055f, 73.508949f); - - RunAwayTimer = 10000; - SayThanksTimer = 0; - } else SayThanksTimer -= diff; - - return; - } - - if (RunAwayTimer) - { - if (RunAwayTimer <= diff) - me->DespawnOrUnsummon(); - else - RunAwayTimer -= diff; - - return; - } - - if (SayHelpTimer <= diff) - { - CanSayHelp = true; - SayHelpTimer = 20000; - } else SayHelpTimer -= diff; - } - }; - -}; - -/*###### -## npc_engineer_spark_overgrind -######*/ - -enum Overgrind -{ - SAY_TEXT = 0, - SAY_EMOTE = 1, - ATTACK_YELL = 2, - - AREA_COVE = 3579, - AREA_ISLE = 3639, - QUEST_GNOMERCY = 9537, - FACTION_HOSTILE = 14, - SPELL_DYNAMITE = 7978 -}; - -#define GOSSIP_FIGHT "Traitor! You will be brought to justice!" - -class npc_engineer_spark_overgrind : public CreatureScript -{ -public: - npc_engineer_spark_overgrind() : CreatureScript("npc_engineer_spark_overgrind") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE); - CAST_AI(npc_engineer_spark_overgrind::npc_engineer_spark_overgrindAI, creature->AI())->AttackStart(player); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_GNOMERCY) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_engineer_spark_overgrindAI (creature); - } - - struct npc_engineer_spark_overgrindAI : public ScriptedAI - { - npc_engineer_spark_overgrindAI(Creature* creature) : ScriptedAI(creature) - { - NormFaction = creature->getFaction(); - NpcFlags = creature->GetUInt32Value(UNIT_NPC_FLAGS); - - if (creature->GetAreaId() == AREA_COVE || creature->GetAreaId() == AREA_ISLE) - IsTreeEvent = true; - } - - uint32 NormFaction; - uint32 NpcFlags; - - uint32 DynamiteTimer; - uint32 EmoteTimer; - - bool IsTreeEvent; - - void Reset() - { - DynamiteTimer = 8000; - EmoteTimer = urand(120000, 150000); - - me->setFaction(NormFaction); - me->SetUInt32Value(UNIT_NPC_FLAGS, NpcFlags); - - IsTreeEvent = false; - } - - void EnterCombat(Unit* who) - { - Talk(ATTACK_YELL, who->GetGUID()); - } - - void UpdateAI(const uint32 diff) - { - if (!me->isInCombat() && !IsTreeEvent) - { - if (EmoteTimer <= diff) - { - Talk(SAY_TEXT); - Talk(SAY_EMOTE); - EmoteTimer = urand(120000, 150000); - } else EmoteTimer -= diff; - } - else if (IsTreeEvent) - return; - - if (!UpdateVictim()) - return; - - if (DynamiteTimer <= diff) - { - DoCast(me->getVictim(), SPELL_DYNAMITE); - DynamiteTimer = 8000; - } else DynamiteTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*###### -## npc_injured_draenei -######*/ - -class npc_injured_draenei : public CreatureScript -{ -public: - npc_injured_draenei() : CreatureScript("npc_injured_draenei") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_injured_draeneiAI (creature); - } - - struct npc_injured_draeneiAI : public ScriptedAI - { - npc_injured_draeneiAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - me->SetHealth(me->CountPctFromMaxHealth(15)); - switch (urand(0, 1)) - { - case 0: - me->SetStandState(UNIT_STAND_STATE_SIT); - break; - - case 1: - me->SetStandState(UNIT_STAND_STATE_SLEEP); - break; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* /*who*/) {} - - void UpdateAI(const uint32 /*diff*/) {} - }; - -}; - -/*###### -## npc_magwin -######*/ - -enum Magwin -{ - SAY_START = 0, - SAY_AGGRO = 1, - SAY_PROGRESS = 2, - SAY_END1 = 3, - SAY_END2 = 4, - EMOTE_HUG = 5, - - QUEST_A_CRY_FOR_SAY_HELP = 9528 -}; - -class npc_magwin : public CreatureScript -{ -public: - npc_magwin() : CreatureScript("npc_magwin") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_A_CRY_FOR_SAY_HELP) - { - creature->setFaction(113); - if (npc_escortAI* pEscortAI = CAST_AI(npc_escortAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_magwinAI(creature); - } - - struct npc_magwinAI : public npc_escortAI - { - npc_magwinAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 0: - Talk(SAY_START, player->GetGUID()); - break; - case 17: - Talk(SAY_PROGRESS, player->GetGUID()); - break; - case 28: - Talk(SAY_END1, player->GetGUID()); - break; - case 29: - Talk(EMOTE_HUG, player->GetGUID()); - Talk(SAY_END2, player->GetGUID()); - player->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP, me); - break; - } - } - } - - void EnterCombat(Unit* who) - { - Talk(SAY_AGGRO, who->GetGUID()); - } - - void Reset() {} - }; - -}; - -/*###### -## npc_geezle -######*/ - -enum Geezle -{ - QUEST_TREES_COMPANY = 9531, - - SPELL_TREE_DISGUISE = 30298, - - GEEZLE_SAY_1 = 0, - SPARK_SAY_2 = 3, - SPARK_SAY_3 = 4, - GEEZLE_SAY_4 = 1, - SPARK_SAY_5 = 5, - SPARK_SAY_6 = 6, - GEEZLE_SAY_7 = 2, - - EMOTE_SPARK = 7, - - MOB_SPARK = 17243, - GO_NAGA_FLAG = 181694 -}; - -Position const SparkPos = {-5029.91f, -11291.79f, 8.096f, 0.0f}; - -class npc_geezle : public CreatureScript -{ -public: - npc_geezle() : CreatureScript("npc_geezle") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_geezleAI(creature); - } - - struct npc_geezleAI : public ScriptedAI - { - npc_geezleAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 SparkGUID; - - uint8 Step; - uint32 SayTimer; - - bool EventStarted; - - void Reset() - { - SparkGUID = 0; - Step = 0; - StartEvent(); - } - - void EnterCombat(Unit* /*who*/){} - - void StartEvent() - { - Step = 0; - EventStarted = true; - if (Creature* Spark = me->SummonCreature(MOB_SPARK, SparkPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) - { - SparkGUID = Spark->GetGUID(); - Spark->setActive(true); - Spark->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } - SayTimer = 8000; - } - - uint32 NextStep(uint8 Step) - { - Creature* Spark = Unit::GetCreature(*me, SparkGUID); - if (!Spark) - return 99999999; - - switch (Step) - { - case 0: - Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f); - me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f); - return 9000; - case 1: - DespawnNagaFlag(true); - Spark->AI()->Talk(EMOTE_SPARK); - return 1000; - case 2: - Talk(GEEZLE_SAY_1, SparkGUID); - Spark->SetInFront(me); - me->SetInFront(Spark); - return 5000; - case 3: - Spark->AI()->Talk(SPARK_SAY_2); - return 7000; - case 4: - Spark->AI()->Talk(SPARK_SAY_3); - return 8000; - case 5: - Talk(GEEZLE_SAY_4, SparkGUID); - return 8000; - case 6: - Spark->AI()->Talk(SPARK_SAY_5); - return 9000; - case 7: - Spark->AI()->Talk(SPARK_SAY_6); - return 8000; - case 8: - Talk(GEEZLE_SAY_7, SparkGUID); - return 2000; - case 9: - me->GetMotionMaster()->MoveTargetedHome(); - Spark->GetMotionMaster()->MovePoint(0, SparkPos); - CompleteQuest(); - return 9000; - case 10: - Spark->DisappearAndDie(); - DespawnNagaFlag(false); - me->DisappearAndDie(); - default: return 99999999; - } - } - - // will complete Tree's company quest for all nearby players that are disguised as trees - void CompleteQuest() - { - float radius = 50.0f; - std::list players; - Trinity::AnyPlayerInObjectRangeCheck checker(me, radius); - Trinity::PlayerListSearcher searcher(me, players, checker); - me->VisitNearbyWorldObject(radius, searcher); - - for (std::list::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE && (*itr)->HasAura(SPELL_TREE_DISGUISE)) - (*itr)->KilledMonsterCredit(MOB_SPARK, 0); - } - - void DespawnNagaFlag(bool despawn) - { - std::list FlagList; - me->GetGameObjectListWithEntryInGrid(FlagList, GO_NAGA_FLAG, 100.0f); - - if (!FlagList.empty()) - { - for (std::list::const_iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr) - { - if (despawn) - (*itr)->SetLootState(GO_JUST_DEACTIVATED); - else - (*itr)->Respawn(); - } - } - else - sLog->outError(LOG_FILTER_TSCR, "SD2 ERROR: FlagList is empty!"); - } - - void UpdateAI(const uint32 diff) - { - if (SayTimer <= diff) - { - if (EventStarted) - SayTimer = NextStep(Step++); - } - else - SayTimer -= diff; - } - }; - -}; - -enum RavegerCage -{ - NPC_DEATH_RAVAGER = 17556, - - SPELL_REND = 13443, - SPELL_ENRAGING_BITE = 30736, - - QUEST_STRENGTH_ONE = 9582 -}; - -class go_ravager_cage : public GameObjectScript -{ -public: - go_ravager_cage() : GameObjectScript("go_ravager_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - if (player->GetQuestStatus(QUEST_STRENGTH_ONE) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* ravager = go->FindNearestCreature(NPC_DEATH_RAVAGER, 5.0f, true)) - { - ravager->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - ravager->SetReactState(REACT_AGGRESSIVE); - ravager->AI()->AttackStart(player); - } - } - return true; - } -}; - -class npc_death_ravager : public CreatureScript -{ -public: - npc_death_ravager() : CreatureScript("npc_death_ravager") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_death_ravagerAI(creature); - } - - struct npc_death_ravagerAI : public ScriptedAI - { - npc_death_ravagerAI(Creature* creature) : ScriptedAI(creature){} - - uint32 RendTimer; - uint32 EnragingBiteTimer; - - void Reset() - { - RendTimer = 30000; - EnragingBiteTimer = 20000; - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (RendTimer <= diff) - { - DoCast(me->getVictim(), SPELL_REND); - RendTimer = 30000; - } - else RendTimer -= diff; - - if (EnragingBiteTimer <= diff) - { - DoCast(me->getVictim(), SPELL_ENRAGING_BITE); - EnragingBiteTimer = 15000; - } - else EnragingBiteTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*######## -## Quest: The Prophecy of Akida -########*/ - -enum BristlelimbCage -{ - QUEST_THE_PROPHECY_OF_AKIDA = 9544, - NPC_STILLPINE_CAPITIVE = 17375, - GO_BRISTELIMB_CAGE = 181714, - - CAPITIVE_SAY = 0, - - POINT_INIT = 1, - EVENT_DESPAWN = 1, -}; - -class npc_stillpine_capitive : public CreatureScript -{ - public: - npc_stillpine_capitive() : CreatureScript("npc_stillpine_capitive") { } - - struct npc_stillpine_capitiveAI : public ScriptedAI - { - npc_stillpine_capitiveAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - if (GameObject* cage = me->FindNearestGameObject(GO_BRISTELIMB_CAGE, 5.0f)) - { - cage->SetLootState(GO_JUST_DEACTIVATED); - cage->SetGoState(GO_STATE_READY); - } - _events.Reset(); - _player = NULL; - _movementComplete = false; - } - - void StartMoving(Player* owner) - { - if (owner) - { - Talk(CAPITIVE_SAY, owner->GetGUID()); - _player = owner; - } - Position pos; - me->GetNearPosition(pos, 3.0f, 0.0f); - me->GetMotionMaster()->MovePoint(POINT_INIT, pos); - } - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE || id != POINT_INIT) - return; - - if (_player) - _player->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - - _movementComplete = true; - _events.ScheduleEvent(EVENT_DESPAWN, 3500); - } - - void UpdateAI(uint32 const diff) - { - if (!_movementComplete) - return; - - _events.Update(diff); - - if (_events.ExecuteEvent() == EVENT_DESPAWN) - me->DespawnOrUnsummon(); - } - - private: - Player* _player; - EventMap _events; - bool _movementComplete; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_stillpine_capitiveAI(creature); - } -}; - -class go_bristlelimb_cage : public GameObjectScript -{ - public: - go_bristlelimb_cage() : GameObjectScript("go_bristlelimb_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->SetGoState(GO_STATE_READY); - if (player->GetQuestStatus(QUEST_THE_PROPHECY_OF_AKIDA) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* capitive = go->FindNearestCreature(NPC_STILLPINE_CAPITIVE, 5.0f, true)) - { - go->ResetDoorOrButton(); - CAST_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player); - return false; - } - } - return true; - } -}; - -void AddSC_azuremyst_isle() -{ - new npc_draenei_survivor(); - new npc_engineer_spark_overgrind(); - new npc_injured_draenei(); - new npc_magwin(); - new npc_geezle(); - new npc_death_ravager(); - new go_ravager_cage(); - new npc_stillpine_capitive(); - new go_bristlelimb_cage(); -} diff --git a/src/server/scripts/Kalimdor/bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/bloodmyst_isle.cpp deleted file mode 100644 index 102a9494a65..00000000000 --- a/src/server/scripts/Kalimdor/bloodmyst_isle.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Bloodmyst_Isle -SD%Complete: 80 -SDComment: Quest support: 9670, 9756(gossip items text needed). -SDCategory: Bloodmyst Isle -EndScriptData */ - -/* ContentData -mob_webbed_creature -npc_captured_sunhawk_agent -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## mob_webbed_creature -######*/ - -//possible creatures to be spawned -uint32 const possibleSpawns[32] = {17322, 17661, 17496, 17522, 17340, 17352, 17333, 17524, 17654, 17348, 17339, 17345, 17359, 17353, 17336, 17550, 17330, 17701, 17321, 17680, 17325, 17320, 17683, 17342, 17715, 17334, 17341, 17338, 17337, 17346, 17344, 17327}; - -class mob_webbed_creature : public CreatureScript -{ -public: - mob_webbed_creature() : CreatureScript("mob_webbed_creature") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_webbed_creatureAI (creature); - } - - struct mob_webbed_creatureAI : public ScriptedAI - { - mob_webbed_creatureAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - - void EnterCombat(Unit* /*who*/) {} - - void JustDied(Unit* killer) - { - uint32 spawnCreatureID = 0; - - switch (urand(0, 2)) - { - case 0: - spawnCreatureID = 17681; - if (Player* player = killer->ToPlayer()) - player->KilledMonsterCredit(spawnCreatureID, 0); - break; - case 1: - case 2: - spawnCreatureID = possibleSpawns[urand(0, 30)]; - break; - } - - if (spawnCreatureID) - me->SummonCreature(spawnCreatureID, 0.0f, 0.0f, 0.0f, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - } - }; - -}; - -/*###### -## npc_captured_sunhawk_agent -######*/ - -#define C_SUNHAWK_TRIGGER 17974 - -#define GOSSIP_HELLO_CSA "[PH] " -#define GOSSIP_SELECT_CSA1 "[PH] " -#define GOSSIP_SELECT_CSA2 "[PH] " -#define GOSSIP_SELECT_CSA3 "[PH] " -#define GOSSIP_SELECT_CSA4 "[PH] " -#define GOSSIP_SELECT_CSA5 "[PH] " - -class npc_captured_sunhawk_agent : public CreatureScript -{ -public: - npc_captured_sunhawk_agent() : CreatureScript("npc_captured_sunhawk_agent") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(9137, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(9138, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(9139, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(9140, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(9141, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->CLOSE_GOSSIP_MENU(); - player->TalkedToCreature(C_SUNHAWK_TRIGGER, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->HasAura(31609) && player->GetQuestStatus(9756) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_CSA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(9136, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(9134, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## Quest 9667: Saving Princess Stillpine -######*/ - -enum Stillpine -{ - QUEST_SAVING_PRINCESS_STILLPINE = 9667, - NPC_PRINCESS_STILLPINE = 17682, - GO_PRINCESS_STILLPINES_CAGE = 181928, - SPELL_OPENING_PRINCESS_STILLPINE_CREDIT = 31003, - SAY_DIRECTION = 0 -}; - -class go_princess_stillpines_cage : public GameObjectScript -{ -public: - go_princess_stillpines_cage() : GameObjectScript("go_princess_stillpines_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->SetGoState(GO_STATE_READY); - if (Creature* stillpine = go->FindNearestCreature(NPC_PRINCESS_STILLPINE, 25, true)) - { - stillpine->GetMotionMaster()->MovePoint(1, go->GetPositionX(), go->GetPositionY()-15, go->GetPositionZ()); - player->CastedCreatureOrGO(NPC_PRINCESS_STILLPINE, 0, SPELL_OPENING_PRINCESS_STILLPINE_CREDIT); - } - return true; - } -}; - -class npc_princess_stillpine : public CreatureScript -{ -public: - npc_princess_stillpine() : CreatureScript("npc_princess_stillpine") { } - - struct npc_princess_stillpineAI : public ScriptedAI - { - npc_princess_stillpineAI(Creature* creature) : ScriptedAI(creature) {} - - void MovementInform(uint32 type, uint32 id) - { - if (type == POINT_MOTION_TYPE && id == 1) - { - Talk(SAY_DIRECTION); - me->DespawnOrUnsummon(); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_princess_stillpineAI(creature); - } -}; - -void AddSC_bloodmyst_isle() -{ - new mob_webbed_creature(); - new npc_captured_sunhawk_agent(); - new npc_princess_stillpine(); - new go_princess_stillpines_cage(); -} diff --git a/src/server/scripts/Kalimdor/darkshore.cpp b/src/server/scripts/Kalimdor/darkshore.cpp deleted file mode 100644 index 09f061148d3..00000000000 --- a/src/server/scripts/Kalimdor/darkshore.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Darkshore -SD%Complete: 100 -SDComment: Quest support: 731, 2078, 5321 -SDCategory: Darkshore -EndScriptData */ - -/* ContentData -npc_kerlonian -npc_prospector_remtravel -npc_threshwackonator -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" -#include "SpellInfo.h" - -/*#### -# npc_kerlonian -####*/ - -enum Kerlonian -{ - SAY_KER_START = 0, - EMOTE_KER_SLEEP = 1, - SAY_KER_SLEEP = 2, - SAY_KER_ALERT_1 = 3, - SAY_KER_END = 4, - EMOTE_KER_AWAKEN = 5, - - SPELL_SLEEP_VISUAL = 25148, - SPELL_AWAKEN = 17536, - QUEST_SLEEPER_AWAKENED = 5321, - NPC_LILADRIS = 11219, //attackers entries unknown - FACTION_KER_ESCORTEE = 113 -}; - -//TODO: make concept similar as "ringo" -escort. Find a way to run the scripted attacks, _if_ player are choosing road. -class npc_kerlonian : public CreatureScript -{ -public: - npc_kerlonian() : CreatureScript("npc_kerlonian") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_SLEEPER_AWAKENED) - { - if (npc_kerlonianAI* pKerlonianAI = CAST_AI(npc_kerlonian::npc_kerlonianAI, creature->AI())) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_KER_START, player->GetGUID()); - pKerlonianAI->StartFollow(player, FACTION_KER_ESCORTEE, quest); - } - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kerlonianAI(creature); - } - - struct npc_kerlonianAI : public FollowerAI - { - npc_kerlonianAI(Creature* creature) : FollowerAI(creature) { } - - uint32 FallAsleepTimer; - - void Reset() - { - FallAsleepTimer = urand(10000, 45000); - } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_LILADRIS) - { - if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE*5)) - { - if (Player* player = GetLeaderForFollower()) - { - if (player->GetQuestStatus(QUEST_SLEEPER_AWAKENED) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_SLEEPER_AWAKENED, me); - - Talk(SAY_KER_END); - } - - SetFollowComplete(); - } - } - } - - void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) - { - if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_AWAKEN) - ClearSleeping(); - } - - void SetSleeping() - { - SetFollowPaused(true); - - Talk(EMOTE_KER_SLEEP); - - Talk(SAY_KER_SLEEP); - - me->SetStandState(UNIT_STAND_STATE_SLEEP); - DoCast(me, SPELL_SLEEP_VISUAL, false); - } - - void ClearSleeping() - { - me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL); - me->SetStandState(UNIT_STAND_STATE_STAND); - - Talk(EMOTE_KER_AWAKEN); - - SetFollowPaused(false); - } - - void UpdateFollowerAI(const uint32 Diff) - { - if (!UpdateVictim()) - { - if (!HasFollowState(STATE_FOLLOW_INPROGRESS)) - return; - - if (!HasFollowState(STATE_FOLLOW_PAUSED)) - { - if (FallAsleepTimer <= Diff) - { - SetSleeping(); - FallAsleepTimer = urand(25000, 90000); - } - else - FallAsleepTimer -= Diff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*#### -# npc_prospector_remtravel -####*/ - -enum Remtravel -{ - SAY_REM_START = 0, - SAY_REM_AGGRO = 1, - SAY_REM_RAMP1_1 = 2, - SAY_REM_RAMP1_2 = 3, - SAY_REM_BOOK = 4, - SAY_REM_TENT1_1 = 5, - SAY_REM_TENT1_2 = 6, - SAY_REM_MOSS = 7, - EMOTE_REM_MOSS = 8, - SAY_REM_MOSS_PROGRESS = 9, - SAY_REM_PROGRESS = 10, - SAY_REM_REMEMBER = 11, - EMOTE_REM_END = 12, - - FACTION_ESCORTEE = 10, - QUEST_ABSENT_MINDED_PT2 = 731, - NPC_GRAVEL_SCOUT = 2158, - NPC_GRAVEL_BONE = 2159, - NPC_GRAVEL_GEO = 2160 -}; - -class npc_prospector_remtravel : public CreatureScript -{ -public: - npc_prospector_remtravel() : CreatureScript("npc_prospector_remtravel") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_ABSENT_MINDED_PT2) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_remtravel::npc_prospector_remtravelAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID()); - - creature->setFaction(FACTION_ESCORTEE); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_prospector_remtravelAI(creature); - } - - struct npc_prospector_remtravelAI : public npc_escortAI - { - npc_prospector_remtravelAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 0: - Talk(SAY_REM_START, player->GetGUID()); - break; - case 5: - Talk(SAY_REM_RAMP1_1, player->GetGUID()); - break; - case 6: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 9: - Talk(SAY_REM_RAMP1_2, player->GetGUID()); - break; - case 14: - //depend quest rewarded? - Talk(SAY_REM_BOOK, player->GetGUID()); - break; - case 15: - Talk(SAY_REM_TENT1_1, player->GetGUID()); - break; - case 16: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 17: - Talk(SAY_REM_TENT1_2, player->GetGUID()); - break; - case 26: - Talk(SAY_REM_MOSS, player->GetGUID()); - break; - case 27: - Talk(EMOTE_REM_MOSS, player->GetGUID()); - break; - case 28: - Talk(SAY_REM_MOSS_PROGRESS, player->GetGUID()); - break; - case 29: - DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 31: - Talk(SAY_REM_PROGRESS, player->GetGUID()); - break; - case 41: - Talk(SAY_REM_REMEMBER, player->GetGUID()); - break; - case 42: - Talk(EMOTE_REM_END, player->GetGUID()); - player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me); - break; - } - } - } - - void Reset() {} - - void EnterCombat(Unit* who) - { - if (urand(0, 1)) - Talk(SAY_REM_AGGRO, who->GetGUID()); - } - - void JustSummoned(Creature* /*pSummoned*/) - { - //unsure if it should be any - //pSummoned->AI()->AttackStart(me); - } - }; - -}; - -/*#### -# npc_threshwackonator -####*/ - -enum Threshwackonator -{ - EMOTE_START = 0, - SAY_AT_CLOSE = 1, - QUEST_GYROMAST_REV = 2078, - NPC_GELKAK = 6667, - FACTION_HOSTILE = 14 -}; - -#define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key" - -class npc_threshwackonator : public CreatureScript -{ -public: - npc_threshwackonator() : CreatureScript("npc_threshwackonator") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - - if (npc_threshwackonatorAI* pThreshAI = CAST_AI(npc_threshwackonator::npc_threshwackonatorAI, creature->AI())) - { - creature->AI()->Talk(EMOTE_START); - pThreshAI->StartFollow(player); - } - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_GYROMAST_REV) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INSERT_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_threshwackonatorAI(creature); - } - - struct npc_threshwackonatorAI : public FollowerAI - { - npc_threshwackonatorAI(Creature* creature) : FollowerAI(creature) { } - - void Reset() { } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_GELKAK) - { - if (me->IsWithinDistInMap(who, 10.0f)) - { - Talk(SAY_AT_CLOSE, who->GetGUID()); - DoAtEnd(); - } - } - } - - void DoAtEnd() - { - me->setFaction(FACTION_HOSTILE); - - if (Player* pHolder = GetLeaderForFollower()) - me->AI()->AttackStart(pHolder); - - SetFollowComplete(); - } - }; - -}; - -void AddSC_darkshore() -{ - new npc_kerlonian(); - new npc_prospector_remtravel(); - new npc_threshwackonator(); -} diff --git a/src/server/scripts/Kalimdor/desolace.cpp b/src/server/scripts/Kalimdor/desolace.cpp deleted file mode 100644 index 8f55bb6102c..00000000000 --- a/src/server/scripts/Kalimdor/desolace.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Desolace -SD%Complete: 100 -SDComment: Quest support: 5561 -SDCategory: Desolace -EndScriptData */ - -/* ContentData -npc_aged_dying_ancient_kodo -go_iruxos -npc_dalinda_malem -go_demon_portal -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "SpellInfo.h" - -enum DyingKodo -{ - // signed for 9999 - SAY_SMEED_HOME = 0, - - QUEST_KODO = 5561, - - NPC_SMEED = 11596, - NPC_AGED_KODO = 4700, - NPC_DYING_KODO = 4701, - NPC_ANCIENT_KODO = 4702, - NPC_TAMED_KODO = 11627, - - SPELL_KODO_KOMBO_ITEM = 18153, - SPELL_KODO_KOMBO_PLAYER_BUFF = 18172, //spells here have unclear function, but using them at least for visual parts and checks - SPELL_KODO_KOMBO_DESPAWN_BUFF = 18377, - SPELL_KODO_KOMBO_GOSSIP = 18362 - -}; - -class npc_aged_dying_ancient_kodo : public CreatureScript -{ -public: - npc_aged_dying_ancient_kodo() : CreatureScript("npc_aged_dying_ancient_kodo") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) && creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - { - //the expected quest objective - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - - player->RemoveAurasDueToSpell(SPELL_KODO_KOMBO_PLAYER_BUFF); - creature->GetMotionMaster()->MoveIdle(); - } - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool EffectDummyCreature(Unit* pCaster, uint32 spellId, uint32 effIndex, Creature* creatureTarget) - { - //always check spellid and effectindex - if (spellId == SPELL_KODO_KOMBO_ITEM && effIndex == 0) - { - //no effect if player/creature already have aura from spells - if (pCaster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || creatureTarget->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) - return true; - - if (creatureTarget->GetEntry() == NPC_AGED_KODO || - creatureTarget->GetEntry() == NPC_DYING_KODO || - creatureTarget->GetEntry() == NPC_ANCIENT_KODO) - { - pCaster->CastSpell(pCaster, SPELL_KODO_KOMBO_PLAYER_BUFF, true); - - creatureTarget->UpdateEntry(NPC_TAMED_KODO); - creatureTarget->CastSpell(creatureTarget, SPELL_KODO_KOMBO_DESPAWN_BUFF, false); - - if (creatureTarget->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - creatureTarget->GetMotionMaster()->MoveIdle(); - - creatureTarget->GetMotionMaster()->MoveFollow(pCaster, PET_FOLLOW_DIST, creatureTarget->GetFollowAngle()); - } - - //always return true when we are handling this spell and effect - return true; - } - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_aged_dying_ancient_kodoAI(creature); - } - - struct npc_aged_dying_ancient_kodoAI : public ScriptedAI - { - npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { Reset(); } - - uint32 DespawnTimer; - - void Reset() - { - DespawnTimer = 0; - } - - void MoveInLineOfSight(Unit* who) - { - if (who->GetEntry() == NPC_SMEED) - { - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - return; - - if (me->IsWithinDistInMap(who, 10.0f)) - { - if (Creature* talker = who->ToCreature()) - talker->AI()->Talk(SAY_SMEED_HOME); - - //spell have no implemented effect (dummy), so useful to notify spellHit - DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); - } - } - } - - void SpellHit(Unit* /*pCaster*/, SpellInfo const* pSpell) - { - if (pSpell->Id == SPELL_KODO_KOMBO_GOSSIP) - { - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - DespawnTimer = 60000; - } - } - - void UpdateAI(const uint32 diff) - { - //timer should always be == 0 unless we already updated entry of creature. Then not expect this updated to ever be in combat. - if (DespawnTimer && DespawnTimer <= diff) - { - if (!me->getVictim() && me->isAlive()) - { - Reset(); - me->setDeathState(JUST_DIED); - me->Respawn(); - return; - } - } else DespawnTimer -= diff; - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*###### -## go_iruxos -## Hand of Iruxos -######*/ - -enum Iruxos -{ - QUEST_HAND_IRUXOS = 5381, - NPC_DEMON_SPIRIT = 11876, -}; - -class go_iruxos : public GameObjectScript -{ - public: - go_iruxos() : GameObjectScript("go_iruxos") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (player->GetQuestStatus(QUEST_HAND_IRUXOS) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_SPIRIT, 25.0f, true)) - player->SummonCreature(NPC_DEMON_SPIRIT, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - - return true; - } -}; - -/*###### -## npc_dalinda_malem. Quest 1440 -######*/ - -enum Dalinda -{ - QUEST_RETURN_TO_VAHLARRIEL = 1440 -}; - -class npc_dalinda : public CreatureScript -{ -public: - npc_dalinda() : CreatureScript("npc_dalinda") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_RETURN_TO_VAHLARRIEL) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_dalinda::npc_dalindaAI, creature->AI())) - { - pEscortAI->Start(true, false, player->GetGUID()); - creature->setFaction(113); - } - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_dalindaAI(creature); - } - - struct npc_dalindaAI : public npc_escortAI - { - npc_dalindaAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - - switch (waypointId) - { - case 1: - me->IsStandState(); - break; - case 15: - if (player) - player->GroupEventHappens(QUEST_RETURN_TO_VAHLARRIEL, me); - break; - } - } - - void EnterCombat(Unit* /*who*/) { } - - void Reset() {} - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_RETURN_TO_VAHLARRIEL); - return; - } - - void UpdateAI(const uint32 Diff) - { - npc_escortAI::UpdateAI(Diff); - if (!UpdateVictim()) - return; - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## go_demon_portal -######*/ - -enum DemonPortal -{ - NPC_DEMON_GUARDIAN = 11937, - - QUEST_PORTAL_OF_THE_LEGION = 5581, -}; - -class go_demon_portal : public GameObjectScript -{ - public: - go_demon_portal() : GameObjectScript("go_demon_portal") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true)) - { - if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0)) - guardian->AI()->AttackStart(player); - } - - return true; - } -}; - -void AddSC_desolace() -{ - new npc_aged_dying_ancient_kodo(); - new go_iruxos(); - new npc_dalinda(); - new go_demon_portal(); -} diff --git a/src/server/scripts/Kalimdor/durotar.cpp b/src/server/scripts/Kalimdor/durotar.cpp deleted file mode 100644 index fa6b830c1ae..00000000000 --- a/src/server/scripts/Kalimdor/durotar.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Vehicle.h" -#include "SpellScript.h" -#include "Player.h" - -/*###### -##Quest 5441: Lazy Peons -##npc_lazy_peon -######*/ - -enum LazyPeonYells -{ - SAY_SPELL_HIT = 0 -}; - -enum LazyPeon -{ - QUEST_LAZY_PEONS = 5441, - GO_LUMBERPILE = 175784, - SPELL_BUFF_SLEEP = 17743, - SPELL_AWAKEN_PEON = 19938 -}; - -class npc_lazy_peon : public CreatureScript -{ -public: - npc_lazy_peon() : CreatureScript("npc_lazy_peon") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lazy_peonAI(creature); - } - - struct npc_lazy_peonAI : public ScriptedAI - { - npc_lazy_peonAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - - uint32 RebuffTimer; - bool work; - - void Reset() - { - PlayerGUID = 0; - RebuffTimer = 0; - work = false; - } - - void MovementInform(uint32 /*type*/, uint32 id) - { - if (id == 1) - work = true; - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id == SPELL_AWAKEN_PEON && caster->GetTypeId() == TYPEID_PLAYER - && CAST_PLR(caster)->GetQuestStatus(QUEST_LAZY_PEONS) == QUEST_STATUS_INCOMPLETE) - { - caster->ToPlayer()->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - Talk(SAY_SPELL_HIT, caster->GetGUID()); - me->RemoveAllAuras(); - if (GameObject* Lumberpile = me->FindNearestGameObject(GO_LUMBERPILE, 20)) - me->GetMotionMaster()->MovePoint(1, Lumberpile->GetPositionX()-1, Lumberpile->GetPositionY(), Lumberpile->GetPositionZ()); - } - } - - void UpdateAI(const uint32 Diff) - { - if (work == true) - me->HandleEmoteCommand(EMOTE_ONESHOT_WORK_CHOPWOOD); - if (RebuffTimer <= Diff) - { - DoCast(me, SPELL_BUFF_SLEEP); - RebuffTimer = 300000; //Rebuff agian in 5 minutes - } - else - RebuffTimer -= Diff; - if (!UpdateVictim()) - return; - DoMeleeAttackIfReady(); - } - }; -}; - -enum Texts -{ - // Tiger Matriarch Credit - SAY_MATRIARCH_AGGRO = 0, - - // Troll Volunteer - SAY_VOLUNTEER_START = 0, - SAY_VOLUNTEER_END = 1, -}; - -enum Spells -{ - // Tiger Matriarch Credit - SPELL_SUMMON_MATRIARCH = 75187, - SPELL_NO_SUMMON_AURA = 75213, - SPELL_DETECT_INVIS = 75180, - SPELL_SUMMON_ZENTABRA_TRIGGER = 75212, - - // Tiger Matriarch - SPELL_POUNCE = 61184, - SPELL_FURIOUS_BITE = 75164, - SPELL_SUMMON_ZENTABRA = 75181, - SPELL_SPIRIT_OF_THE_TIGER_RIDER = 75166, - SPELL_EJECT_PASSENGERS = 50630, - - // Troll Volunteer - SPELL_VOLUNTEER_AURA = 75076, - SPELL_PETACT_AURA = 74071, - SPELL_QUEST_CREDIT = 75106, - SPELL_MOUNTING_CHECK = 75420, - SPELL_TURNIN = 73953, - SPELL_AOE_TURNIN = 75107, - - // Vol'jin War Drums - SPELL_MOTIVATE_1 = 75088, - SPELL_MOTIVATE_2 = 75086, -}; - -enum Creatures -{ - // Tiger Matriarch Credit - NPC_TIGER_VEHICLE = 40305, - - // Troll Volunteer - NPC_URUZIN = 40253, - NPC_VOLUNTEER_1 = 40264, - NPC_VOLUNTEER_2 = 40260, - - // Vol'jin War Drums - NPC_CITIZEN_1 = 40256, - NPC_CITIZEN_2 = 40257, -}; - -enum Events -{ - // Tiger Matriarch Credit - EVENT_CHECK_SUMMON_AURA = 1, - - // Tiger Matriarch - EVENT_POUNCE = 2, - EVENT_NOSUMMON = 3, -}; - -enum Points -{ - POINT_URUZIN = 4026400, -}; - -class npc_tiger_matriarch_credit : public CreatureScript -{ - public: - npc_tiger_matriarch_credit() : CreatureScript("npc_tiger_matriarch_credit") { } - - struct npc_tiger_matriarch_creditAI : public Scripted_NoMovementAI - { - npc_tiger_matriarch_creditAI(Creature* creature) : Scripted_NoMovementAI(creature) - { - events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 2000); - } - - void UpdateAI(uint32 const diff) - { - events.Update(diff); - - if (events.ExecuteEvent() == EVENT_CHECK_SUMMON_AURA) - { - std::list tigers; - GetCreatureListWithEntryInGrid(tigers, me, NPC_TIGER_VEHICLE, 15.0f); - if (!tigers.empty()) - { - for (std::list::iterator itr = tigers.begin(); itr != tigers.end(); ++itr) - { - if (!(*itr)->isSummon()) - continue; - - if (Unit* summoner = (*itr)->ToTempSummon()->GetSummoner()) - if (!summoner->HasAura(SPELL_NO_SUMMON_AURA) && !summoner->HasAura(SPELL_SUMMON_ZENTABRA_TRIGGER) - && !summoner->isInCombat()) - { - me->AddAura(SPELL_NO_SUMMON_AURA, summoner); - me->AddAura(SPELL_DETECT_INVIS, summoner); - summoner->CastSpell(summoner, SPELL_SUMMON_MATRIARCH, true); - Talk(SAY_MATRIARCH_AGGRO, summoner->GetGUID()); - } - } - } - - events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 5000); - } - } - - private: - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_tiger_matriarch_creditAI(creature); - } -}; - -class npc_tiger_matriarch : public CreatureScript -{ - public: - npc_tiger_matriarch() : CreatureScript("npc_tiger_matriarch") {} - - struct npc_tiger_matriarchAI : public ScriptedAI - { - npc_tiger_matriarchAI(Creature* creature) : ScriptedAI(creature), - _tigerGuid(0) - { - } - - void EnterCombat(Unit* /*target*/) - { - _events.Reset(); - _events.ScheduleEvent(EVENT_POUNCE, 100); - _events.ScheduleEvent(EVENT_NOSUMMON, 50000); - } - - void IsSummonedBy(Unit* summoner) - { - if (summoner->GetTypeId() != TYPEID_PLAYER || !summoner->GetVehicle()) - return; - - _tigerGuid = summoner->GetVehicle()->GetBase()->GetGUID(); - if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid)) - { - me->AddThreat(tiger, 500000.0f); - DoCast(me, SPELL_FURIOUS_BITE); - } - } - - void KilledUnit(Unit* victim) - { - if (victim->GetTypeId() != TYPEID_UNIT || !victim->isSummon()) - return; - - if (Unit* vehSummoner = victim->ToTempSummon()->GetSummoner()) - { - vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA); - vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS); - vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); - vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); - } - me->DespawnOrUnsummon(); - } - - void DamageTaken(Unit* attacker, uint32& damage) - { - if (!attacker->isSummon()) - return; - - if (HealthBelowPct(20)) - { - damage = 0; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (Unit* vehSummoner = attacker->ToTempSummon()->GetSummoner()) - { - vehSummoner->AddAura(SPELL_SUMMON_ZENTABRA_TRIGGER, vehSummoner); - vehSummoner->CastSpell(vehSummoner, SPELL_SUMMON_ZENTABRA, true); - attacker->CastSpell(attacker, SPELL_EJECT_PASSENGERS, true); - vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA); - vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS); - vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); - vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); - } - - me->DespawnOrUnsummon(); - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (!_tigerGuid) - return; - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_POUNCE: - DoCastVictim(SPELL_POUNCE); - _events.ScheduleEvent(EVENT_POUNCE, 30000); - break; - case EVENT_NOSUMMON: // Reapply SPELL_NO_SUMMON_AURA - if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid)) - { - if (tiger->isSummon()) - if (Unit* vehSummoner = tiger->ToTempSummon()->GetSummoner()) - me->AddAura(SPELL_NO_SUMMON_AURA, vehSummoner); - } - _events.ScheduleEvent(EVENT_NOSUMMON, 50000); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap _events; - uint64 _tigerGuid; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_tiger_matriarchAI(creature); - } -}; - -// These models was found in sniff. -// TODO: generalize these models with race from dbc -uint32 const trollmodel[] = -{11665, 11734, 11750, 12037, 12038, 12042, 12049, 12849, 13529, 14759, 15570, 15701, -15702, 1882, 1897, 1976, 2025, 27286, 2734, 2735, 4084, 4085, 4087, 4089, 4231, 4357, -4358, 4360, 4361, 4362, 4363, 4370, 4532, 4537, 4540, 4610, 6839, 7037, 9767, 9768}; - -class npc_troll_volunteer : public CreatureScript -{ - public: - npc_troll_volunteer() : CreatureScript("npc_troll_volunteer") { } - - struct npc_troll_volunteerAI : public ScriptedAI - { - npc_troll_volunteerAI(Creature* creature) : ScriptedAI(creature) - { - } - - void InitializeAI() - { - if (me->isDead() || !me->GetOwner()) - return; - - Reset(); - - switch (urand(0, 3)) - { - case 0: - _mountModel = 6471; - break; - case 1: - _mountModel = 6473; - break; - case 2: - _mountModel = 6469; - break; - default: - _mountModel = 6472; - break; - } - me->SetDisplayId(trollmodel[urand(0, 39)]); - if (Player* player = me->GetOwner()->ToPlayer()) - me->GetMotionMaster()->MoveFollow(player, 5.0f, float(rand_norm() + 1.0f) * M_PI / 3.0f * 4.0f); - } - - void Reset() - { - _complete = false; - me->AddAura(SPELL_VOLUNTEER_AURA, me); - me->AddAura(SPELL_MOUNTING_CHECK, me); - DoCast(me, SPELL_PETACT_AURA); - me->SetReactState(REACT_PASSIVE); - Talk(SAY_VOLUNTEER_START); - } - - // This is needed for mount check aura to know what mountmodel the npc got stored - uint32 GetMountId() - { - return _mountModel; - } - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - if (id == POINT_URUZIN) - me->DespawnOrUnsummon(); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) - { - if (spell->Id == SPELL_AOE_TURNIN && caster->GetEntry() == NPC_URUZIN && !_complete) - { - _complete = true; // Preventing from giving credit twice - DoCast(me, SPELL_TURNIN); - DoCast(me, SPELL_QUEST_CREDIT); - me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK); - me->Dismount(); - Talk(SAY_VOLUNTEER_END); - me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); - } - } - - private: - uint32 _mountModel; - bool _complete; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_troll_volunteerAI(creature); - } -}; - -typedef npc_troll_volunteer::npc_troll_volunteerAI VolunteerAI; - -class spell_mount_check : public SpellScriptLoader -{ - public: - spell_mount_check() : SpellScriptLoader("spell_mount_check") {} - - class spell_mount_check_AuraScript : public AuraScript - { - PrepareAuraScript(spell_mount_check_AuraScript) - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTING_CHECK)) - return false; - return true; - } - - void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) - { - Unit* target = GetTarget(); - Unit* owner = target->GetOwner(); - - if (!owner) - return; - - if (owner->IsMounted() && !target->IsMounted()) - { - if (VolunteerAI* volunteerAI = CAST_AI(VolunteerAI, target->GetAI())) - target->Mount(volunteerAI->GetMountId()); - } - else if (!owner->IsMounted() && target->IsMounted()) - target->Dismount(); - - target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); - target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); - } - - void Register() - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_mount_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; - - AuraScript* GetAuraScript() const - { - return new spell_mount_check_AuraScript(); - } -}; - -class spell_voljin_war_drums : public SpellScriptLoader -{ - public: - spell_voljin_war_drums() : SpellScriptLoader("spell_voljin_war_drums") {} - - class spell_voljin_war_drums_SpellScript : public SpellScript - { - PrepareSpellScript(spell_voljin_war_drums_SpellScript) - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_1)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_2)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* caster = GetCaster(); - if (Unit* target = GetHitUnit()) - { - uint32 motivate = 0; - if (target->GetEntry() == NPC_CITIZEN_1) - motivate = SPELL_MOTIVATE_1; - else if (target->GetEntry() == NPC_CITIZEN_2) - motivate = SPELL_MOTIVATE_2; - if (motivate) - caster->CastSpell(target, motivate, false); - } - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_voljin_war_drums_SpellScript(); - } -}; - -enum VoodooSpells -{ - SPELL_BREW = 16712, // Special Brew - SPELL_GHOSTLY = 16713, // Ghostly - SPELL_HEX1 = 16707, // Hex - SPELL_HEX2 = 16708, // Hex - SPELL_HEX3 = 16709, // Hex - SPELL_GROW = 16711, // Grow - SPELL_LAUNCH = 16716, // Launch (Whee!) -}; - -// 17009 -class spell_voodoo : public SpellScriptLoader -{ - public: - spell_voodoo() : SpellScriptLoader("spell_voodoo") {} - - class spell_voodoo_SpellScript : public SpellScript - { - PrepareSpellScript(spell_voodoo_SpellScript) - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_BREW) || !sSpellMgr->GetSpellInfo(SPELL_GHOSTLY) || - !sSpellMgr->GetSpellInfo(SPELL_HEX1) || !sSpellMgr->GetSpellInfo(SPELL_HEX2) || - !sSpellMgr->GetSpellInfo(SPELL_HEX3) || !sSpellMgr->GetSpellInfo(SPELL_GROW) || - !sSpellMgr->GetSpellInfo(SPELL_LAUNCH)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - uint32 spellid = RAND(SPELL_BREW, SPELL_GHOSTLY, RAND(SPELL_HEX1, SPELL_HEX2, SPELL_HEX3), SPELL_GROW, SPELL_LAUNCH); - if (Unit* target = GetHitUnit()) - GetCaster()->CastSpell(target, spellid, false); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_voodoo_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_voodoo_SpellScript(); - } -}; - -void AddSC_durotar() -{ - new npc_lazy_peon(); - new npc_tiger_matriarch_credit(); - new npc_tiger_matriarch(); - new npc_troll_volunteer(); - new spell_mount_check(); - new spell_voljin_war_drums(); - new spell_voodoo(); -} diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp deleted file mode 100644 index 37941227c78..00000000000 --- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Dustwallow_Marsh -SD%Complete: 95 -SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle -SDCategory: Dustwallow Marsh -EndScriptData */ - -/* ContentData -mobs_risen_husk_spirit -npc_lady_jaina_proudmoore -npc_nat_pagle -npc_private_hendel -npc_cassa_crimsonwing - handled by npc_taxi -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" -#include "SpellScript.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## mobs_risen_husk_spirit -######*/ - -enum HauntingWitchHill -{ - // Quest - QUEST_WHATS_HAUNTING_WITCH_HILL = 11180, - - // General spells - SPELL_SUMMON_RESTLESS_APPARITION = 42511, - SPELL_WITCH_HILL_INFORMATION_CREDIT = 42512, - - // Risen Husk specific - SPELL_CONSUME_FLESH = 37933, - NPC_RISEN_HUSK = 23555, - - // Risen Spirit specific - SPELL_INTANGIBLE_PRESENCE = 43127, - NPC_RISEN_SPIRIT = 23554, - - // Events - EVENT_CONSUME_FLESH = 0, - EVENT_INTANGIBLE_PRESENCE = 1, -}; - -class mobs_risen_husk_spirit : public CreatureScript -{ - public: - mobs_risen_husk_spirit() : CreatureScript("mobs_risen_husk_spirit") { } - - struct mobs_risen_husk_spiritAI : public ScriptedAI - { - mobs_risen_husk_spiritAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() - { - events.Reset(); - if (me->GetEntry() == NPC_RISEN_HUSK) - events.ScheduleEvent(EVENT_CONSUME_FLESH, 5000); - else if (me->GetEntry() == NPC_RISEN_SPIRIT) - events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 5000); - } - - void JustDied(Unit* killer) - { - if (killer->GetTypeId() == TYPEID_PLAYER) - { - if (killer->ToPlayer()->GetQuestStatus(QUEST_WHATS_HAUNTING_WITCH_HILL) == QUEST_STATUS_INCOMPLETE) - { - DoCast(me, SPELL_SUMMON_RESTLESS_APPARITION, true); - DoCast(killer, SPELL_WITCH_HILL_INFORMATION_CREDIT, true); - } - } - } - - void UpdateAI(uint32 const diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CONSUME_FLESH: - DoCastVictim(SPELL_CONSUME_FLESH); - events.ScheduleEvent(EVENT_CONSUME_FLESH, 15000); - break; - case EVENT_INTANGIBLE_PRESENCE: - DoCastVictim(SPELL_INTANGIBLE_PRESENCE); - events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 15000); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mobs_risen_husk_spiritAI (creature); - } -}; - -/*###### -## npc_theramor_guard -######*/ - -enum TheramoreGuard -{ - QUEST_DISCREDITING_THE_DESERTERS = 11133, - - NPC_THERAMORE_GUARD = 4979, - - SPELL_DOCTORED_LEAFLET = 42725, - SPELL_PROPAGANDIZED = 42246, - - SAY_QUEST1 = 0, - SAY_QUEST2 = 1, - SAY_QUEST3 = 2 -}; - -#define GOSSIP_ITEM_THERAMORE_GUARD "You look like an intelligent person. Why don't you read one of these leaflets and give it some thought?" - -class npc_theramore_guard : public CreatureScript -{ -public: - npc_theramore_guard() : CreatureScript("npc_theramore_guard") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_DISCREDITING_THE_DESERTERS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THERAMORE_GUARD, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - - if (action == GOSSIP_SENDER_INFO) - { - player->CLOSE_GOSSIP_MENU(); - player->KilledMonsterCredit(NPC_THERAMORE_GUARD, 0); - creature->AI()->Talk(SAY_QUEST1); - creature->CastSpell(creature, SPELL_DOCTORED_LEAFLET, false); - creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->YellTimer = 4000; - CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->bYellTimer = true; - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_theramore_guardAI(creature); - } - - struct npc_theramore_guardAI : public ScriptedAI - { - npc_theramore_guardAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 YellTimer; - uint32 Step; - bool bYellTimer; - - void Reset() - { - bYellTimer = false; - Step = 0; - } - - void UpdateAI(const uint32 Diff) - { - if (!me->HasAura(SPELL_PROPAGANDIZED)) - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - if (bYellTimer && YellTimer <= Diff) - { - switch (Step) - { - case 0: - Talk(SAY_QUEST2); - YellTimer = 3000; - ++Step; - break; - case 1: - Talk(SAY_QUEST3); - me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); - Step = 0; - bYellTimer = false; - break; - } - } - else - YellTimer -= Diff; - } - }; -}; - -/*###### -## npc_lady_jaina_proudmoore -######*/ - -enum LadyJaina -{ - QUEST_JAINAS_AUTOGRAPH = 558, - SPELL_JAINAS_AUTOGRAPH = 23122 -}; - -#define GOSSIP_ITEM_JAINA "I know this is rather silly but i have a young ward who is a bit shy and would like your autograph." - -class npc_lady_jaina_proudmoore : public CreatureScript -{ -public: - npc_lady_jaina_proudmoore() : CreatureScript("npc_lady_jaina_proudmoore") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_SENDER_INFO) - { - player->SEND_GOSSIP_MENU(7012, creature->GetGUID()); - player->CastSpell(player, SPELL_JAINAS_AUTOGRAPH, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_JAINAS_AUTOGRAPH) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_JAINA, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_nat_pagle -######*/ - -enum NatPagle -{ - QUEST_NATS_MEASURING_TAPE = 8227 -}; - -class npc_nat_pagle : public CreatureScript -{ -public: - npc_nat_pagle() : CreatureScript("npc_nat_pagle") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor() && player->GetQuestRewardStatus(QUEST_NATS_MEASURING_TAPE)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(7640, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(7638, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_private_hendel -######*/ - -enum Hendel -{ - SAY_PROGRESS_1_TER = 0, - SAY_PROGRESS_2_HEN = 1, - SAY_PROGRESS_3_TER = 2, - SAY_PROGRESS_4_TER = 3, - EMOTE_SURRENDER = 4, - - QUEST_MISSING_DIPLO_PT16 = 1324, - FACTION_HOSTILE = 168, //guessed, may be different - - NPC_SENTRY = 5184, //helps hendel - NPC_JAINA = 4968, //appears once hendel gives up - NPC_TERVOSH = 4967 -}; - -//TODO: develop this further, end event not created -class npc_private_hendel : public CreatureScript -{ -public: - npc_private_hendel() : CreatureScript("npc_private_hendel") { } - - bool OnQuestAccept(Player* /*player*/, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT16) - creature->setFaction(FACTION_HOSTILE); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_private_hendelAI(creature); - } - - struct npc_private_hendelAI : public ScriptedAI - { - npc_private_hendelAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() - { - me->RestoreFaction(); - } - - void AttackedBy(Unit* pAttacker) - { - if (me->getVictim()) - return; - - if (me->IsFriendlyTo(pAttacker)) - return; - - AttackStart(pAttacker); - } - - void DamageTaken(Unit* pDoneBy, uint32 &Damage) - { - if (Damage > me->GetHealth() || me->HealthBelowPctDamaged(20, Damage)) - { - Damage = 0; - - if (Player* player = pDoneBy->GetCharmerOrOwnerPlayerOrPlayerItself()) - player->GroupEventHappens(QUEST_MISSING_DIPLO_PT16, me); - - Talk(EMOTE_SURRENDER); - EnterEvadeMode(); - } - } - }; - -}; - -/*###### -## npc_zelfrax -######*/ - -Position const MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f}; - -enum Zelfrax -{ - SAY_ZELFRAX1 = 0, - SAY_ZELFRAX2 = 1 -}; - -class npc_zelfrax : public CreatureScript -{ -public: - npc_zelfrax() : CreatureScript("npc_zelfrax") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_zelfraxAI(creature); - } - - struct npc_zelfraxAI : public ScriptedAI - { - npc_zelfraxAI(Creature* creature) : ScriptedAI(creature) - { - MoveToDock(); - } - - void AttackStart(Unit* who) - { - if (!who) - return; - - if (me->Attack(who, true)) - { - me->SetInCombatWith(who); - who->SetInCombatWith(me); - - if (IsCombatMovementAllowed()) - me->GetMotionMaster()->MoveChase(who); - } - } - - void MovementInform(uint32 Type, uint32 /*Id*/) - { - if (Type != POINT_MOTION_TYPE) - return; - - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - SetCombatMovement(true); - - if (me->isInCombat()) - if (Unit* unit = me->getVictim()) - me->GetMotionMaster()->MoveChase(unit); - } - - void MoveToDock() - { - SetCombatMovement(false); - me->GetMotionMaster()->MovePoint(0, MovePosition); - Talk(SAY_ZELFRAX1); - Talk(SAY_ZELFRAX2); - } - - void UpdateAI(uint32 const /*Diff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*###### -## npc_stinky -######*/ - -enum Stinky -{ - QUEST_STINKYS_ESCAPE_H = 1270, - QUEST_STINKYS_ESCAPE_A = 1222, - SAY_QUEST_ACCEPTED = 0, - SAY_STAY_1 = 1, - SAY_STAY_2 = 2, - SAY_STAY_3 = 3, - SAY_STAY_4 = 4, - SAY_STAY_5 = 5, - SAY_STAY_6 = 6, - SAY_QUEST_COMPLETE = 7, - SAY_ATTACKED_1 = 8, - EMOTE_DISAPPEAR = 9 -}; - -class npc_stinky : public CreatureScript -{ -public: - npc_stinky() : CreatureScript("npc_stinky") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_stinkyAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_STINKYS_ESCAPE_H || quest->GetQuestId() == QUEST_STINKYS_ESCAPE_A) - { - if (npc_stinkyAI* pEscortAI = CAST_AI(npc_stinky::npc_stinkyAI, creature->AI())) - { - creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE); - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_QUEST_ACCEPTED); - pEscortAI->Start(false, false, player->GetGUID()); - } - } - return true; - } - - struct npc_stinkyAI : public npc_escortAI - { - npc_stinkyAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 7: - Talk(SAY_STAY_1, player->GetGUID()); - break; - case 11: - Talk(SAY_STAY_2, player->GetGUID()); - break; - case 25: - Talk(SAY_STAY_3, player->GetGUID()); - break; - case 26: - Talk(SAY_STAY_4, player->GetGUID()); - break; - case 27: - Talk(SAY_STAY_5, player->GetGUID()); - break; - case 28: - Talk(SAY_STAY_6, player->GetGUID()); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - break; - case 29: - me->SetStandState(UNIT_STAND_STATE_STAND); - break; - case 37: - Talk(SAY_QUEST_COMPLETE, player->GetGUID()); - me->SetSpeed(MOVE_RUN, 1.2f, true); - me->SetWalk(false); - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H)) - player->GroupEventHappens(QUEST_STINKYS_ESCAPE_H, me); - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A)) - player->GroupEventHappens(QUEST_STINKYS_ESCAPE_A, me); - break; - case 39: - Talk(EMOTE_DISAPPEAR); - break; - } - } - - void EnterCombat(Unit* who) - { - Talk(SAY_ATTACKED_1, who->GetGUID()); - } - - void Reset() {} - - void JustDied(Unit* /*killer*/) - { - Player* player = GetPlayerForEscort(); - if (player && HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H)) - player->FailQuest(QUEST_STINKYS_ESCAPE_H); - - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A)) - player->FailQuest(QUEST_STINKYS_ESCAPE_A); - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -enum SpellScripts -{ - SPELL_OOZE_ZAP = 42489, - SPELL_OOZE_ZAP_CHANNEL_END = 42485, - SPELL_OOZE_CHANNEL_CREDIT = 42486, - SPELL_ENERGIZED = 42492, -}; - -class spell_ooze_zap : public SpellScriptLoader -{ - public: - spell_ooze_zap() : SpellScriptLoader("spell_ooze_zap") { } - - class spell_ooze_zap_SpellScript : public SpellScript - { - PrepareSpellScript(spell_ooze_zap_SpellScript); - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP)) - return false; - return true; - } - - SpellCastResult CheckRequirement() - { - if (!GetCaster()->HasAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue())) - return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; // This is actually correct - - if (!GetExplTargetUnit()) - return SPELL_FAILED_BAD_TARGETS; - - return SPELL_CAST_OK; - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (GetHitUnit()) - GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - OnCheckCast += SpellCheckCastFn(spell_ooze_zap_SpellScript::CheckRequirement); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_ooze_zap_SpellScript(); - } -}; - -class spell_ooze_zap_channel_end : public SpellScriptLoader -{ - public: - spell_ooze_zap_channel_end() : SpellScriptLoader("spell_ooze_zap_channel_end") { } - - class spell_ooze_zap_channel_end_SpellScript : public SpellScript - { - PrepareSpellScript(spell_ooze_zap_channel_end_SpellScript); - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP_CHANNEL_END)) - return false; - return true; - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - if (Player* player = GetCaster()->ToPlayer()) - player->CastSpell(player, SPELL_OOZE_CHANNEL_CREDIT, true); - GetHitUnit()->Kill(GetHitUnit()); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_channel_end_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_ooze_zap_channel_end_SpellScript(); - } -}; - -class spell_energize_aoe : public SpellScriptLoader -{ - public: - spell_energize_aoe() : SpellScriptLoader("spell_energize_aoe") { } - - class spell_energize_aoe_SpellScript : public SpellScript - { - PrepareSpellScript(spell_energize_aoe_SpellScript); - - bool Validate(SpellInfo const* /*spellEntry*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_ENERGIZED)) - return false; - return true; - } - - void FilterTargets(std::list& targets) - { - for (std::list::iterator itr = targets.begin(); itr != targets.end();) - { - if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE) - ++itr; - else - targets.erase(itr++); - } - targets.push_back(GetCaster()); - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_energize_aoe_SpellScript(); - } -}; - -/*###### -## go_blackhoof_cage -######*/ - -enum PrisonersOfTheGrimTotems -{ - NPC_THERAMORE_PRISONER = 23720, - SAY_FREE = 0, -}; - -class go_blackhoof_cage : public GameObjectScript -{ -public: - go_blackhoof_cage() : GameObjectScript("go_blackhoof_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - if (Creature* prisoner = go->FindNearestCreature(NPC_THERAMORE_PRISONER, 1.0f)) - { - if (player) - player->KilledMonsterCredit(NPC_THERAMORE_PRISONER, 0); - - prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote) - prisoner->DespawnOrUnsummon(6000); - } - return true; - } -}; - -void AddSC_dustwallow_marsh() -{ - new mobs_risen_husk_spirit(); - new npc_lady_jaina_proudmoore(); - new npc_nat_pagle(); - new npc_private_hendel(); - new npc_zelfrax(); - new npc_stinky(); - new npc_theramore_guard(); - new spell_ooze_zap(); - new spell_ooze_zap_channel_end(); - new spell_energize_aoe(); - new go_blackhoof_cage(); -} diff --git a/src/server/scripts/Kalimdor/felwood.cpp b/src/server/scripts/Kalimdor/felwood.cpp deleted file mode 100644 index e23eaa961bb..00000000000 --- a/src/server/scripts/Kalimdor/felwood.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Felwood -SD%Complete: 95 -SDComment: Quest support: 4101, 4102 -SDCategory: Felwood -EndScriptData */ - -/* ContentData -npcs_riverbreeze_and_silversky -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npcs_riverbreeze_and_silversky -######*/ - -#define GOSSIP_ITEM_BEACON "Please make me a Cenarion Beacon" - -enum RiverbreezeAndSilversky -{ - SPELL_CENARION_BEACON = 15120, - - NPC_ARATHANDRIS_SILVERSKY = 9528, - NPC_MAYBESS_RIVERBREEZE = 9529, - - QUEST_CLEASING_FELWOOD_A = 4101, - QUEST_CLEASING_FELWOOD_H = 4102 -}; - -class npcs_riverbreeze_and_silversky : public CreatureScript -{ -public: - npcs_riverbreeze_and_silversky() : CreatureScript("npcs_riverbreeze_and_silversky") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_CENARION_BEACON, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - uint32 creatureId = creature->GetEntry(); - - if (creatureId == NPC_ARATHANDRIS_SILVERSKY) - { - if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_A)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(2848, creature->GetGUID()); - } else if (player->GetTeam() == HORDE) - player->SEND_GOSSIP_MENU(2845, creature->GetGUID()); - else - player->SEND_GOSSIP_MENU(2844, creature->GetGUID()); - } - - if (creatureId == NPC_MAYBESS_RIVERBREEZE) - { - if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_H)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(2849, creature->GetGUID()); - } else if (player->GetTeam() == ALLIANCE) - player->SEND_GOSSIP_MENU(2843, creature->GetGUID()); - else - player->SEND_GOSSIP_MENU(2842, creature->GetGUID()); - } - - return true; - } -}; - -void AddSC_felwood() -{ - new npcs_riverbreeze_and_silversky(); -} diff --git a/src/server/scripts/Kalimdor/feralas.cpp b/src/server/scripts/Kalimdor/feralas.cpp deleted file mode 100644 index b2326de86ab..00000000000 --- a/src/server/scripts/Kalimdor/feralas.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Feralas -SD%Complete: 100 -SDComment: Quest support: 3520, 2767, Special vendor Gregan Brewspewer -SDCategory: Feralas -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" -#include "SpellScript.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_gregan_brewspewer -######*/ - -#define GOSSIP_HELLO "Buy somethin', will ya?" - -class npc_gregan_brewspewer : public CreatureScript -{ -public: - npc_gregan_brewspewer() : CreatureScript("npc_gregan_brewspewer") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(2434, creature->GetGUID()); - } - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor() && player->GetQuestStatus(3909) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(2433, creature->GetGUID()); - return true; - } - -}; - -/*###### -## npc_oox22fe -######*/ - -enum OOX -{ - SAY_OOX_START = 0, - SAY_OOX_AGGRO = 1, - SAY_OOX_AMBUSH = 2, - SAY_OOX_END = 3, - - NPC_YETI = 7848, - NPC_GORILLA = 5260, - NPC_WOODPAW_REAVER = 5255, - NPC_WOODPAW_BRUTE = 5253, - NPC_WOODPAW_ALPHA = 5258, - NPC_WOODPAW_MYSTIC = 5254, - - QUEST_RESCUE_OOX22FE = 2767, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775 -}; - -class npc_oox22fe : public CreatureScript -{ -public: - npc_oox22fe() : CreatureScript("npc_oox22fe") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_RESCUE_OOX22FE) - { - creature->AI()->Talk(SAY_OOX_START); - //change that the npc is not lying dead on the ground - creature->SetStandState(UNIT_STAND_STATE_STAND); - - if (player->GetTeam() == ALLIANCE) - creature->setFaction(FACTION_ESCORTEE_A); - - if (player->GetTeam() == HORDE) - creature->setFaction(FACTION_ESCORTEE_H); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_oox22fe::npc_oox22feAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_oox22feAI(creature); - } - - struct npc_oox22feAI : public npc_escortAI - { - npc_oox22feAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - // First Ambush(3 Yetis) - case 11: - Talk(SAY_OOX_AMBUSH); - me->SummonCreature(NPC_YETI, -4841.01f, 1593.91f, 73.42f, 3.98f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_YETI, -4837.61f, 1568.58f, 78.21f, 3.13f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_YETI, -4841.89f, 1569.95f, 76.53f, 0.68f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - break; - //Second Ambush(3 Gorillas) - case 21: - Talk(SAY_OOX_AMBUSH); - me->SummonCreature(NPC_GORILLA, -4595.81f, 2005.99f, 53.08f, 3.74f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_GORILLA, -4597.53f, 2008.31f, 52.70f, 3.78f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_GORILLA, -4599.37f, 2010.59f, 52.77f, 3.84f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - break; - //Third Ambush(4 Gnolls) - case 30: - Talk(SAY_OOX_AMBUSH); - me->SummonCreature(NPC_WOODPAW_REAVER, -4425.14f, 2075.87f, 47.77f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_WOODPAW_BRUTE, -4426.68f, 2077.98f, 47.57f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_WOODPAW_MYSTIC, -4428.33f, 2080.24f, 47.43f, 3.87f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(NPC_WOODPAW_ALPHA, -4430.04f, 2075.54f, 46.83f, 3.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - break; - case 37: - Talk(SAY_OOX_END); - // Award quest credit - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_RESCUE_OOX22FE, me); - break; - } - } - - void Reset() - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - me->SetStandState(UNIT_STAND_STATE_DEAD); - } - - void EnterCombat(Unit* /*who*/) - { - //For an small probability the npc says something when he get aggro - if (urand(0, 9) > 7) - Talk(SAY_OOX_AGGRO); - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - }; - -}; - -/*###### -## npc_screecher_spirit -######*/ - -class npc_screecher_spirit : public CreatureScript -{ -public: - npc_screecher_spirit() : CreatureScript("npc_screecher_spirit") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - player->SEND_GOSSIP_MENU(2039, creature->GetGUID()); - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - return true; - } - -}; - -enum GordunniTrap -{ - GO_GORDUNNI_DIRT_MOUND = 144064, -}; - -class spell_gordunni_trap : public SpellScriptLoader -{ - public: - spell_gordunni_trap() : SpellScriptLoader("spell_gordunni_trap") { } - - class spell_gordunni_trap_SpellScript : public SpellScript - { - PrepareSpellScript(spell_gordunni_trap_SpellScript); - - void HandleDummy() - { - if (Unit* caster = GetCaster()) - if (GameObject* chest = caster->SummonGameObject(GO_GORDUNNI_DIRT_MOUND, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) - chest->SetSpellId(GetSpellInfo()->Id); - } - - void Register() - { - OnCast += SpellCastFn(spell_gordunni_trap_SpellScript::HandleDummy); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_gordunni_trap_SpellScript(); - } -}; - -/*###### -## AddSC -######*/ - -void AddSC_feralas() -{ - new npc_gregan_brewspewer(); - new npc_oox22fe(); - new npc_screecher_spirit(); - new spell_gordunni_trap(); -} diff --git a/src/server/scripts/Kalimdor/moonglade.cpp b/src/server/scripts/Kalimdor/moonglade.cpp deleted file mode 100644 index e41ffae03e6..00000000000 --- a/src/server/scripts/Kalimdor/moonglade.cpp +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Moonglade -SD%Complete: 100 -SDComment: Quest support: 30, 272, 5929, 5930, 10965. Special Flight Paths for Druid class. -SDCategory: Moonglade -EndScriptData */ - -/* ContentData -npc_bunthen_plainswind -npc_great_bear_spirit -npc_silva_filnaveth -npc_clintar_spirit -npc_clintar_dreamwalker -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "SpellInfo.h" -#include "Cell.h" -#include "CellImpl.h" -#include "GridNotifiers.h" - -/*###### -## npc_bunthen_plainswind -######*/ - -enum Bunthen -{ - QUEST_SEA_LION_HORDE = 30, - QUEST_SEA_LION_ALLY = 272, - TAXI_PATH_ID_ALLY = 315, - TAXI_PATH_ID_HORDE = 316 -}; - -#define GOSSIP_ITEM_THUNDER "I'd like to fly to Thunder Bluff." -#define GOSSIP_ITEM_AQ_END "Do you know where I can find Half Pendant of Aquatic Endurance?" - -class npc_bunthen_plainswind : public CreatureScript -{ -public: - npc_bunthen_plainswind() : CreatureScript("npc_bunthen_plainswind") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CLOSE_GOSSIP_MENU(); - if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) - player->ActivateTaxiPathTo(TAXI_PATH_ID_HORDE); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->SEND_GOSSIP_MENU(5373, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(5376, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->getClass() != CLASS_DRUID) - player->SEND_GOSSIP_MENU(4916, creature->GetGUID()); - else if (player->GetTeam() != HORDE) - { - if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - player->SEND_GOSSIP_MENU(4917, creature->GetGUID()); - } - else if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THUNDER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - player->SEND_GOSSIP_MENU(4918, creature->GetGUID()); - } - return true; - } - -}; - -/*###### -## npc_great_bear_spirit -######*/ - -#define GOSSIP_BEAR1 "What do you represent, spirit?" -#define GOSSIP_BEAR2 "I seek to understand the importance of strength of the body." -#define GOSSIP_BEAR3 "I seek to understand the importance of strength of the heart." -#define GOSSIP_BEAR4 "I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw." - -class npc_great_bear_spirit : public CreatureScript -{ -public: - npc_great_bear_spirit() : CreatureScript("npc_great_bear_spirit") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(4721, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(4733, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(4734, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(4735, creature->GetGUID()); - if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(5929); - if (player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(5930); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - //ally or horde quest - if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(4719, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(4718, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_silva_filnaveth -######*/ - -#define GOSSIP_ITEM_RUTHERAN "I'd like to fly to Rut'theran Village." -#define GOSSIP_ITEM_AQ_AGI "Do you know where I can find Half Pendant of Aquatic Agility?" - -class npc_silva_filnaveth : public CreatureScript -{ -public: - npc_silva_filnaveth() : CreatureScript("npc_silva_filnaveth") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CLOSE_GOSSIP_MENU(); - if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) - player->ActivateTaxiPathTo(TAXI_PATH_ID_ALLY); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->SEND_GOSSIP_MENU(5374, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->SEND_GOSSIP_MENU(5375, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->getClass() != CLASS_DRUID) - player->SEND_GOSSIP_MENU(4913, creature->GetGUID()); - else if (player->GetTeam() != ALLIANCE) - { - if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - player->SEND_GOSSIP_MENU(4915, creature->GetGUID()); - } - else if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RUTHERAN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - player->SEND_GOSSIP_MENU(4914, creature->GetGUID()); - } - return true; - } - -}; - -/*###### -## npc_clintar_spirit -######*/ - -float const Clintar_spirit_WP[41][5] = -{ - //pos_x pos_y pos_z orien waitTime - {7465.28f, -3115.46f, 439.327f, 0.83f, 4000}, - {7476.49f, -3101, 443.457f, 0.89f, 0}, - {7486.57f, -3085.59f, 439.478f, 1.07f, 0}, - {7472.19f, -3085.06f, 443.142f, 3.07f, 0}, - {7456.92f, -3085.91f, 438.862f, 3.24f, 0}, - {7446.68f, -3083.43f, 438.245f, 2.40f, 0}, - {7446.17f, -3080.21f, 439.826f, 1.10f, 6000}, - {7452.41f, -3085.8f, 438.984f, 5.78f, 0}, - {7469.11f, -3084.94f, 443.048f, 6.25f, 0}, - {7483.79f, -3085.44f, 439.607f, 6.25f, 0}, - {7491.14f, -3090.96f, 439.983f, 5.44f, 0}, - {7497.62f, -3098.22f, 436.854f, 5.44f, 0}, - {7498.72f, -3113.41f, 434.596f, 4.84f, 0}, - {7500.06f, -3122.51f, 434.749f, 5.17f, 0}, - {7504.96f, -3131.53f, 434.475f, 4.74f, 0}, - {7504.31f, -3133.53f, 435.693f, 3.84f, 6000}, - {7504.55f, -3133.27f, 435.476f, 0.68f, 15000}, - {7501.99f, -3126.01f, 434.93f, 1.83f, 0}, - {7490.76f, -3114.97f, 434.431f, 2.51f, 0}, - {7479.64f, -3105.51f, 431.123f, 1.83f, 0}, - {7474.63f, -3086.59f, 428.994f, 1.83f, 2000}, - {7472.96f, -3074.18f, 427.566f, 1.57f, 0}, - {7472.25f, -3063, 428.268f, 1.55f, 0}, - {7473.46f, -3054.22f, 427.588f, 0.36f, 0}, - {7475.08f, -3053.6f, 428.653f, 0.36f, 6000}, - {7474.66f, -3053.56f, 428.433f, 3.19f, 4000}, - {7471.81f, -3058.84f, 427.073f, 4.29f, 0}, - {7472.16f, -3064.91f, 427.772f, 4.95f, 0}, - {7471.56f, -3085.36f, 428.924f, 4.72f, 0}, - {7473.56f, -3093.48f, 429.294f, 5.04f, 0}, - {7478.94f, -3104.29f, 430.638f, 5.23f, 0}, - {7484.46f, -3109.61f, 432.769f, 5.79f, 0}, - {7490.23f, -3111.08f, 434.431f, 0.02f, 0}, - {7496.29f, -3108, 434.783f, 1.15f, 0}, - {7497.46f, -3100.66f, 436.191f, 1.50f, 0}, - {7495.64f, -3093.39f, 438.349f, 2.10f, 0}, - {7492.44f, -3086.01f, 440.267f, 1.38f, 0}, - {7498.26f, -3076.44f, 440.808f, 0.71f, 0}, - {7506.4f, -3067.35f, 443.64f, 0.77f, 0}, - {7518.37f, -3057.42f, 445.584f, 0.74f, 0}, - {7517.51f, -3056.3f, 444.568f, 2.49f, 4500} -}; - -Position const AspectRavenSummon = {7472.96f, -3074.18f, 427.566f, 0.0f}; -Position const ClintarSpiritSummon = {7459.2275f, -3122.5632f, 438.9842f, 0.8594f}; - -enum ClintarSpirit -{ - ASPECT_RAVEN = 22915, - - // Texts for EnterCombat, the event and the end of the event are missing - CLINTAR_SPIRIT_SAY_START = 0, -}; - -class npc_clintar_spirit : public CreatureScript -{ -public: - npc_clintar_spirit() : CreatureScript("npc_clintar_spirit") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_clintar_spiritAI (creature); - } - - struct npc_clintar_spiritAI : public npc_escortAI - { - public: - npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature) - { - PlayerGUID = 0; - } - - uint8 Step; - uint32 CurrWP; - uint32 EventTimer; - uint32 checkPlayerTimer; - - uint64 PlayerGUID; - - bool EventOnWait; - - void Reset() - { - if (!PlayerGUID) - { - Step = 0; - CurrWP = 0; - EventTimer = 0; - PlayerGUID = 0; - checkPlayerTimer = 1000; - EventOnWait = false; - } - } - - void IsSummonedBy(Unit* /*summoner*/) - { - std::list playerOnQuestList; - Trinity::AnyPlayerInObjectRangeCheck checker(me, 5.0f); - Trinity::PlayerListSearcher searcher(me, playerOnQuestList, checker); - me->VisitNearbyWorldObject(5.0f, searcher); - for (std::list::const_iterator itr = playerOnQuestList.begin(); itr != playerOnQuestList.end(); ++itr) - { - // Check if found player target has active quest - if (Player* player = (*itr)) - { - if (player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) - { - StartEvent(player); - break; - } - } - else - break; - } - } - - void JustDied(Unit* /*killer*/) - { - if (!PlayerGUID) - return; - - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) - { - player->FailQuest(10965); - PlayerGUID = 0; - Reset(); - } - } - - void EnterEvadeMode() - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player && player->isInCombat() && player->getAttackerForHelper()) - { - AttackStart(player->getAttackerForHelper()); - return; - } - npc_escortAI::EnterEvadeMode(); - } - - void StartEvent(Player* player) - { - if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) - { - for (uint8 i = 0; i < 41; ++i) - { - AddWaypoint(i, Clintar_spirit_WP[i][0], Clintar_spirit_WP[i][1], Clintar_spirit_WP[i][2], (uint32)Clintar_spirit_WP[i][4]); - } - PlayerGUID = player->GetGUID(); - Start(true, false, PlayerGUID); - } - return; - } - - void UpdateAI(uint32 const diff) - { - npc_escortAI::UpdateAI(diff); - - if (!PlayerGUID) - { - me->setDeathState(JUST_DIED); - return; - } - - if (!me->isInCombat() && !EventOnWait) - { - if (checkPlayerTimer <= diff) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player && player->isInCombat() && player->getAttackerForHelper()) - AttackStart(player->getAttackerForHelper()); - checkPlayerTimer = 1000; - } else checkPlayerTimer -= diff; - } - - if (EventOnWait && EventTimer <= diff) - { - - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (!player || (player && player->GetQuestStatus(10965) == QUEST_STATUS_NONE)) - { - me->setDeathState(JUST_DIED); - return; - } - - switch (CurrWP) - { - case 0: - switch (Step) - { - case 0: - Talk(CLINTAR_SPIRIT_SAY_START, PlayerGUID); - EventTimer = 8000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 6: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - EventTimer = 5000; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - // Needs text - EventOnWait = false; - break; - } - break; - case 15: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - EventTimer = 5000; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - EventOnWait = false; - break; - } - break; - case 16: - switch (Step) - { - case 0: - // Needs text - EventTimer = 15000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 20: - switch (Step) - { - case 0: - if (Creature* mob = me->SummonCreature(ASPECT_RAVEN, AspectRavenSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) - { - mob->AddThreat(me, 10000.0f); - mob->AI()->AttackStart(me); - } - EventTimer = 2000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 24: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); - EventTimer = 5000; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - EventOnWait = false; - break; - } - break; - case 25: - switch (Step) - { - case 0: - // Needs text - EventTimer = 4000; - Step = 1; - break; - case 1: - EventOnWait = false; - break; - } - break; - case 40: - switch (Step) - { - case 0: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2); - // Needs text - player->CompleteQuest(10965); - EventTimer = 1500; - Step = 1; - break; - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - EventTimer = 3000; - Step = 2; - break; - case 2: - player->TalkedToCreature(me->GetEntry(), me->GetGUID()); - PlayerGUID = 0; - Reset(); - me->setDeathState(JUST_DIED); - break; - } - break; - default: - EventOnWait = false; - break; - } - - } else if (EventOnWait) EventTimer -= diff; - } - - void WaypointReached(uint32 waypointId) - { - CurrWP = waypointId; - EventTimer = 0; - Step = 0; - EventOnWait = true; - } - }; - -}; - -/*#### -# npc_omen -####*/ - -enum Omen -{ - NPC_OMEN = 15467, - - SPELL_OMEN_CLEAVE = 15284, - SPELL_OMEN_STARFALL = 26540, - SPELL_OMEN_SUMMON_SPOTLIGHT = 26392, - SPELL_ELUNE_CANDLE = 26374, - - GO_ELUNE_TRAP_1 = 180876, - GO_ELUNE_TRAP_2 = 180877, - - EVENT_CAST_CLEAVE = 1, - EVENT_CAST_STARFALL = 2, - EVENT_DESPAWN = 3, -}; - -class npc_omen : public CreatureScript -{ -public: - npc_omen() : CreatureScript("npc_omen") { } - - struct npc_omenAI : public ScriptedAI - { - npc_omenAI(Creature* creature) : ScriptedAI(creature) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->GetMotionMaster()->MovePoint(1, 7549.977f, -2855.137f, 456.9678f); - } - - EventMap events; - - void MovementInform(uint32 type, uint32 pointId) - { - if (type != POINT_MOTION_TYPE) - return; - - if (pointId == 1) - { - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - if (Player* player = me->SelectNearestPlayer(40.0f)) - AttackStart(player); - } - } - - void EnterCombat(Unit* /*attacker*/) - { - events.Reset(); - events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(3000, 5000)); - events.ScheduleEvent(EVENT_CAST_STARFALL, urand(8000, 10000)); - } - - void JustDied(Unit* /*killer*/) - { - DoCast(SPELL_OMEN_SUMMON_SPOTLIGHT); - } - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) - { - if (spell->Id == SPELL_ELUNE_CANDLE) - { - if (me->HasAura(SPELL_OMEN_STARFALL)) - me->RemoveAurasDueToSpell(SPELL_OMEN_STARFALL); - - events.RescheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000)); - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_CAST_CLEAVE: - DoCastVictim(SPELL_OMEN_CLEAVE); - events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(8000, 10000)); - break; - case EVENT_CAST_STARFALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_OMEN_STARFALL); - events.ScheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000)); - break; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_omenAI(creature); - } -}; - -class npc_giant_spotlight : public CreatureScript -{ -public: - npc_giant_spotlight() : CreatureScript("npc_giant_spotlight") { } - - struct npc_giant_spotlightAI : public ScriptedAI - { - npc_giant_spotlightAI(Creature* creature) : ScriptedAI(creature) {} - - EventMap events; - - void Reset() - { - events.Reset(); - events.ScheduleEvent(EVENT_DESPAWN, 5*MINUTE*IN_MILLISECONDS); - } - - void UpdateAI(const uint32 diff) - { - events.Update(diff); - - if (events.ExecuteEvent() == EVENT_DESPAWN) - { - if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_1, 5.0f)) - trap->RemoveFromWorld(); - - if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_2, 5.0f)) - trap->RemoveFromWorld(); - - if (Creature* omen = me->FindNearestCreature(NPC_OMEN, 5.0f, false)) - omen->DespawnOrUnsummon(); - - me->DespawnOrUnsummon(); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_giant_spotlightAI(creature); - } -}; - -void AddSC_moonglade() -{ - new npc_bunthen_plainswind(); - new npc_great_bear_spirit(); - new npc_silva_filnaveth(); - new npc_clintar_spirit(); - new npc_omen(); - new npc_giant_spotlight(); -} diff --git a/src/server/scripts/Kalimdor/mulgore.cpp b/src/server/scripts/Kalimdor/mulgore.cpp deleted file mode 100644 index aca55284b67..00000000000 --- a/src/server/scripts/Kalimdor/mulgore.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Mulgore -SD%Complete: 100 -SDComment: Support for quest: 11129, 772 -SDCategory: Mulgore -EndScriptData */ - -/* ContentData -npc_skorn_whitecloud -npc_kyle_frenzied -npc_plains_vision -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "SpellInfo.h" - -/*###### -# npc_skorn_whitecloud -######*/ - -#define GOSSIP_SW "Tell me a story, Skorn." - -class npc_skorn_whitecloud : public CreatureScript -{ -public: - npc_skorn_whitecloud() : CreatureScript("npc_skorn_whitecloud") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - player->SEND_GOSSIP_MENU(523, creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (!player->GetQuestRewardStatus(770)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(522, creature->GetGUID()); - - return true; - } - -}; - -/*##### -# npc_kyle_frenzied -######*/ - -enum KyleFrenzied -{ - EMOTE_SEE_LUNCH = 0, - EMOTE_EAT_LUNCH = 1, - EMOTE_DANCE = 2, - - SPELL_LUNCH = 42222, - NPC_KYLE_FRENZIED = 23616, - NPC_KYLE_FRIENDLY = 23622, - POINT_ID = 1 -}; - -class npc_kyle_frenzied : public CreatureScript -{ -public: - npc_kyle_frenzied() : CreatureScript("npc_kyle_frenzied") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kyle_frenziedAI (creature); - } - - struct npc_kyle_frenziedAI : public ScriptedAI - { - npc_kyle_frenziedAI(Creature* creature) : ScriptedAI(creature) {} - - bool EventActive; - bool IsMovingToLunch; - uint64 PlayerGUID; - uint32 EventTimer; - uint8 EventPhase; - - void Reset() - { - EventActive = false; - IsMovingToLunch = false; - PlayerGUID = 0; - EventTimer = 5000; - EventPhase = 0; - - if (me->GetEntry() == NPC_KYLE_FRIENDLY) - me->UpdateEntry(NPC_KYLE_FRENZIED); - } - - void SpellHit(Unit* Caster, SpellInfo const* Spell) - { - if (!me->getVictim() && !EventActive && Spell->Id == SPELL_LUNCH) - { - if (Caster->GetTypeId() == TYPEID_PLAYER) - PlayerGUID = Caster->GetGUID(); - - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - { - me->GetMotionMaster()->MovementExpired(); - me->GetMotionMaster()->MoveIdle(); - me->StopMoving(); - } - - EventActive = true; - Talk(EMOTE_SEE_LUNCH); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CREATURE_SPECIAL); - } - } - - void MovementInform(uint32 Type, uint32 PointId) - { - if (Type != POINT_MOTION_TYPE || !EventActive) - return; - - if (PointId == POINT_ID) - IsMovingToLunch = false; - } - - void UpdateAI(const uint32 diff) - { - if (EventActive) - { - if (IsMovingToLunch) - return; - - if (EventTimer <= diff) - { - EventTimer = 5000; - ++EventPhase; - - switch (EventPhase) - { - case 1: - if (Unit* unit = Unit::GetUnit(*me, PlayerGUID)) - { - if (GameObject* go = unit->GetGameObject(SPELL_LUNCH)) - { - IsMovingToLunch = true; - me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()); - } - } - break; - case 2: - Talk(EMOTE_EAT_LUNCH); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); - break; - case 3: - if (Player* unit = Unit::GetPlayer(*me, PlayerGUID)) - unit->TalkedToCreature(me->GetEntry(), me->GetGUID()); - - me->UpdateEntry(NPC_KYLE_FRIENDLY); - break; - case 4: - EventTimer = 30000; - Talk(EMOTE_DANCE); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCESPECIAL); - break; - case 5: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - Reset(); - me->GetMotionMaster()->Clear(); - break; - } - } - else - EventTimer -= diff; - } - } - }; - -}; - -/*##### -# npc_plains_vision -######*/ - -Position const wpPlainVision[50] = -{ - {-2226.32f, -408.095f, -9.36235f, 0.0f}, - {-2203.04f, -437.212f, -5.72498f, 0.0f}, - {-2163.91f, -457.851f, -7.09049f, 0.0f}, - {-2123.87f, -448.137f, -9.29591f, 0.0f}, - {-2104.66f, -427.166f, -6.49513f, 0.0f}, - {-2101.48f, -422.826f, -5.3567f, 0.0f}, - {-2097.56f, -417.083f, -7.16716f, 0.0f}, - {-2084.87f, -398.626f, -9.88973f, 0.0f}, - {-2072.71f, -382.324f, -10.2488f, 0.0f}, - {-2054.05f, -356.728f, -6.22468f, 0.0f}, - {-2051.8f, -353.645f, -5.35791f, 0.0f}, - {-2049.08f, -349.912f, -6.15723f, 0.0f}, - {-2030.6f, -310.724f, -9.59302f, 0.0f}, - {-2002.15f, -249.308f, -10.8124f, 0.0f}, - {-1972.85f, -195.811f, -10.6316f, 0.0f}, - {-1940.93f, -147.652f, -11.7055f, 0.0f}, - {-1888.06f, -81.943f, -11.4404f, 0.0f}, - {-1837.05f, -34.0109f, -12.258f, 0.0f}, - {-1796.12f, -14.6462f, -10.3581f, 0.0f}, - {-1732.61f, -4.27746f, -10.0213f, 0.0f}, - {-1688.94f, -0.829945f, -11.7103f, 0.0f}, - {-1681.32f, 13.0313f, -9.48056f, 0.0f}, - {-1677.04f, 36.8349f, -7.10318f, 0.0f}, - {-1675.2f, 68.559f, -8.95384f, 0.0f}, - {-1676.57f, 89.023f, -9.65104f, 0.0f}, - {-1678.16f, 110.939f, -10.1782f, 0.0f}, - {-1677.86f, 128.681f, -5.73869f, 0.0f}, - {-1675.27f, 144.324f, -3.47916f, 0.0f}, - {-1671.7f, 163.169f, -1.23098f, 0.0f}, - {-1666.61f, 181.584f, 5.26145f, 0.0f}, - {-1661.51f, 196.154f, 8.95252f, 0.0f}, - {-1655.47f, 210.811f, 8.38727f, 0.0f}, - {-1647.07f, 226.947f, 5.27755f, 0.0f}, - {-1621.65f, 232.91f, 2.69579f, 0.0f}, - {-1600.23f, 237.641f, 2.98539f, 0.0f}, - {-1576.07f, 242.546f, 4.66541f, 0.0f}, - {-1554.57f, 248.494f, 6.60377f, 0.0f}, - {-1547.53f, 259.302f, 10.6741f, 0.0f}, - {-1541.7f, 269.847f, 16.4418f, 0.0f}, - {-1539.83f, 278.989f, 21.0597f, 0.0f}, - {-1540.16f, 290.219f, 27.8247f, 0.0f}, - {-1538.99f, 298.983f, 34.0032f, 0.0f}, - {-1540.38f, 307.337f, 41.3557f, 0.0f}, - {-1536.61f, 314.884f, 48.0179f, 0.0f}, - {-1532.42f, 323.277f, 55.6667f, 0.0f}, - {-1528.77f, 329.774f, 61.1525f, 0.0f}, - {-1525.65f, 333.18f, 63.2161f, 0.0f}, - {-1517.01f, 350.713f, 62.4286f, 0.0f}, - {-1511.39f, 362.537f, 62.4539f, 0.0f}, - {-1508.68f, 366.822f, 62.733f, 0.0f} -}; - -class npc_plains_vision : public CreatureScript -{ -public: - npc_plains_vision() : CreatureScript("npc_plains_vision") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_plains_visionAI (creature); - } - - struct npc_plains_visionAI : public ScriptedAI - { - npc_plains_visionAI(Creature* creature) : ScriptedAI(creature) {} - - bool newWaypoint; - uint8 WayPointId; - uint8 amountWP; - - void Reset() - { - WayPointId = 0; - newWaypoint = true; - amountWP = 49; - } - - void EnterCombat(Unit* /*who*/){} - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id < amountWP) - { - ++WayPointId; - newWaypoint = true; - } - else - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - } - } - - void UpdateAI(const uint32 /*diff*/) - { - if (newWaypoint) - { - me->GetMotionMaster()->MovePoint(WayPointId, wpPlainVision[WayPointId]); - newWaypoint = false; - } - } - }; - -}; - -/*##### -# -######*/ - -void AddSC_mulgore() -{ - new npc_skorn_whitecloud(); - new npc_kyle_frenzied(); - new npc_plains_vision(); -} diff --git a/src/server/scripts/Kalimdor/orgrimmar.cpp b/src/server/scripts/Kalimdor/orgrimmar.cpp deleted file mode 100644 index 42ef9843a4e..00000000000 --- a/src/server/scripts/Kalimdor/orgrimmar.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Orgrimmar -SD%Complete: 100 -SDComment: Quest support: 2460, 6566 -SDCategory: Orgrimmar -EndScriptData */ - -/* ContentData -npc_shenthul -npc_thrall_warchief -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*###### -## npc_shenthul -######*/ - -enum Shenthul -{ - QUEST_SHATTERED_SALUTE = 2460 -}; - -class npc_shenthul : public CreatureScript -{ -public: - npc_shenthul() : CreatureScript("npc_shenthul") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_SHATTERED_SALUTE) - { - CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->CanTalk = true; - CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->PlayerGUID = player->GetGUID(); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_shenthulAI (creature); - } - - struct npc_shenthulAI : public ScriptedAI - { - npc_shenthulAI(Creature* creature) : ScriptedAI(creature) {} - - bool CanTalk; - bool CanEmote; - uint32 SaluteTimer; - uint32 ResetTimer; - uint64 PlayerGUID; - - void Reset() - { - CanTalk = false; - CanEmote = false; - SaluteTimer = 6000; - ResetTimer = 0; - PlayerGUID = 0; - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (CanEmote) - { - if (ResetTimer <= diff) - { - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) - { - if (player->GetTypeId() == TYPEID_PLAYER && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE) - player->FailQuest(QUEST_SHATTERED_SALUTE); - } - Reset(); - } else ResetTimer -= diff; - } - - if (CanTalk && !CanEmote) - { - if (SaluteTimer <= diff) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - CanEmote = true; - ResetTimer = 60000; - } else SaluteTimer -= diff; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void ReceiveEmote(Player* player, uint32 emote) - { - if (emote == TEXT_EMOTE_SALUTE && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE) - { - if (CanEmote) - { - player->AreaExploredOrEventHappens(QUEST_SHATTERED_SALUTE); - Reset(); - } - } - } - }; - -}; - -/*###### -## npc_thrall_warchief -######*/ - -enum ThrallWarchief -{ - QUEST_6566 = 6566, - - SPELL_CHAIN_LIGHTNING = 16033, - SPELL_SHOCK = 16034 -}; - -#define GOSSIP_HTW "Please share your wisdom with me, Warchief." -#define GOSSIP_STW1 "What discoveries?" -#define GOSSIP_STW2 "Usurper?" -#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?" -#define GOSSIP_STW4 "I... I did not think of it that way, Warchief." -#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance." -#define GOSSIP_STW6 "Of course, Warchief!" - -//TODO: verify abilities/timers -class npc_thrall_warchief : public CreatureScript -{ -public: - npc_thrall_warchief() : CreatureScript("npc_thrall_warchief") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(5733, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(5734, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(5735, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(5736, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(5737, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); - player->SEND_GOSSIP_MENU(5738, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(QUEST_6566); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_thrall_warchiefAI (creature); - } - - struct npc_thrall_warchiefAI : public ScriptedAI - { - npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 ChainLightningTimer; - uint32 ShockTimer; - - void Reset() - { - ChainLightningTimer = 2000; - ShockTimer = 8000; - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (ChainLightningTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CHAIN_LIGHTNING); - ChainLightningTimer = 9000; - } else ChainLightningTimer -= diff; - - if (ShockTimer <= diff) - { - DoCast(me->getVictim(), SPELL_SHOCK); - ShockTimer = 15000; - } else ShockTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - -void AddSC_orgrimmar() -{ - new npc_shenthul(); - new npc_thrall_warchief(); -} diff --git a/src/server/scripts/Kalimdor/silithus.cpp b/src/server/scripts/Kalimdor/silithus.cpp deleted file mode 100644 index 58665224bdd..00000000000 --- a/src/server/scripts/Kalimdor/silithus.cpp +++ /dev/null @@ -1,1515 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Silithus -SD%Complete: 100 -SDComment: Quest support: 7785, 8304, 8507. -SDCategory: Silithus -EndScriptData */ - -/* ContentData -npc_highlord_demitrian -npcs_rutgar_and_frankal -quest_a_pawn_on_the_eternal_pawn -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Group.h" -#include "Player.h" - -/*### -## npc_highlord_demitrian -###*/ - -#define GOSSIP_DEMITRIAN1 "What do you know of it?" -#define GOSSIP_DEMITRIAN2 "I am listening, Demitrian." -#define GOSSIP_DEMITRIAN3 "Continue, please." -#define GOSSIP_DEMITRIAN4 "A battle?" -#define GOSSIP_DEMITRIAN5 "" -#define GOSSIP_DEMITRIAN6 "Caught unaware? How?" -#define GOSSIP_DEMITRIAN7 "So what did Ragnaros do next?" - -class npc_highlord_demitrian : public CreatureScript -{ -public: - npc_highlord_demitrian() : CreatureScript("npc_highlord_demitrian") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(6842, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(6843, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(6844, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(6867, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(6868, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(6869, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->SEND_GOSSIP_MENU(6870, creature->GetGUID()); - - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 19016, 1); - if (msg == EQUIP_ERR_OK) - player->StoreNewItem(dest, 19016, true); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(7785) == QUEST_STATUS_NONE && - (player->HasItemCount(18563, 1, false) || player->HasItemCount(18564, 1, false))) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(6812, creature->GetGUID()); - return true; - } - -}; - -/*### -## npcs_rutgar_and_frankal -###*/ - -//gossip item text best guess -#define GOSSIP_ITEM1 "I seek information about Natalia" - -#define GOSSIP_ITEM2 "That sounds dangerous!" -#define GOSSIP_ITEM3 "What did you do?" -#define GOSSIP_ITEM4 "Who?" -#define GOSSIP_ITEM5 "Women do that. What did she demand?" -#define GOSSIP_ITEM6 "What do you mean?" -#define GOSSIP_ITEM7 "What happened next?" - -#define GOSSIP_ITEM11 "Yes, please continue" -#define GOSSIP_ITEM12 "What language?" -#define GOSSIP_ITEM13 "The Priestess attacked you?!" -#define GOSSIP_ITEM14 "I should ask the monkey about this" -#define GOSSIP_ITEM15 "Then what..." - -enum RutgarAndFrankal //trigger creatures to kill -{ - TRIGGER_FRANKAL = 15221, - TRIGGER_RUTGAR = 15222 -}; - -class npcs_rutgar_and_frankal : public CreatureScript -{ -public: - npcs_rutgar_and_frankal() : CreatureScript("npcs_rutgar_and_frankal") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(7755, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(7756, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(7757, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(7758, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(7759, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(7760, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 6: - player->SEND_GOSSIP_MENU(7761, creature->GetGUID()); - //'kill' our trigger to update quest status - player->KilledMonsterCredit(TRIGGER_RUTGAR, 0); - break; - - case GOSSIP_ACTION_INFO_DEF + 9: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - player->SEND_GOSSIP_MENU(7762, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 10: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM12, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - player->SEND_GOSSIP_MENU(7763, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 11: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM13, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12); - player->SEND_GOSSIP_MENU(7764, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 12: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM14, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13); - player->SEND_GOSSIP_MENU(7765, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 13: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM15, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14); - player->SEND_GOSSIP_MENU(7766, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 14: - player->SEND_GOSSIP_MENU(7767, creature->GetGUID()); - //'kill' our trigger to update quest status - player->KilledMonsterCredit(TRIGGER_FRANKAL, 0); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(8304) == QUEST_STATUS_INCOMPLETE && - creature->GetEntry() == 15170 && - !player->GetReqKillOrCastCurrentCount(8304, TRIGGER_RUTGAR)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - if (player->GetQuestStatus(8304) == QUEST_STATUS_INCOMPLETE && - creature->GetEntry() == 15171 && - player->GetReqKillOrCastCurrentCount(8304, TRIGGER_RUTGAR)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+9); - - player->SEND_GOSSIP_MENU(7754, creature->GetGUID()); - - return true; - } - -}; - -/*#### -# quest_a_pawn_on_the_eternal_board (Defines) -####*/ -enum EternalBoard -{ - QUEST_A_PAWN_ON_THE_ETERNAL_BOARD = 8519, - - FACTION_HOSTILE = 14, - FACTION_FRIENDLY = 35, - - C_ANACHRONOS = 15381, - C_FANDRAL_STAGHELM = 15382, - C_ARYGOS = 15380, - C_MERITHRA = 15378, - C_CAELESTRASZ = 15379, - - ANACHRONOS_SAY_1 = 0, - ANACHRONOS_SAY_2 = 1, - ANACHRONOS_SAY_3 = 2, - ANACHRONOS_SAY_4 = 3, - ANACHRONOS_SAY_5 = 4, - ANACHRONOS_SAY_6 = 5, - ANACHRONOS_SAY_7 = 6, - ANACHRONOS_SAY_8 = 7, - ANACHRONOS_SAY_9 = 8, - ANACHRONOS_SAY_10 = 9, - ANACHRONOS_EMOTE_1 = 10, - ANACHRONOS_EMOTE_2 = 11, - ANACHRONOS_EMOTE_3 = 12, - - FANDRAL_SAY_1 = 0, - FANDRAL_SAY_2 = 1, - FANDRAL_SAY_3 = 2, - FANDRAL_SAY_4 = 3, - FANDRAL_SAY_5 = 4, - FANDRAL_SAY_6 = 5, - FANDRAL_EMOTE_1 = 6, - FANDRAL_EMOTE_2 = 7, - - CAELESTRASZ_SAY_1 = 0, - CAELESTRASZ_SAY_2 = 1, - CAELESTRASZ_YELL_1 = 2, - - ARYGOS_SAY_1 = 0, - ARYGOS_YELL_1 = 1, - ARYGOS_EMOTE_1 = 2, - - MERITHRA_SAY_1 = 0, - MERITHRA_SAY_2 = 1, - MERITHRA_YELL_1 = 2, - MERITHRA_EMOTE_1 = 3, - - GO_GATE_OF_AHN_QIRAJ = 176146, - GO_GLYPH_OF_AHN_QIRAJ = 176148, - GO_ROOTS_OF_AHN_QIRAJ = 176147 -}; -/*##### -# Quest: A Pawn on the Eternal Board -#####*/ - -/* ContentData -A Pawn on the Eternal Board - creatures, gameobjects and defines -mob_qiraj_war_spawn : Adds that are summoned in the Qiraj gates battle. -npc_anachronos_the_ancient : Creature that controls the event. -npc_anachronos_quest_trigger: controls the spawning of the BG War mobs. -go_crystalline_tear : GameObject that begins the event and hands out quest -TO DO: get correct spell IDs and timings for spells cast upon dragon transformations -TO DO: Dragons should use the HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF) after transformation, but for some unknown reason it doesnt work. -EndContentData */ - -#define EVENT_AREA_RADIUS 65 //65yds -#define EVENT_COOLDOWN 500000 //in ms. appear after event completed or failed (should be = Adds despawn time) - -struct QuestCinematic -{ - int32 TextId; - uint32 Creature, Timer; -}; - -// Creature 0 - Anachronos, 1 - Fandral, 2 - Arygos, 3 - Merithra, 4 - Caelestrasz -static QuestCinematic EventAnim[]= -{ - {ANACHRONOS_SAY_1, 0, 2000}, - {FANDRAL_SAY_1, 1, 4000}, - {MERITHRA_EMOTE_1, 3, 500}, - {MERITHRA_SAY_1, 3, 500}, - {ARYGOS_EMOTE_1, 2, 2000}, - {CAELESTRASZ_SAY_1, 4, 8000}, - {MERITHRA_SAY_2, 3, 6000}, - {0, 3, 2000}, - {MERITHRA_YELL_1, 3, 2500}, - {0, 3, 3000}, //Morph - {0, 3, 4000}, //EmoteLiftoff - {0, 3, 4000}, // spell - {0, 3, 1250}, //fly - {0, 3, 250}, //remove flags - {ARYGOS_SAY_1, 2, 3000}, - {0, 3, 2000}, - {ARYGOS_YELL_1, 2, 3000}, - {0, 3, 3000}, //Morph - {0, 3, 4000}, //EmoteLiftoff - {0, 3, 4000}, // spell - {0, 3, 1000}, //fly - {0, 3, 1000}, //remove flags - {CAELESTRASZ_SAY_2, 4, 5000}, - {0, 3, 3000}, - {CAELESTRASZ_YELL_1, 4, 3000}, - {0, 3, 3000}, //Morph - {0, 3, 4000}, //EmoteLiftoff - {0, 3, 2500}, // spell - {ANACHRONOS_SAY_2, 0, 2000}, - {0, 3, 250}, //fly - {0, 3, 25}, //remove flags - {FANDRAL_SAY_2, 1, 3000}, - {ANACHRONOS_SAY_3, 0, 10000}, //Both run through the armies - {0, 3, 2000}, // Sands will stop - {0, 3, 8000}, // Summon Gate - {ANACHRONOS_SAY_4, 0, 4000}, - {0, 0, 2000}, //spell 1-> Arcane cosmetic (Mobs freeze) - {0, 0, 5000}, //Spell 2-> Arcane long cosmetic (barrier appears) (Barrier -> Glyphs) - {0, 0, 7000}, //BarrieR - {0, 0, 4000}, //Glyphs - {ANACHRONOS_SAY_5, 0, 2000}, - {0, 0, 4000}, // Roots - {FANDRAL_SAY_3, 1, 3000}, //Root Text - {FANDRAL_EMOTE_1, 1, 3000}, //falls knee - {ANACHRONOS_SAY_6, 0, 3000}, - {ANACHRONOS_SAY_7, 0, 3000}, - {ANACHRONOS_SAY_8, 0, 8000}, - {ANACHRONOS_EMOTE_1, 0, 1000}, //Give Scepter - {FANDRAL_SAY_4, 1, 3000}, - {FANDRAL_SAY_5, 1, 3000}, //->Equip hammer~Scepter, throw it at door - {FANDRAL_EMOTE_2, 1, 3000}, //Throw hammer at door. - {ANACHRONOS_SAY_9, 0, 3000}, - {FANDRAL_SAY_6, 1, 3000}, //fandral goes away - {ANACHRONOS_EMOTE_2, 0, 3000}, - {ANACHRONOS_EMOTE_3, 0, 3000}, - {0, 0, 2000}, - {0, 0, 2000}, - {0, 0, 4000}, - {ANACHRONOS_SAY_10, 0, 3000}, - {0, 0, 2000}, - {0, 0, 3000}, - {0, 0, 15000}, - {0, 0, 5000}, - {0, 0, 3500}, - {0, 0, 5000}, - {0, 0, 3500}, - {0, 0, 5000}, - {0, 0, 0} -}; - -//Cordinates for Spawns -Position const SpawnLocation[] = -{ - {-8085.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8085.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8085.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - - {-8085.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8085.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8085.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - - {-8085.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8080.0f, 1424.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8085.0f, 1422.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - // 2 waves of warriors - {-8082.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1525.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1527.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - - {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - - {-8082.0f, 1523.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1521.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1519.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - - {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8078.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - {-8082.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry - - {-8088.0f, 1510.0f, 2.61f, 0.0f}, //Anubisath Conqueror - {-8084.0f, 1520.0f, 2.61f, 0.0f}, //Anubisath Conqueror - {-8088.0f, 1530.0f, 2.61f, 0.0f}, //Anubisath Conqueror - - {-8080.0f, 1513.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8082.0f, 1523.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8085.0f, 1518.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8082.0f, 1516.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8085.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8080.0f, 1528.0f, 2.61f, 0.0f}, //Qiraj Wasp - - {-8082.0f, 1513.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8079.0f, 1523.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8080.0f, 1531.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8079.0f, 1516.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8082.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Wasp - {-8080.0f, 1518.0f, 2.61f, 0.0f}, //Qiraj Wasp - - {-8081.0f, 1514.0f, 2.61f, 0.0f}, //Qiraj Tank - {-8081.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Tank - {-8081.0f, 1526.0f, 2.61f, 0.0f}, //Qiraj Tank - {-8081.0f, 1512.0f, 2.61f, 0.0f}, //Qiraj Tank - {-8082.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Tank - {-8081.0f, 1528.0f, 2.61f, 0.0f}, //Qiraj Tank - - {-8082.0f, 1513.0f, 2.61f, 3.141592f}, //Anubisath Conqueror - {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Anubisath Conqueror - {-8082.0f, 1527.0f, 2.61f, 3.141592f}, //Anubisath Conqueror -}; - -struct WaveData -{ - uint8 SpawnCount, UsedSpawnPoint; - uint32 CreatureId, SpawnTimer, YellTimer, DespTimer; - int32 WaveTextId; -}; - -static WaveData WavesInfo[5] = -{ - {30, 0, 15423, 0, 0, 24000, 0}, // Kaldorei Soldier - { 3, 35, 15424, 0, 0, 24000, 0}, // Anubisath Conqueror - {12, 38, 15414, 0, 0, 24000, 0}, // Qiraji Wasps - { 6, 50, 15422, 0, 0, 24000, 0}, // Qiraji Tanks - {15, 15, 15423, 0, 0, 24000, 0} // Kaldorei Soldier - -}; - -struct SpawnSpells -{ - uint32 Timer1, Timer2, SpellId; -}; - -static SpawnSpells SpawnCast[4] = -{ - {100000, 2000, 33652}, // Stop Time - {38500, 300000, 28528}, // Poison Cloud - {58000, 300000, 35871}, // Frost Debuff (need correct spell) - {80950, 300000, 42075}, // Fire Explosion (need correct spell however this one looks cool) -}; -/*##### -# npc_anachronos_the_ancient -######*/ -class npc_anachronos_the_ancient : public CreatureScript -{ -public: - npc_anachronos_the_ancient() : CreatureScript("npc_anachronos_the_ancient") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_anachronos_the_ancientAI(creature); - } - - struct npc_anachronos_the_ancientAI : public ScriptedAI - { - npc_anachronos_the_ancientAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 AnimationTimer; - uint8 AnimationCount; - - uint64 AnachronosQuestTriggerGUID; - uint64 MerithraGUID; - uint64 ArygosGUID; - uint64 CaelestraszGUID; - uint64 FandralGUID; - uint64 PlayerGUID; - bool eventEnd; - - void Reset() - { - AnimationTimer = 1500; - AnimationCount = 0; - AnachronosQuestTriggerGUID = 0; - MerithraGUID = 0; - ArygosGUID = 0; - CaelestraszGUID = 0; - FandralGUID = 0; - PlayerGUID = 0; - eventEnd = false; - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - - void HandleAnimation() - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (!player) - return; - - Creature* Fandral = player->FindNearestCreature(C_FANDRAL_STAGHELM, 100.0f, me); - Creature* Arygos = player->FindNearestCreature(C_ARYGOS, 100.0f, me); - Creature* Caelestrasz = player->FindNearestCreature(C_CAELESTRASZ, 100.0f, me); - Creature* Merithra = player->FindNearestCreature(C_MERITHRA, 100.0f, me); - - if (!Fandral || !Arygos || !Caelestrasz || !Merithra) - return; - - AnimationTimer = EventAnim[AnimationCount].Timer; - if (eventEnd == false) - { - switch (AnimationCount) - { - case 0: - Talk(ANACHRONOS_SAY_1,Fandral->GetGUID()); - break; - case 1: - Fandral->SetTarget(me->GetGUID()); - Fandral->AI()->Talk(FANDRAL_SAY_1, me->GetGUID()); - break; - case 2: - Fandral->SetTarget(0); - Merithra->AI()->Talk(MERITHRA_EMOTE_1); - break; - case 3: - Merithra->AI()->Talk(MERITHRA_SAY_1); - break; - case 4: - Arygos->AI()->Talk(ARYGOS_EMOTE_1); - break; - case 5: - Caelestrasz->SetTarget(Fandral->GetGUID()); - Caelestrasz->AI()->Talk(CAELESTRASZ_SAY_1); - break; - case 6: - Merithra->AI()->Talk(MERITHRA_SAY_2); - break; - case 7: - Caelestrasz->SetTarget(0); - Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); - break; - case 8: - Merithra->AI()->Talk(MERITHRA_YELL_1); - break; - case 9: - Merithra->CastSpell(Merithra, 25105, true); - break; - case 10: - Merithra->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Merithra->SetDisableGravity(true); - Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 3); - break; - case 11: - Merithra->CastSpell(Merithra, 24818, false); - break; - case 12: - Merithra->GetMotionMaster()->MoveCharge(-8100, 1530, 50, 42); - break; - case 13: - break; - case 14: - Arygos->AI()->Talk(ARYGOS_SAY_1); - Merithra->SetVisible(false); - break; - case 15: - Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); - Merithra->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); - break; - case 16: - Arygos->AI()->Talk(ARYGOS_YELL_1); - break; - case 17: - Arygos->CastSpell(Arygos, 25107, true); - break; - case 18: - Arygos->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Arygos->SetDisableGravity(true); - Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 42); - break; - case 19: - Arygos->CastSpell(Arygos, 50505, false); - break; - case 20: - Arygos->GetMotionMaster()->MoveCharge(-8095, 1530, 50, 42); - break; - case 21: - break; - case 22: - Caelestrasz->AI()->Talk(CAELESTRASZ_SAY_2, Fandral->GetGUID()); - break; - case 23: - Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); - Arygos->SetVisible(false); - Arygos->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 10); - break; - case 24: - Caelestrasz->AI()->Talk(CAELESTRASZ_YELL_1); - break; - case 25: - Caelestrasz->CastSpell(Caelestrasz, 25106, true); - break; - case 26: - Caelestrasz->HandleEmoteCommand(254); - Caelestrasz->SetDisableGravity(true); - Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 7.61f, 4); - break; - case 27: - Caelestrasz->CastSpell(Caelestrasz, 54293, false); - break; - case 28: - Talk(ANACHRONOS_SAY_2, Fandral->GetGUID()); - break; - case 29: - Caelestrasz->GetMotionMaster()->MoveCharge(-8095, 1530, 50, 42); - Fandral->AI()->Talk(FANDRAL_SAY_2); - break; - case 30: - break; - case 31: - Talk(ANACHRONOS_SAY_3, Fandral->GetGUID()); - break; - case 32: - Caelestrasz->SetVisible(false); - Caelestrasz->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); - Fandral->GetMotionMaster()->MoveCharge(-8108, 1529, 2.77f, 8); - me->GetMotionMaster()->MoveCharge(-8113, 1525, 2.77f, 8); - break;//both run to the gate - case 33: - Talk(ANACHRONOS_SAY_4); - Caelestrasz->GetMotionMaster()->MoveCharge(-8050, 1473, 65, 15); - break; //Text: sands will stop - case 34: - DoCast(player, 23017, true);//Arcane Channeling - break; - case 35: - me->CastSpell(-8088, 1520.43f, 2.67f, 25158, true); - break; - case 36: - DoCast(player, 25159, true); - break; - case 37: - me->SummonGameObject(GO_GATE_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); - break; - case 38: - DoCast(player, 25166, true); - me->SummonGameObject(GO_GLYPH_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); - break; - case 39: - Talk(ANACHRONOS_SAY_5, Fandral->GetGUID()); - break; - case 40: - Fandral->CastSpell(me, 25167, true); - break; - case 41: - Fandral->SummonGameObject(GO_ROOTS_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); - Fandral->AI()->Talk(FANDRAL_SAY_3); - break; - case 42: - me->CastStop(); - Fandral->AI()->Talk(FANDRAL_EMOTE_1); - break; - case 43: - Fandral->CastStop(); - break; - case 44: - Talk(ANACHRONOS_SAY_6); - break; - case 45: - Talk(ANACHRONOS_SAY_7); - break; - case 46: - Talk(ANACHRONOS_SAY_8); - me->GetMotionMaster()->MoveCharge(-8110, 1527, 2.77f, 4); - break; - case 47: - Talk(ANACHRONOS_EMOTE_1); - break; - case 48: - Fandral->AI()->Talk(FANDRAL_SAY_4, me->GetGUID()); - break; - case 49: - Fandral->AI()->Talk(FANDRAL_SAY_5, me->GetGUID()); - break; - case 50: - Fandral->AI()->Talk(FANDRAL_EMOTE_2); - Fandral->CastSpell(-8127, 1525, 17.5f, 33806, true); - break; - case 51: - { - uint32 entries[4] = { 15423, 15424, 15414, 15422 }; - Unit* mob = NULL; - for (uint8 i = 0; i < 4; ++i) - { - mob = player->FindNearestCreature(entries[i], 50, me); - while (mob) - { - mob->RemoveFromWorld(); - mob = player->FindNearestCreature(15423, 50, me); - } - } - break; - } - case 52: - Fandral->GetMotionMaster()->MoveCharge(-8028.75f, 1538.795f, 2.61f, 4); - Fandral->AI()->Talk(ANACHRONOS_SAY_9, me->GetGUID()); - break; - case 53: - Fandral->AI()->Talk(FANDRAL_SAY_6); - break; - case 54: - Talk(ANACHRONOS_EMOTE_2); - break; - case 55: - Fandral->SetVisible(false); - break; - case 56: - Talk(ANACHRONOS_EMOTE_3); - me->GetMotionMaster()->MoveCharge(-8116, 1522, 3.65f, 4); - break; - case 57: - me->GetMotionMaster()->MoveCharge(-8116.7f, 1527, 3.7f, 4); - break; - case 58: - me->GetMotionMaster()->MoveCharge(-8112.67f, 1529.9f, 2.86f, 4); - break; - case 59: - me->GetMotionMaster()->MoveCharge(-8117.99f, 1532.24f, 3.94f, 4); - break; - case 60: - if (player) - Talk(ANACHRONOS_SAY_10, player->GetGUID()); - me->GetMotionMaster()->MoveCharge(-8113.46f, 1524.16f, 2.89f, 4); - break; - case 61: - me->GetMotionMaster()->MoveCharge(-8057.1f, 1470.32f, 2.61f, 6); - if (player->IsInRange(me, 0, 15)) - player->GroupEventHappens(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD, me); - break; - case 62: - me->SetDisplayId(15500); - break; - case 63: - me->HandleEmoteCommand(254); - me->SetDisableGravity(true); - break; - case 64: - me->GetMotionMaster()->MoveCharge(-8000, 1400, 150, 9); - break; - case 65: - me->SetVisible(false); - if (Creature* AnachronosQuestTrigger = (Unit::GetCreature(*me, AnachronosQuestTriggerGUID))) - { - Talk(ARYGOS_YELL_1); - AnachronosQuestTrigger->AI()->EnterEvadeMode(); - eventEnd=true; - } - break; - } - } - ++AnimationCount; - } - void UpdateAI(const uint32 diff) - { - if (AnimationTimer) - { - if (AnimationTimer <= diff) - HandleAnimation(); - else AnimationTimer -= diff; - } - if (AnimationCount < 65) - me->CombatStop(); - if (AnimationCount == 65 || eventEnd) - me->AI()->EnterEvadeMode(); - } - }; - -}; - -/*###### -# mob_qiraj_war_spawn -######*/ - -class mob_qiraj_war_spawn : public CreatureScript -{ -public: - mob_qiraj_war_spawn() : CreatureScript("mob_qiraj_war_spawn") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_qiraj_war_spawnAI(creature); - } - - struct mob_qiraj_war_spawnAI : public ScriptedAI - { - mob_qiraj_war_spawnAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 MobGUID; - uint64 PlayerGUID; - uint32 SpellTimer1, SpellTimer2, SpellTimer3, SpellTimer4; - bool Timers; - bool hasTarget; - - void Reset() - { - MobGUID = 0; - PlayerGUID = 0; - Timers = false; - hasTarget = false; - } - - void EnterCombat(Unit* /*who*/) {} - void JustDied(Unit* /*slayer*/); - - void UpdateAI(const uint32 diff) - { - if (!Timers) - { - if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) //all but Kaldorei Soldiers - { - SpellTimer1 = SpawnCast[1].Timer1; - SpellTimer2 = SpawnCast[2].Timer1; - SpellTimer3 = SpawnCast[3].Timer1; - } - if (me->GetEntry() == 15423 || me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) - SpellTimer4 = SpawnCast[0].Timer1; - Timers = true; - } - if (me->GetEntry() == 15424 || me->GetEntry() == 15422|| me->GetEntry() == 15414) - { - if (SpellTimer1 <= diff) - { - DoCast(me, SpawnCast[1].SpellId); - DoCast(me, 24319); - SpellTimer1 = SpawnCast[1].Timer2; - } else SpellTimer1 -= diff; - if (SpellTimer2 <= diff) - { - DoCast(me, SpawnCast[2].SpellId); - SpellTimer2 = SpawnCast[2].Timer2; - } else SpellTimer2 -= diff; - if (SpellTimer3 <= diff) - { - DoCast(me, SpawnCast[3].SpellId); - SpellTimer3 = SpawnCast[3].Timer2; - } else SpellTimer3 -= diff; - } - if (me->GetEntry() == 15423 || me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) - { - if (SpellTimer4 <= diff) - { - me->RemoveAllAttackers(); - me->AttackStop(); - DoCast(me, 15533); - SpellTimer4 = SpawnCast[0].Timer2; - } else SpellTimer4 -= diff; - } - if (!hasTarget) - { - Unit* target = NULL; - if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) - target = me->FindNearestCreature(15423, 20, true); - if (me->GetEntry() == 15423) - { - uint8 tar = urand(0, 2); - - if (tar == 0) - target = me->FindNearestCreature(15422, 20, true); - else if (tar == 1) - target = me->FindNearestCreature(15424, 20, true); - else if (tar == 2) - target = me->FindNearestCreature(15414, 20, true); - } - hasTarget = true; - if (target) - me->AI()->AttackStart(target); - } - if (!(me->FindNearestCreature(15379, 60))) - DoCast(me, 33652); - - if (!UpdateVictim()) - { - hasTarget = false; - return; - } - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*##### -# npc_anachronos_quest_trigger -#####*/ - -class npc_anachronos_quest_trigger : public CreatureScript -{ -public: - npc_anachronos_quest_trigger() : CreatureScript("npc_anachronos_quest_trigger") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_anachronos_quest_triggerAI(creature); - } - - struct npc_anachronos_quest_triggerAI : public ScriptedAI - { - npc_anachronos_quest_triggerAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - - uint32 WaveTimer; - uint32 AnnounceTimer; - - int8 LiveCount; - uint8 WaveCount; - - bool EventStarted; - bool Announced; - bool Failed; - - void Reset() - { - PlayerGUID = 0; - - WaveTimer = 2000; - AnnounceTimer = 1000; - LiveCount = 0; - WaveCount = 0; - - EventStarted = false; - Announced = false; - Failed = false; - - me->SetVisible(false); - } - - void SummonNextWave() - { - uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; - uint8 count = locIndex + WavesInfo[WaveCount].SpawnCount; - - for (uint8 i = locIndex; i <= count; ++i) - { - uint32 desptimer = WavesInfo[WaveCount].DespTimer; - - if (Creature* spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, SpawnLocation[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, desptimer)) - { - if (spawn->GetEntry() == 15423) - spawn->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15427+rand()%4); - if (i >= 30) WaveCount = 1; - if (i >= 33) WaveCount = 2; - if (i >= 45) WaveCount = 3; - if (i >= 51) WaveCount = 4; - - if (WaveCount < 5) //1-4 Wave - { - if (mob_qiraj_war_spawn::mob_qiraj_war_spawnAI* spawnAI = CAST_AI(mob_qiraj_war_spawn::mob_qiraj_war_spawnAI, spawn->AI())) - { - spawnAI->MobGUID = me->GetGUID(); - spawnAI->PlayerGUID = PlayerGUID; - } - } - } - } - - WaveTimer = WavesInfo[WaveCount].SpawnTimer; - AnnounceTimer = WavesInfo[WaveCount].YellTimer; - } - - void CheckEventFail() - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - - if (!player) - return; - - if (Group* EventGroup = player->GetGroup()) - { - Player* groupMember; - - uint8 GroupMemberCount = 0; - uint8 DeadMemberCount = 0; - uint8 FailedMemberCount = 0; - - Group::MemberSlotList const members = EventGroup->GetMemberSlots(); - - for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) - { - groupMember = (Unit::GetPlayer(*me, itr->guid)); - if (!groupMember) - continue; - if (!groupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && groupMember->GetQuestStatus(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) == QUEST_STATUS_INCOMPLETE) - { - groupMember->FailQuest(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD); - ++FailedMemberCount; - } - ++GroupMemberCount; - - if (groupMember->isDead()) - ++DeadMemberCount; - } - - if (GroupMemberCount == FailedMemberCount || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS)) - Failed = true; //only so event can restart - } - } - - void LiveCounter() - { - --LiveCount; - if (!LiveCount) - Announced = false; - } - - void UpdateAI(const uint32 diff) - { - if (!PlayerGUID || !EventStarted) - return; - - if (WaveCount < 4) - { - if (!Announced && AnnounceTimer <= diff) - { - Talk(WavesInfo[WaveCount].WaveTextId); - Announced = true; - } else AnnounceTimer -= diff; - - if (WaveTimer <= diff) - SummonNextWave(); - else WaveTimer -= diff; - } - CheckEventFail(); - if (WaveCount == 4 || Failed) - EnterEvadeMode(); - }; - }; - -}; - -void mob_qiraj_war_spawn::mob_qiraj_war_spawnAI::JustDied(Unit* /*slayer*/) -{ - me->RemoveCorpse(); - - if (!MobGUID) - return; - - if (Creature* mob = Unit::GetCreature(*me, MobGUID)) - if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, mob->AI())) - triggerAI->LiveCounter(); - -}; - -/*##### -# go_crystalline_tear -######*/ - -class go_crystalline_tear : public GameObjectScript -{ -public: - go_crystalline_tear() : GameObjectScript("go_crystalline_tear") { } - - bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) - { - if (Creature* trigger = go->FindNearestCreature(15454, 100, player)) - { - Unit* Merithra = trigger->SummonCreature(15378, -8034.535f, 1535.14f, 2.61f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - Unit* Caelestrasz = trigger->SummonCreature(15379, -8032.767f, 1533.148f, 2.61f, 1.5f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - Unit* Arygos = trigger->SummonCreature(15380, -8034.52f, 1537.843f, 2.61f, 5.7f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - /* Unit* Fandral = */ trigger->SummonCreature(15382, -8028.462f, 1535.843f, 2.61f, 3.141592f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - Creature* Anachronos = trigger->SummonCreature(15381, -8028.75f, 1538.795f, 2.61f, 4, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); - - if (Merithra) - { - Merithra->SetUInt32Value(UNIT_NPC_FLAGS, 0); - Merithra->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - Merithra->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15420); - Merithra->setFaction(35); - } - - if (Caelestrasz) - { - Caelestrasz->SetUInt32Value(UNIT_NPC_FLAGS, 0); - Caelestrasz->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - Caelestrasz->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15419); - Caelestrasz->setFaction(35); - } - - if (Arygos) - { - Arygos->SetUInt32Value(UNIT_NPC_FLAGS, 0); - Arygos->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - Arygos->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15418); - Arygos->setFaction(35); - } - - if (Anachronos) - { - if (npc_anachronos_the_ancient::npc_anachronos_the_ancientAI* anachronosAI = CAST_AI(npc_anachronos_the_ancient::npc_anachronos_the_ancientAI, Anachronos->AI())) - anachronosAI->PlayerGUID = player->GetGUID(); - - if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, trigger->AI())) - { - triggerAI->Failed = false; - triggerAI->PlayerGUID = player->GetGUID(); - triggerAI->EventStarted = true; - triggerAI->Announced = true; - } - } - } - } - return true; - } - -}; - -/*### -## go_wind_stone -###*/ - -enum WSSpells -{ - SPELL_PUNISHMENT = 24803, - SPELL_SPAWN_IN = 25035, - - AURA_TWILIGHT_SET = 24746, - AURA_MEDALLION = 24748, - AURA_RING = 24782, - - SPELL_TEMPLAR_RANDOM = 24745, - SPELL_TEMPLAR_FIRE = 24747, - SPELL_TEMPLAR_AIR = 24757, - SPELL_TEMPLAR_EARTH = 24759, - SPELL_TEMPLAR_WATER = 24761, - - SPELL_DUKE_RANDOM = 24762, - SPELL_DUKE_FIRE = 24766, - SPELL_DUKE_AIR = 24769, - SPELL_DUKE_EARTH = 24771, - SPELL_DUKE_WATER = 24773, - - SPELL_ROYAL_RANDOM = 24785, - SPELL_ROYAL_FIRE = 24787, - SPELL_ROYAL_AIR = 24791, - SPELL_ROYAL_EARTH = 24792, - SPELL_ROYAL_WATER = 24793 -}; - -enum WSGossip -{ - GOSSIPID_LESSER_WS = 6540, - GOSSIPID_WS = 6542, - GOSSIPID_GREATER_WS = 6543 -}; - -enum WSCreatures -{ - NPC_TEMPLAR_FIRE = 15209, - NPC_TEMPLAR_WATER = 15211, - NPC_TEMPLAR_AIR = 15212, - NPC_TEMPLAR_EARTH = 15307, - - NPC_DUKE_FIRE = 15206, - NPC_DUKE_WATER = 15207, - NPC_DUKE_EARTH = 15208, - NPC_DUKE_AIR = 15220, - - NPC_ROYAL_FIRE = 15203, - NPC_ROYAL_AIR = 15204, - NPC_ROYAL_EARTH = 15205, - NPC_ROYAL_WATER = 15305 -}; - -enum WSItems -{ - ITEM_TEMPLAR_FIRE = 20416, - ITEM_TEMPLAR_EARTH = 20419, - ITEM_TEMPLAR_WATER = 20420, - ITEM_TEMPLAR_AIR = 20418, - - ITEM_DUKE_FIRE = 20432, - ITEM_DUKE_EARTH = 20435, - ITEM_DUKE_WATER = 20436, - ITEM_DUKE_AIR = 20433, - - ITEM_ROYAL_FIRE = 20447, - ITEM_ROYAL_EARTH = 20449, - ITEM_ROYAL_WATER = 20450, - ITEM_ROYAL_AIR = 20448, -}; - -enum WS -{ - TEMPLAR = 0, - DUKE = 1, - ROYAL = 2, - - FIRE = 0x1, - WATER = 0x2, - EARTH = 0x4, - AIR = 0x8 -}; - -enum WSTexts -{ - SAY_TEMPLAR_AGGRO = 0, - SAY_DUKE_AGGRO = 0, - YELL_ROYAL_AGGRO = 0 -}; - -#define GOSSIP_TEMPLAR_RANDOM "I am no cultist, you monster! Come to me and face your destruction!" -#define GOSSIP_TEMPLAR_FIRE "Crimson Templar! I hold your signet! Heed my call!" -#define GOSSIP_TEMPLAR_EARTH "Earthen Templar! I hold your signet! Heed my call!" -#define GOSSIP_TEMPLAR_AIR "Hoary Templar! I hold your signet! Heed my call!" -#define GOSSIP_TEMPLAR_WATER "Azure Templar! I hold your signet! Heed my call!" - -#define GOSSIP_DUKE_RANDOM "You will listen to this, vile duke! I am not your Twilight's Hammer lapdog! I am here to challenge you! Come! Come, and meet your death..." -#define GOSSIP_DUKE_FIRE "Duke of Cynders! I hold your signet! Heed my call!" -#define GOSSIP_DUKE_EARTH "The Duke of Shards! I hold your signet! Heed my call!" -#define GOSSIP_DUKE_AIR "The Duke of Zephyrs! I hold your signet! Heed my call!" -#define GOSSIP_DUKE_WATER "The Duke of Fathoms! I hold your signet! Heed my call!" - -#define GOSSIP_ROYAL_RANDOM "The day of the judgement has come, fiend! I challenge you to battle!" -#define GOSSIP_ROYAL_FIRE "Prince Skaldrenox! I hold your signet! Heed my call!" -#define GOSSIP_ROYAL_EARTH "Baron Kazum! I hold your signet! Heed my call!" -#define GOSSIP_ROYAL_AIR "High Marshal Whirlaxis! I hold your signet! Heed my call!" -#define GOSSIP_ROYAL_WATER "Lord Skwol! I hold your signet! Heed my call!" - -class go_wind_stone : public GameObjectScript -{ - public: - go_wind_stone() : GameObjectScript("go_wind_stone") { } - - private: - uint8 GetPlayerRank(Player* player) // For random summoning - { - bool setAura = player->HasAura(AURA_TWILIGHT_SET); - bool medallionAura = player->HasAura(AURA_MEDALLION); - bool ringAura = player->HasAura(AURA_RING); - - if (setAura && medallionAura && ringAura) - return 3; - else if (setAura && medallionAura) - return 2; - else if (setAura) - return 1; - else - return 0; - } - - uint8 GetItems(Player* player, WS type) - { - uint8 result = 0x0; - - switch (type) - { - case TEMPLAR: - { - if (player->HasItemCount(ITEM_TEMPLAR_FIRE)) - result |= FIRE; - if (player->HasItemCount(ITEM_TEMPLAR_WATER)) - result |= WATER; - if (player->HasItemCount(ITEM_TEMPLAR_EARTH)) - result |= EARTH; - if (player->HasItemCount(ITEM_TEMPLAR_AIR)) - result |= AIR; - break; - } - case DUKE: - { - if (player->HasItemCount(ITEM_DUKE_FIRE)) - result |= FIRE; - if (player->HasItemCount(ITEM_DUKE_WATER)) - result |= WATER; - if (player->HasItemCount(ITEM_DUKE_EARTH)) - result |= EARTH; - if (player->HasItemCount(ITEM_DUKE_AIR)) - result |= AIR; - break; - } - case ROYAL: - { - if (player->HasItemCount(ITEM_ROYAL_FIRE)) - result |= FIRE; - if (player->HasItemCount(ITEM_ROYAL_WATER)) - result |= WATER; - if (player->HasItemCount(ITEM_ROYAL_EARTH)) - result |= EARTH; - if (player->HasItemCount(ITEM_ROYAL_AIR)) - result |= AIR; - break; - } - default: - break; - } - return result; - } - - void SummonNPC(GameObject* go, Player* player, uint32 npc, uint32 spell) - { - go->CastSpell(player, spell); - TempSummon* summons = go->SummonCreature(npc, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), player->GetOrientation() - M_PI, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10 * 60 * 1000); - summons->CastSpell(summons, SPELL_SPAWN_IN, false); - switch (summons->GetEntry()) - { - case NPC_TEMPLAR_FIRE: - case NPC_TEMPLAR_WATER: - case NPC_TEMPLAR_AIR: - case NPC_TEMPLAR_EARTH: - summons->AI()->Talk(SAY_TEMPLAR_AGGRO); - break; - - case NPC_DUKE_FIRE: - case NPC_DUKE_WATER: - case NPC_DUKE_EARTH: - case NPC_DUKE_AIR: - summons->AI()->Talk(SAY_DUKE_AGGRO); - break; - case NPC_ROYAL_FIRE: - case NPC_ROYAL_AIR: - case NPC_ROYAL_EARTH: - case NPC_ROYAL_WATER: - summons->AI()->Talk(YELL_ROYAL_AGGRO); - break; - } - summons->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - summons->SendMeleeAttackStart(player); - summons->CombatStart(player); - } - - public: - bool OnGossipHello(Player* player, GameObject* go) - { - uint8 rank = GetPlayerRank(player); - - uint32 gossipId = go->GetGOInfo()->GetGossipMenuId(); - switch (gossipId) - { - case GOSSIPID_LESSER_WS: - { - if (rank >= 1) // 1 or 2 or 3 - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_RANDOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - else - { - go->CastSpell(player, SPELL_PUNISHMENT); - break; - } - - uint8 item = GetItems(player, TEMPLAR); - if (item & FIRE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_FIRE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - if (item & WATER) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_WATER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - if (item & EARTH) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_EARTH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - if (item & AIR) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_AIR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - break; - } - case GOSSIPID_WS: - { - if (rank >= 2) // 2 or 3 - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_RANDOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - else - { - go->CastSpell(player, SPELL_PUNISHMENT); - break; - } - - uint8 item = GetItems(player, DUKE); - if (item & FIRE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_FIRE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - if (item & WATER) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_WATER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); - if (item & EARTH) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_EARTH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); - if (item & AIR) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_AIR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); - break; - } - case GOSSIPID_GREATER_WS: - { - if (rank == 3) // 3 - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_RANDOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - else - { - go->CastSpell(player, SPELL_PUNISHMENT); - break; - } - - uint8 item = GetItems(player, ROYAL); - if (item & FIRE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_FIRE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12); - if (item & WATER) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_WATER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13); - if (item & EARTH) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_EARTH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14); - if (item & AIR) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_AIR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15); - break; - } - default: - break; - } - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(gossipId, go), go->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - player->PlayerTalkClass->SendCloseGossip(); - - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - SummonNPC(go, player, RAND(NPC_TEMPLAR_WATER, NPC_TEMPLAR_FIRE, NPC_TEMPLAR_EARTH, NPC_TEMPLAR_AIR), SPELL_TEMPLAR_RANDOM); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - SummonNPC(go, player, NPC_TEMPLAR_FIRE, SPELL_TEMPLAR_FIRE); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - SummonNPC(go, player, NPC_TEMPLAR_WATER, SPELL_TEMPLAR_WATER); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - SummonNPC(go, player, NPC_TEMPLAR_EARTH, SPELL_TEMPLAR_EARTH); - break; - case GOSSIP_ACTION_INFO_DEF + 5: - SummonNPC(go, player, NPC_TEMPLAR_AIR, SPELL_TEMPLAR_AIR); - break; - - case GOSSIP_ACTION_INFO_DEF + 6: - SummonNPC(go, player, RAND(NPC_DUKE_FIRE, NPC_DUKE_WATER, NPC_DUKE_EARTH, NPC_DUKE_AIR), SPELL_DUKE_RANDOM); - break; - case GOSSIP_ACTION_INFO_DEF + 7: - SummonNPC(go, player, NPC_DUKE_FIRE, SPELL_DUKE_FIRE); - break; - case GOSSIP_ACTION_INFO_DEF + 8: - SummonNPC(go, player, NPC_DUKE_WATER, SPELL_DUKE_WATER); - break; - case GOSSIP_ACTION_INFO_DEF + 9: - SummonNPC(go, player, NPC_DUKE_EARTH, SPELL_DUKE_EARTH); - break; - case GOSSIP_ACTION_INFO_DEF + 10: - SummonNPC(go, player, NPC_DUKE_AIR, SPELL_DUKE_AIR); - break; - - case GOSSIP_ACTION_INFO_DEF + 11: - SummonNPC(go, player, RAND(NPC_ROYAL_FIRE, NPC_ROYAL_AIR, NPC_ROYAL_EARTH, NPC_ROYAL_WATER), SPELL_ROYAL_RANDOM); - break; - case GOSSIP_ACTION_INFO_DEF + 12: - SummonNPC(go, player, NPC_ROYAL_FIRE, SPELL_ROYAL_FIRE); - break; - case GOSSIP_ACTION_INFO_DEF + 13: - SummonNPC(go, player, NPC_ROYAL_WATER, SPELL_ROYAL_WATER); - break; - case GOSSIP_ACTION_INFO_DEF + 14: - SummonNPC(go, player, NPC_ROYAL_EARTH, SPELL_ROYAL_EARTH); - break; - case GOSSIP_ACTION_INFO_DEF + 15: - SummonNPC(go, player, NPC_ROYAL_AIR, SPELL_ROYAL_AIR); - break; - - default: - break; - } - return true; - } -}; - -void AddSC_silithus() -{ - new go_crystalline_tear(); - new npc_anachronos_quest_trigger(); - new npc_anachronos_the_ancient(); - new mob_qiraj_war_spawn(); - new npc_highlord_demitrian(); - new npcs_rutgar_and_frankal(); - new go_wind_stone(); -} diff --git a/src/server/scripts/Kalimdor/stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/stonetalon_mountains.cpp deleted file mode 100644 index 26c92c7404c..00000000000 --- a/src/server/scripts/Kalimdor/stonetalon_mountains.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Stonetalon_Mountains -SD%Complete: 95 -SDComment: Quest support: 6627, 6523 -SDCategory: Stonetalon Mountains -EndScriptData */ - -/* ContentData -npc_braug_dimspirit -npc_kaya_flathoof -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_braug_dimspirit -######*/ - -#define GOSSIP_HBD1 "Ysera" -#define GOSSIP_HBD2 "Neltharion" -#define GOSSIP_HBD3 "Nozdormu" -#define GOSSIP_HBD4 "Alexstrasza" -#define GOSSIP_HBD5 "Malygos" - -class npc_braug_dimspirit : public CreatureScript -{ -public: - npc_braug_dimspirit() : CreatureScript("npc_braug_dimspirit") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, 6766, false); - - } - if (action == GOSSIP_ACTION_INFO_DEF+2) - { - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(6627); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(6627) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(5820, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(5819, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_kaya_flathoof -######*/ - -enum Kaya -{ - FACTION_ESCORTEE_H = 775, - - NPC_GRIMTOTEM_RUFFIAN = 11910, - NPC_GRIMTOTEM_BRUTE = 11912, - NPC_GRIMTOTEM_SORCERER = 11913, - - SAY_START = 0, - SAY_AMBUSH = 1, - SAY_END = 2, - - QUEST_PROTECT_KAYA = 6523 -}; - -class npc_kaya_flathoof : public CreatureScript -{ -public: - npc_kaya_flathoof() : CreatureScript("npc_kaya_flathoof") { } - - struct npc_kaya_flathoofAI : public npc_escortAI - { - npc_kaya_flathoofAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 16: - Talk(SAY_AMBUSH); - me->SummonCreature(NPC_GRIMTOTEM_BRUTE, -48.53f, -503.34f, -46.31f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_GRIMTOTEM_RUFFIAN, -38.85f, -503.77f, -45.90f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - me->SummonCreature(NPC_GRIMTOTEM_SORCERER, -36.37f, -496.23f, -45.71f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 18: - me->SetInFront(player); - Talk(SAY_END); - player->GroupEventHappens(QUEST_PROTECT_KAYA, me); - break; - } - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void Reset(){} - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_PROTECT_KAYA) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_kaya_flathoof::npc_kaya_flathoofAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - - creature->AI()->Talk(SAY_START); - creature->setFaction(113); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kaya_flathoofAI(creature); - } - -}; - -/*###### -## AddSC -######*/ - -void AddSC_stonetalon_mountains() -{ - new npc_braug_dimspirit(); - new npc_kaya_flathoof(); -} diff --git a/src/server/scripts/Kalimdor/tanaris.cpp b/src/server/scripts/Kalimdor/tanaris.cpp deleted file mode 100644 index 0648e40416d..00000000000 --- a/src/server/scripts/Kalimdor/tanaris.cpp +++ /dev/null @@ -1,685 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Tanaris -SD%Complete: 80 -SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor -SDCategory: Tanaris -EndScriptData */ - -/* ContentData -mob_aquementas -npc_custodian_of_time -npc_marin_noggenfogger -npc_steward_of_time -npc_stone_watcher_of_norgannon -npc_OOX17 -npc_tooga -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## mob_aquementas -######*/ - -enum Aquementas -{ - AGGRO_YELL_AQUE = 0, - - SPELL_AQUA_JET = 13586, - SPELL_FROST_SHOCK = 15089 -}; - -class mob_aquementas : public CreatureScript -{ -public: - mob_aquementas() : CreatureScript("mob_aquementas") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_aquementasAI (creature); - } - - struct mob_aquementasAI : public ScriptedAI - { - mob_aquementasAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 SendItemTimer; - uint32 SwitchFactionTimer; - bool isFriendly; - - uint32 FrostShockTimer; - uint32 AquaJetTimer; - - void Reset() - { - SendItemTimer = 0; - SwitchFactionTimer = 10000; - me->setFaction(35); - isFriendly = true; - - AquaJetTimer = 5000; - FrostShockTimer = 1000; - } - - void SendItem(Unit* receiver) - { - if (CAST_PLR(receiver)->HasItemCount(11169, 1, false) && - CAST_PLR(receiver)->HasItemCount(11172, 11, false) && - CAST_PLR(receiver)->HasItemCount(11173, 1, false) && - !CAST_PLR(receiver)->HasItemCount(11522, 1, true)) - { - ItemPosCountVec dest; - uint8 msg = CAST_PLR(receiver)->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 11522, 1, NULL); - if (msg == EQUIP_ERR_OK) - CAST_PLR(receiver)->StoreNewItem(dest, 11522, 1, true); - } - } - - void EnterCombat(Unit* who) - { - Talk(AGGRO_YELL_AQUE, who->GetGUID()); - } - - void UpdateAI(const uint32 diff) - { - if (isFriendly) - { - if (SwitchFactionTimer <= diff) - { - me->setFaction(91); - isFriendly = false; - } else SwitchFactionTimer -= diff; - } - - if (!UpdateVictim()) - return; - - if (!isFriendly) - { - if (SendItemTimer <= diff) - { - if (me->getVictim()->GetTypeId() == TYPEID_PLAYER) - SendItem(me->getVictim()); - SendItemTimer = 5000; - } else SendItemTimer -= diff; - } - - if (FrostShockTimer <= diff) - { - DoCast(me->getVictim(), SPELL_FROST_SHOCK); - FrostShockTimer = 15000; - } else FrostShockTimer -= diff; - - if (AquaJetTimer <= diff) - { - DoCast(me, SPELL_AQUA_JET); - AquaJetTimer = 15000; - } else AquaJetTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - -/*###### -## npc_custodian_of_time -######*/ - -enum CustodianOfTime -{ - WHISPER_CUSTODIAN_1 = 0, - WHISPER_CUSTODIAN_2 = 1, - WHISPER_CUSTODIAN_3 = 2, - WHISPER_CUSTODIAN_4 = 3, - WHISPER_CUSTODIAN_5 = 4, - WHISPER_CUSTODIAN_6 = 5, - WHISPER_CUSTODIAN_7 = 6, - WHISPER_CUSTODIAN_8 = 7, - WHISPER_CUSTODIAN_9 = 8, - WHISPER_CUSTODIAN_10 = 9, - WHISPER_CUSTODIAN_11 = 10, - WHISPER_CUSTODIAN_12 = 11, - WHISPER_CUSTODIAN_13 = 12, - WHISPER_CUSTODIAN_14 = 13 -}; - -class npc_custodian_of_time : public CreatureScript -{ -public: - npc_custodian_of_time() : CreatureScript("npc_custodian_of_time") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_custodian_of_timeAI(creature); - } - - struct npc_custodian_of_timeAI : public npc_escortAI - { - npc_custodian_of_timeAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 0: - Talk(WHISPER_CUSTODIAN_1, player->GetGUID()); - break; - case 1: - Talk(WHISPER_CUSTODIAN_2, player->GetGUID()); - break; - case 2: - Talk(WHISPER_CUSTODIAN_3, player->GetGUID()); - break; - case 3: - Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); - break; - case 5: - Talk(WHISPER_CUSTODIAN_5, player->GetGUID()); - break; - case 6: - Talk(WHISPER_CUSTODIAN_6, player->GetGUID()); - break; - case 7: - Talk(WHISPER_CUSTODIAN_7, player->GetGUID()); - break; - case 8: - Talk(WHISPER_CUSTODIAN_8, player->GetGUID()); - break; - case 9: - Talk(WHISPER_CUSTODIAN_9, player->GetGUID()); - break; - case 10: - Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); - break; - case 13: - Talk(WHISPER_CUSTODIAN_10, player->GetGUID()); - break; - case 14: - Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); - break; - case 16: - Talk(WHISPER_CUSTODIAN_11, player->GetGUID()); - break; - case 17: - Talk(WHISPER_CUSTODIAN_12, player->GetGUID()); - break; - case 18: - Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); - break; - case 22: - Talk(WHISPER_CUSTODIAN_13, player->GetGUID()); - break; - case 23: - Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); - break; - case 24: - Talk(WHISPER_CUSTODIAN_14, player->GetGUID()); - DoCast(player, 34883); - // below here is temporary workaround, to be removed when spell works properly - player->AreaExploredOrEventHappens(10277); - break; - } - } - } - - void MoveInLineOfSight(Unit* who) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - return; - - if (who->GetTypeId() == TYPEID_PLAYER) - { - if (who->HasAura(34877) && CAST_PLR(who)->GetQuestStatus(10277) == QUEST_STATUS_INCOMPLETE) - { - float Radius = 10.0f; - if (me->IsWithinDistInMap(who, Radius)) - { - Start(false, false, who->GetGUID()); - } - } - } - } - - void EnterCombat(Unit* /*who*/) {} - void Reset() {} - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - } - }; - -}; - -/*###### -## npc_marin_noggenfogger -######*/ - -class npc_marin_noggenfogger : public CreatureScript -{ -public: - npc_marin_noggenfogger() : CreatureScript("npc_marin_noggenfogger") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor() && player->GetQuestRewardStatus(2662)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_steward_of_time -######*/ - -#define GOSSIP_ITEM_FLIGHT "Please take me to the master's lair." - -class npc_steward_of_time : public CreatureScript -{ -public: - npc_steward_of_time() : CreatureScript("npc_steward_of_time") { } - - bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) - { - if (quest->GetQuestId() == 10279) //Quest: To The Master's Lair - player->CastSpell(player, 34891, true); //(Flight through Caverns) - - return false; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - player->CastSpell(player, 34891, true); //(Flight through Caverns) - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(10279) == QUEST_STATUS_INCOMPLETE || player->GetQuestRewardStatus(10279)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(9978, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(9977, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_stone_watcher_of_norgannon -######*/ - -#define GOSSIP_ITEM_NORGANNON_1 "What function do you serve?" -#define GOSSIP_ITEM_NORGANNON_2 "What are the Plates of Uldum?" -#define GOSSIP_ITEM_NORGANNON_3 "Where are the Plates of Uldum?" -#define GOSSIP_ITEM_NORGANNON_4 "Excuse me? We've been \"reschedueled for visitations\"? What does that mean?!" -#define GOSSIP_ITEM_NORGANNON_5 "So, what's inside Uldum?" -#define GOSSIP_ITEM_NORGANNON_6 "I will return when i have the Plates of Uldum." - -class npc_stone_watcher_of_norgannon : public CreatureScript -{ -public: - npc_stone_watcher_of_norgannon() : CreatureScript("npc_stone_watcher_of_norgannon") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(1675, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(1676, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(1677, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(1678, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(1679, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(2954); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(2954) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(1674, creature->GetGUID()); - - return true; - } - -}; - -/*###### -## npc_OOX17 -######*/ - -enum Npc00X17 -{ - SAY_OOX_START = 0, - SAY_OOX_AGGRO = 1, - SAY_OOX_AMBUSH = 2, - SAY_OOX17_AMBUSH_REPLY = 0, - SAY_OOX_END = 3, - - Q_OOX17 = 648, - SPAWN_FIRST = 7803, - SPAWN_SECOND_1 = 5617, - SPAWN_SECOND_2 = 7805 -}; - -class npc_OOX17 : public CreatureScript -{ -public: - npc_OOX17() : CreatureScript("npc_OOX17") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == Q_OOX17) - { - creature->setFaction(113); - creature->SetFullHealth(); - creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - creature->AI()->Talk(SAY_OOX_START); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_OOX17::npc_OOX17AI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_OOX17AI(creature); - } - - struct npc_OOX17AI : public npc_escortAI - { - npc_OOX17AI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 23: - me->SummonCreature(SPAWN_FIRST, -8350.96f, -4445.79f, 10.10f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_FIRST, -8355.96f, -4447.79f, 10.10f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_FIRST, -8353.96f, -4442.79f, 10.10f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_OOX_AMBUSH); - break; - case 56: - me->SummonCreature(SPAWN_SECOND_1, -7510.07f, -4795.50f, 9.35f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_SECOND_2, -7515.07f, -4797.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_SECOND_2, -7518.07f, -4792.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_OOX_AMBUSH); - if (Creature* scoff = me->FindNearestCreature(SPAWN_SECOND_2, 30)) - scoff->AI()->Talk(SAY_OOX17_AMBUSH_REPLY); - break; - case 86: - Talk(SAY_OOX_END); - player->GroupEventHappens(Q_OOX17, me); - break; - } - } - } - - void Reset(){} - - void EnterCombat(Unit* /*who*/) - { - Talk(SAY_OOX_AGGRO); - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - }; -}; - -/*#### -# npc_tooga -####*/ - -enum Tooga -{ - SAY_TOOG_WORRIED = 0, - SAY_TOOG_POST_1 = 1, - SAY_TORT_POST_2 = 0, - SAY_TOOG_POST_3 = 2, - SAY_TORT_POST_4 = 1, - SAY_TOOG_POST_5 = 3, - SAY_TORT_POST_6 = 2, - - QUEST_TOOGA = 1560, - NPC_TORTA = 6015, - - POINT_ID_TO_WATER = 1, - FACTION_TOOG_ESCORTEE = 113 -}; - -Position const ToWaterLoc = {-7032.664551f, -4906.199219f, -1.606446f, 0.0f}; - -class npc_tooga : public CreatureScript -{ -public: - npc_tooga() : CreatureScript("npc_tooga") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_TOOGA) - { - if (npc_toogaAI* pToogaAI = CAST_AI(npc_tooga::npc_toogaAI, creature->AI())) - pToogaAI->StartFollow(player, FACTION_TOOG_ESCORTEE, quest); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_toogaAI(creature); - } - - struct npc_toogaAI : public FollowerAI - { - npc_toogaAI(Creature* creature) : FollowerAI(creature) { } - - uint32 CheckSpeechTimer; - uint32 PostEventTimer; - uint32 PhasePostEvent; - - uint64 TortaGUID; - - void Reset() - { - CheckSpeechTimer = 2500; - PostEventTimer = 1000; - PhasePostEvent = 0; - - TortaGUID = 0; - } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE | STATE_FOLLOW_POSTEVENT) && who->GetEntry() == NPC_TORTA) - { - if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) - { - Player* player = GetLeaderForFollower(); - if (player && player->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_TOOGA, me); - - TortaGUID = who->GetGUID(); - SetFollowComplete(true); - } - } - } - - void MovementInform(uint32 MotionType, uint32 PointId) - { - FollowerAI::MovementInform(MotionType, PointId); - - if (MotionType != POINT_MOTION_TYPE) - return; - - if (PointId == POINT_ID_TO_WATER) - SetFollowComplete(); - } - - void UpdateFollowerAI(const uint32 Diff) - { - if (!UpdateVictim()) - { - //we are doing the post-event, or... - if (HasFollowState(STATE_FOLLOW_POSTEVENT)) - { - if (PostEventTimer <= Diff) - { - PostEventTimer = 5000; - - Creature* torta = Creature::GetCreature(*me, TortaGUID); - if (!torta || !torta->isAlive()) - { - //something happened, so just complete - SetFollowComplete(); - return; - } - - switch (PhasePostEvent) - { - case 1: - Talk(SAY_TOOG_POST_1); - break; - case 2: - torta->AI()->Talk(SAY_TORT_POST_2); - break; - case 3: - Talk(SAY_TOOG_POST_3); - break; - case 4: - torta->AI()->Talk(SAY_TORT_POST_4); - break; - case 5: - Talk(SAY_TOOG_POST_5); - break; - case 6: - torta->AI()->Talk(SAY_TORT_POST_6); - me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, ToWaterLoc); - break; - } - - ++PhasePostEvent; - } - else - PostEventTimer -= Diff; - } - //...we are doing regular speech check - else if (HasFollowState(STATE_FOLLOW_INPROGRESS)) - { - if (CheckSpeechTimer <= Diff) - { - CheckSpeechTimer = 5000; - - if (urand(0, 9) > 8) - Talk(SAY_TOOG_WORRIED); - } - else - CheckSpeechTimer -= Diff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; - -}; - -void AddSC_tanaris() -{ - new mob_aquementas(); - new npc_custodian_of_time(); - new npc_marin_noggenfogger(); - new npc_steward_of_time(); - new npc_stone_watcher_of_norgannon(); - new npc_OOX17(); - new npc_tooga(); -} diff --git a/src/server/scripts/Kalimdor/teldrassil.cpp b/src/server/scripts/Kalimdor/teldrassil.cpp deleted file mode 100644 index d7983c2cbe6..00000000000 --- a/src/server/scripts/Kalimdor/teldrassil.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Teldrassil -SD%Complete: 100 -SDComment: Quest support: 938 -SDCategory: Teldrassil -EndScriptData */ - -/* ContentData -npc_mist -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" - -/*#### -# npc_mist -####*/ - -enum Mist -{ - SAY_AT_HOME = 0, - EMOTE_AT_HOME = 1, - QUEST_MIST = 938, - NPC_ARYNIA = 3519, - FACTION_DARNASSUS = 79 -}; - -class npc_mist : public CreatureScript -{ -public: - npc_mist() : CreatureScript("npc_mist") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_MIST) - if (npc_mistAI* pMistAI = CAST_AI(npc_mist::npc_mistAI, creature->AI())) - pMistAI->StartFollow(player, FACTION_DARNASSUS, quest); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_mistAI(creature); - } - - struct npc_mistAI : public FollowerAI - { - npc_mistAI(Creature* creature) : FollowerAI(creature) { } - - void Reset() { } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_ARYNIA) - { - if (me->IsWithinDistInMap(who, 10.0f)) - { - Talk(SAY_AT_HOME, who->GetGUID()); - DoComplete(); - } - } - } - - void DoComplete() - { - Talk(EMOTE_AT_HOME); - - Player* player = GetLeaderForFollower(); - if (player && player->GetQuestStatus(QUEST_MIST) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_MIST, me); - - //The follow is over (and for later development, run off to the woods before really end) - SetFollowComplete(); - } - - //call not needed here, no known abilities - /*void UpdateFollowerAI(const uint32 Diff) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - }*/ - }; - -}; - -void AddSC_teldrassil() -{ - new npc_mist(); -} diff --git a/src/server/scripts/Kalimdor/the_barrens.cpp b/src/server/scripts/Kalimdor/the_barrens.cpp deleted file mode 100644 index 8f7ab09260b..00000000000 --- a/src/server/scripts/Kalimdor/the_barrens.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: The_Barrens -SD%Complete: 90 -SDComment: Quest support: 863, 898, 1719, 2458, 4921, 6981, -SDCategory: Barrens -EndScriptData */ - -/* ContentData -npc_beaten_corpse -npc_gilthares -npc_sputtervalve -npc_taskmaster_fizzule -npc_twiggy_flathead -npc_wizzlecrank_shredder -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "SpellInfo.h" - -/*###### -## npc_beaten_corpse -######*/ - -#define GOSSIP_CORPSE "Examine corpse in detail..." - -enum BeatenCorpse -{ - QUEST_LOST_IN_BATTLE = 4921 -}; - -class npc_beaten_corpse : public CreatureScript -{ -public: - npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF +1) - { - player->SEND_GOSSIP_MENU(3558, creature->GetGUID()); - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_COMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CORPSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(3557, creature->GetGUID()); - return true; - } - -}; - -/*###### -# npc_gilthares -######*/ - -enum Gilthares -{ - SAY_GIL_START = 0, - SAY_GIL_AT_LAST = 1, - SAY_GIL_PROCEED = 2, - SAY_GIL_FREEBOOTERS = 3, - SAY_GIL_AGGRO = 4, - SAY_GIL_ALMOST = 5, - SAY_GIL_SWEET = 6, - SAY_GIL_FREED = 7, - - QUEST_FREE_FROM_HOLD = 898, - AREA_MERCHANT_COAST = 391, - FACTION_ESCORTEE = 232 //guessed, possible not needed for this quest -}; - -class npc_gilthares : public CreatureScript -{ -public: - npc_gilthares() : CreatureScript("npc_gilthares") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_FREE_FROM_HOLD) - { - creature->setFaction(FACTION_ESCORTEE); - creature->SetStandState(UNIT_STAND_STATE_STAND); - - creature->AI()->Talk(SAY_GIL_START, player->GetGUID()); - - if (npc_giltharesAI* pEscortAI = CAST_AI(npc_gilthares::npc_giltharesAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_giltharesAI(creature); - } - - struct npc_giltharesAI : public npc_escortAI - { - npc_giltharesAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() { } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 16: - Talk(SAY_GIL_AT_LAST, player->GetGUID()); - break; - case 17: - Talk(SAY_GIL_PROCEED, player->GetGUID()); - break; - case 18: - Talk(SAY_GIL_FREEBOOTERS, player->GetGUID()); - break; - case 37: - Talk(SAY_GIL_ALMOST,player->GetGUID()); - break; - case 47: - Talk(SAY_GIL_SWEET, player->GetGUID()); - break; - case 53: - Talk(SAY_GIL_FREED, player->GetGUID()); - player->GroupEventHappens(QUEST_FREE_FROM_HOLD, me); - break; - } - } - - void EnterCombat(Unit* who) - { - //not always use - if (rand()%4) - return; - - //only aggro text if not player and only in this area - if (who->GetTypeId() != TYPEID_PLAYER && me->GetAreaId() == AREA_MERCHANT_COAST) - { - //appears to be pretty much random (possible only if escorter not in combat with who yet?) - Talk(SAY_GIL_AGGRO, who->GetGUID()); - } - } - }; - -}; - -/*###### -## npc_sputtervalve -######*/ - -#define GOSSIP_SPUTTERVALVE "Can you tell me about this shard?" - -class npc_sputtervalve : public CreatureScript -{ -public: - npc_sputtervalve() : CreatureScript("npc_sputtervalve") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->SEND_GOSSIP_MENU(2013, creature->GetGUID()); - player->AreaExploredOrEventHappens(6981); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(6981) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SPUTTERVALVE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - -}; - -/*###### -## npc_taskmaster_fizzule -######*/ - -enum TaskmasterFizzule -{ - FACTION_FRIENDLY_F = 35, - SPELL_FLARE = 10113, - SPELL_FOLLY = 10137, -}; - -class npc_taskmaster_fizzule : public CreatureScript -{ -public: - npc_taskmaster_fizzule() : CreatureScript("npc_taskmaster_fizzule") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_taskmaster_fizzuleAI(creature); - } - - struct npc_taskmaster_fizzuleAI : public ScriptedAI - { - npc_taskmaster_fizzuleAI(Creature* creature) : ScriptedAI(creature) - { - factionNorm = creature->getFaction(); - } - - uint32 factionNorm; - bool IsFriend; - uint32 ResetTimer; - uint8 FlareCount; - - void Reset() - { - IsFriend = false; - ResetTimer = 120000; - FlareCount = 0; - me->setFaction(factionNorm); - } - - void DoFriend() - { - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(true); - - me->StopMoving(); - me->GetMotionMaster()->MoveIdle(); - - me->setFaction(FACTION_FRIENDLY_F); - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - } - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) - { - if (spell->Id == SPELL_FLARE || spell->Id == SPELL_FOLLY) - { - ++FlareCount; - - if (FlareCount >= 2) - IsFriend = true; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (IsFriend) - { - if (ResetTimer <= diff) - { - EnterEvadeMode(); - return; - } else ResetTimer -= diff; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void ReceiveEmote(Player* /*player*/, uint32 emote) - { - if (emote == TEXT_EMOTE_SALUTE) - { - if (FlareCount >= 2) - { - if (me->getFaction() == FACTION_FRIENDLY_F) - return; - - DoFriend(); - } - } - } - }; - -}; - -/*##### -## npc_twiggy_flathead -#####*/ - -enum TwiggyFlathead -{ - NPC_BIG_WILL = 6238, - NPC_AFFRAY_CHALLENGER = 6240, - - SAY_BIG_WILL_READY = 0, - SAY_TWIGGY_FLATHEAD_BEGIN = 0, - SAY_TWIGGY_FLATHEAD_FRAY = 1, - SAY_TWIGGY_FLATHEAD_DOWN = 2, - SAY_TWIGGY_FLATHEAD_OVER = 3 -}; - -Position const AffrayChallengerLoc[6] = -{ - {-1683.0f, -4326.0f, 2.79f, 0.0f}, - {-1682.0f, -4329.0f, 2.79f, 0.0f}, - {-1683.0f, -4330.0f, 2.79f, 0.0f}, - {-1680.0f, -4334.0f, 2.79f, 1.49f}, - {-1674.0f, -4326.0f, 2.79f, 3.49f}, - {-1677.0f, -4334.0f, 2.79f, 1.66f} -}; - -class npc_twiggy_flathead : public CreatureScript -{ -public: - npc_twiggy_flathead() : CreatureScript("npc_twiggy_flathead") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_twiggy_flatheadAI (creature); - } - - struct npc_twiggy_flatheadAI : public ScriptedAI - { - npc_twiggy_flatheadAI(Creature* creature) : ScriptedAI(creature) {} - - bool EventInProgress; - bool EventGrate; - bool EventBigWill; - bool ChallengerDown[6]; - uint8 Wave; - uint32 WaveTimer; - uint32 ChallengerChecker; - uint64 PlayerGUID; - uint64 AffrayChallenger[6]; - uint64 BigWill; - - void Reset() - { - EventInProgress = false; - EventGrate = false; - EventBigWill = false; - WaveTimer = 600000; - ChallengerChecker = 0; - Wave = 0; - PlayerGUID = 0; - - for (uint8 i = 0; i < 6; ++i) - { - AffrayChallenger[i] = 0; - ChallengerDown[i] = false; - } - BigWill = 0; - } - - void EnterCombat(Unit* /*who*/) { } - - void MoveInLineOfSight(Unit* who) - { - if (!who || (!who->isAlive())) - return; - - if (me->IsWithinDistInMap(who, 10.0f) && (who->GetTypeId() == TYPEID_PLAYER) && CAST_PLR(who)->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE && !EventInProgress) - { - PlayerGUID = who->GetGUID(); - EventInProgress = true; - } - } - - void KilledUnit(Unit* /*victim*/) { } - - void UpdateAI(const uint32 diff) - { - if (EventInProgress) { - Player* pWarrior = NULL; - - if (PlayerGUID) - pWarrior = Unit::GetPlayer(*me, PlayerGUID); - - if (!pWarrior) - return; - - if (!pWarrior->isAlive() && pWarrior->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE) { - Talk(SAY_TWIGGY_FLATHEAD_DOWN); - pWarrior->FailQuest(1719); - - for (uint8 i = 0; i < 6; ++i) // unsummon challengers - { - if (AffrayChallenger[i]) - { - Creature* creature = Unit::GetCreature((*me), AffrayChallenger[i]); - if (creature && creature->isAlive()) - creature->DisappearAndDie(); - } - } - - if (BigWill) // unsummon bigWill - { - Creature* creature = Unit::GetCreature((*me), BigWill); - if (creature && creature->isAlive()) - creature->DisappearAndDie(); - } - Reset(); - } - - if (!EventGrate && EventInProgress) - { - float x, y, z; - pWarrior->GetPosition(x, y, z); - - if (x >= -1684 && x <= -1674 && y >= -4334 && y <= -4324) { - pWarrior->AreaExploredOrEventHappens(1719); - Talk(SAY_TWIGGY_FLATHEAD_BEGIN, pWarrior->GetGUID()); - - for (uint8 i = 0; i < 6; ++i) - { - Creature* creature = me->SummonCreature(NPC_AFFRAY_CHALLENGER, AffrayChallengerLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); - if (!creature) - continue; - creature->setFaction(35); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - AffrayChallenger[i] = creature->GetGUID(); - } - WaveTimer = 5000; - ChallengerChecker = 1000; - EventGrate = true; - } - } - else if (EventInProgress) - { - if (ChallengerChecker <= diff) - { - for (uint8 i = 0; i < 6; ++i) - { - if (AffrayChallenger[i]) - { - Creature* creature = Unit::GetCreature((*me), AffrayChallenger[i]); - if ((!creature || (!creature->isAlive())) && !ChallengerDown[i]) - { - Talk(SAY_TWIGGY_FLATHEAD_DOWN); - ChallengerDown[i] = true; - } - } - } - ChallengerChecker = 1000; - } else ChallengerChecker -= diff; - - if (WaveTimer <= diff) - { - if (Wave < 6 && AffrayChallenger[Wave] && !EventBigWill) - { - Talk(SAY_TWIGGY_FLATHEAD_FRAY); - Creature* creature = Unit::GetCreature((*me), AffrayChallenger[Wave]); - if (creature && (creature->isAlive())) - { - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - creature->setFaction(14); - creature->AI()->AttackStart(pWarrior); - ++Wave; - WaveTimer = 20000; - } - } - else if (Wave >= 6 && !EventBigWill) { - if (Creature* creature = me->SummonCreature(NPC_BIG_WILL, -1722, -4341, 6.12f, 6.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 480000)) - { - BigWill = creature->GetGUID(); - //creature->GetMotionMaster()->MovePoint(0, -1693, -4343, 4.32f); - //creature->GetMotionMaster()->MovePoint(1, -1684, -4333, 2.78f); - creature->GetMotionMaster()->MovePoint(2, -1682, -4329, 2.79f); - creature->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED); - EventBigWill = true; - WaveTimer = 1000; - } - } - else if (Wave >= 6 && EventBigWill && BigWill) - { - Creature* creature = Unit::GetCreature((*me), BigWill); - if (!creature || !creature->isAlive()) - { - Talk(SAY_TWIGGY_FLATHEAD_OVER); - Reset(); - } - } - } else WaveTimer -= diff; - } - } - } - }; - -}; - -/*##### -## npc_wizzlecrank_shredder -#####*/ - -enum Wizzlecrank -{ - SAY_MERCENARY = 0, - SAY_START = 0, - SAY_STARTUP1 = 1, - SAY_STARTUP2 = 2, - SAY_PROGRESS_1 = 3, - SAY_PROGRESS_2 = 4, - SAY_PROGRESS_3 = 5, - SAY_END = 6, - - QUEST_ESCAPE = 863, - FACTION_RATCHET = 637, - NPC_PILOT_WIZZ = 3451, - NPC_MERCENARY = 3282, -}; - -class npc_wizzlecrank_shredder : public CreatureScript -{ -public: - npc_wizzlecrank_shredder() : CreatureScript("npc_wizzlecrank_shredder") { } - - struct npc_wizzlecrank_shredderAI : public npc_escortAI - { - npc_wizzlecrank_shredderAI(Creature* creature) : npc_escortAI(creature) - { - IsPostEvent = false; - PostEventTimer = 1000; - PostEventCount = 0; - } - - bool IsPostEvent; - uint32 PostEventTimer; - uint32 PostEventCount; - - void Reset() - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (me->getStandState() == UNIT_STAND_STATE_DEAD) - me->SetStandState(UNIT_STAND_STATE_STAND); - - IsPostEvent = false; - PostEventTimer = 1000; - PostEventCount = 0; - } - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 0: - Talk(SAY_STARTUP1); - break; - case 9: - SetRun(false); - break; - case 17: - if (Creature* temp = me->SummonCreature(NPC_MERCENARY, 1128.489f, -3037.611f, 92.701f, 1.472f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000)) - { - temp->AI()->Talk(SAY_MERCENARY); - me->SummonCreature(NPC_MERCENARY, 1160.172f, -2980.168f, 97.313f, 3.690f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - } - break; - case 24: - IsPostEvent = true; - break; - } - } - - void WaypointStart(uint32 PointId) - { - Player* player = GetPlayerForEscort(); - - if (!player) - return; - - switch (PointId) - { - case 9: - Talk(SAY_STARTUP2, player->GetGUID()); - break; - case 18: - Talk(SAY_PROGRESS_1, player->GetGUID()); - SetRun(); - break; - } - } - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == NPC_PILOT_WIZZ) - me->SetStandState(UNIT_STAND_STATE_DEAD); - - if (summoned->GetEntry() == NPC_MERCENARY) - summoned->AI()->AttackStart(me); - } - - void UpdateEscortAI(const uint32 Diff) - { - if (!UpdateVictim()) - { - if (IsPostEvent) - { - if (PostEventTimer <= Diff) - { - switch (PostEventCount) - { - case 0: - Talk(SAY_PROGRESS_2); - break; - case 1: - Talk(SAY_PROGRESS_3); - break; - case 2: - Talk(SAY_END); - break; - case 3: - if (Player* player = GetPlayerForEscort()) - { - player->GroupEventHappens(QUEST_ESCAPE, me); - me->SummonCreature(NPC_PILOT_WIZZ, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 180000); - } - break; - } - - ++PostEventCount; - PostEventTimer = 5000; - } - else - PostEventTimer -= Diff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPE) - { - creature->setFaction(FACTION_RATCHET); - if (npc_escortAI* pEscortAI = CAST_AI(npc_wizzlecrank_shredder::npc_wizzlecrank_shredderAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_wizzlecrank_shredderAI(creature); - } - -}; - -void AddSC_the_barrens() -{ - new npc_beaten_corpse(); - new npc_gilthares(); - new npc_sputtervalve(); - new npc_taskmaster_fizzule(); - new npc_twiggy_flathead(); - new npc_wizzlecrank_shredder(); -} diff --git a/src/server/scripts/Kalimdor/thousand_needles.cpp b/src/server/scripts/Kalimdor/thousand_needles.cpp deleted file mode 100644 index 9c47991a5d5..00000000000 --- a/src/server/scripts/Kalimdor/thousand_needles.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Thousand Needles -SD%Complete: 100 -SDComment: Support for Quest: 1950, 4770, 4904, 4966, 5151. -SDCategory: Thousand Needles -EndScriptData */ - -/* ContentData -npc_kanati -npc_lakota_windsong -npc_swiftmountain -npc_plucky -npc_enraged_panther -go_panther_cage -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*##### -# npc_kanati -######*/ - -enum Kanati -{ - SAY_KAN_START = 0, - - QUEST_PROTECT_KANATI = 4966, - NPC_GALAK_ASS = 10720 -}; - -Position const GalakLoc = {-4867.387695f, -1357.353760f, -48.226f, 0.0f}; - -class npc_kanati : public CreatureScript -{ -public: - npc_kanati() : CreatureScript("npc_kanati") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_PROTECT_KANATI) - if (npc_kanatiAI* pEscortAI = CAST_AI(npc_kanati::npc_kanatiAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest, true); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kanatiAI(creature); - } - - struct npc_kanatiAI : public npc_escortAI - { - npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() {} - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 0: - Talk(SAY_KAN_START); - DoSpawnGalak(); - break; - case 1: - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_PROTECT_KANATI, me); - break; - } - } - - void DoSpawnGalak() - { - for (int i = 0; i < 3; ++i) - me->SummonCreature(NPC_GALAK_ASS, GalakLoc, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - }; - -}; - -/*###### -# npc_lakota_windsong -######*/ - -enum Lakota -{ - SAY_LAKO_START = 0, - SAY_LAKO_LOOK_OUT = 1, - SAY_LAKO_HERE_COME = 2, - SAY_LAKO_MORE = 3, - SAY_LAKO_END = 4, - - QUEST_FREE_AT_LAST = 4904, - NPC_GRIM_BANDIT = 10758, - FACTION_ESCORTEE_LAKO = 232, //guessed - - ID_AMBUSH_1 = 0, - ID_AMBUSH_2 = 2, - ID_AMBUSH_3 = 4 -}; - -Position const BanditLoc[6] = -{ - {-4905.479492f, -2062.732666f, 84.352f, 0.0f}, - {-4915.201172f, -2073.528320f, 84.733f, 0.0f}, - {-4878.883301f, -1986.947876f, 91.966f, 0.0f}, - {-4877.503906f, -1966.113403f, 91.859f, 0.0f}, - {-4767.985352f, -1873.169189f, 90.192f, 0.0f}, - {-4788.861328f, -1888.007813f, 89.888f, 0.0f} -}; - -class npc_lakota_windsong : public CreatureScript -{ -public: - npc_lakota_windsong() : CreatureScript("npc_lakota_windsong") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_FREE_AT_LAST) - { - creature->AI()->Talk(SAY_LAKO_START, player->GetGUID()); - creature->setFaction(FACTION_ESCORTEE_LAKO); - - if (npc_lakota_windsongAI* pEscortAI = CAST_AI(npc_lakota_windsong::npc_lakota_windsongAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lakota_windsongAI(creature); - } - - struct npc_lakota_windsongAI : public npc_escortAI - { - npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() {} - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 8: - Talk(SAY_LAKO_LOOK_OUT); - DoSpawnBandits(ID_AMBUSH_1); - break; - case 14: - Talk(SAY_LAKO_HERE_COME); - DoSpawnBandits(ID_AMBUSH_2); - break; - case 21: - Talk(SAY_LAKO_MORE); - DoSpawnBandits(ID_AMBUSH_3); - break; - case 45: - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_FREE_AT_LAST, me); - break; - } - } - - void DoSpawnBandits(int AmbushId) - { - for (int i = 0; i < 2; ++i) - me->SummonCreature(NPC_GRIM_BANDIT, BanditLoc[i+AmbushId], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); - } - }; - -}; - -/*###### -# npc_paoka_swiftmountain -######*/ - -enum Packa -{ - SAY_START = 0, - SAY_WYVERN = 1, - SAY_COMPLETE = 2, - - QUEST_HOMEWARD = 4770, - NPC_WYVERN = 4107, - FACTION_ESCORTEE = 232 //guessed -}; - -Position const WyvernLoc[3] = -{ - {-4990.606f, -906.057f, -5.343f, 0.0f}, - {-4970.241f, -927.378f, -4.951f, 0.0f}, - {-4985.364f, -952.528f, -5.199f, 0.0f} -}; - -class npc_paoka_swiftmountain : public CreatureScript -{ -public: - npc_paoka_swiftmountain() : CreatureScript("npc_paoka_swiftmountain") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_HOMEWARD) - { - creature->AI()->Talk(SAY_START, player->GetGUID()); - creature->setFaction(FACTION_ESCORTEE); - - if (npc_paoka_swiftmountainAI* pEscortAI = CAST_AI(npc_paoka_swiftmountain::npc_paoka_swiftmountainAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_paoka_swiftmountainAI(creature); - } - - struct npc_paoka_swiftmountainAI : public npc_escortAI - { - npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() {} - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 15: - Talk(SAY_WYVERN); - DoSpawnWyvern(); - break; - case 26: - Talk(SAY_COMPLETE); - break; - case 27: - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_HOMEWARD, me); - break; - } - } - - void DoSpawnWyvern() - { - for (int i = 0; i < 3; ++i) - me->SummonCreature(NPC_WYVERN, WyvernLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); - } - }; -}; - -/*##### -# npc_plucky -######*/ - -#define GOSSIP_P "Please tell me the Phrase.." - -enum Plucky -{ - FACTION_FRIENDLY = 35, - QUEST_SCOOP = 1950, - SPELL_PLUCKY_HUMAN = 9192, - SPELL_PLUCKY_CHICKEN = 9220 -}; - -class npc_plucky : public CreatureScript -{ -public: - npc_plucky() : CreatureScript("npc_plucky") { } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->CLOSE_GOSSIP_MENU(); - player->CompleteQuest(QUEST_SCOOP); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_P, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(738, creature->GetGUID()); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_pluckyAI(creature); - } - - struct npc_pluckyAI : public ScriptedAI - { - npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { NormFaction = creature->getFaction(); } - - uint32 NormFaction; - uint32 ResetTimer; - - void Reset() - { - ResetTimer = 120000; - - if (me->getFaction() != NormFaction) - me->setFaction(NormFaction); - - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - DoCast(me, SPELL_PLUCKY_CHICKEN, false); - } - - void ReceiveEmote(Player* player, uint32 TextEmote) - { - if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) - { - if (TextEmote == TEXT_EMOTE_BECKON) - { - me->setFaction(FACTION_FRIENDLY); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - DoCast(me, SPELL_PLUCKY_HUMAN, false); - } - } - - if (TextEmote == TEXT_EMOTE_CHICKEN) - { - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - return; - else - { - me->setFaction(FACTION_FRIENDLY); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - DoCast(me, SPELL_PLUCKY_HUMAN, false); - me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); - } - } - } - - void UpdateAI(const uint32 Diff) - { - if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - { - if (ResetTimer <= Diff) - { - if (!me->getVictim()) - EnterEvadeMode(); - else - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - return; - } - else - ResetTimer -= Diff; - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - -enum PantherCage -{ - ENRAGED_PANTHER = 10992 -}; - -class go_panther_cage : public GameObjectScript -{ -public: - go_panther_cage() : GameObjectScript("go_panther_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - if (player->GetQuestStatus(5151) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* panther = go->FindNearestCreature(ENRAGED_PANTHER, 5, true)) - { - panther->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - panther->SetReactState(REACT_AGGRESSIVE); - panther->AI()->AttackStart(player); - } - } - - return true; - } -}; - -class npc_enraged_panther : public CreatureScript -{ -public: - npc_enraged_panther() : CreatureScript("npc_enraged_panther") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_enraged_pantherAI(creature); - } - - struct npc_enraged_pantherAI : public ScriptedAI - { - npc_enraged_pantherAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); - } - - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - -void AddSC_thousand_needles() -{ - new npc_kanati(); - new npc_lakota_windsong(); - new npc_paoka_swiftmountain(); - new npc_plucky(); - new npc_enraged_panther(); - new go_panther_cage(); -} diff --git a/src/server/scripts/Kalimdor/thunder_bluff.cpp b/src/server/scripts/Kalimdor/thunder_bluff.cpp deleted file mode 100644 index 0d915dc7c44..00000000000 --- a/src/server/scripts/Kalimdor/thunder_bluff.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Thunder_Bluff -SD%Complete: 100 -SDComment: Quest support: 925 -SDCategory: Thunder Bluff -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" - -/*##### -# npc_cairne_bloodhoof -######*/ - -enum CairneBloodhoof -{ - SPELL_BERSERKER_CHARGE = 16636, - SPELL_CLEAVE = 16044, - SPELL_MORTAL_STRIKE = 16856, - SPELL_THUNDERCLAP = 23931, - SPELL_UPPERCUT = 22916 -}; - -#define GOSSIP_HCB "I know this is rather silly but a young ward who is a bit shy would like your hoofprint." -//TODO: verify abilities/timers -class npc_cairne_bloodhoof : public CreatureScript -{ -public: - npc_cairne_bloodhoof() : CreatureScript("npc_cairne_bloodhoof") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_SENDER_INFO) - { - player->CastSpell(player, 23123, false); - player->SEND_GOSSIP_MENU(7014, creature->GetGUID()); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(925) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HCB, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); - - player->SEND_GOSSIP_MENU(7013, creature->GetGUID()); - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_cairne_bloodhoofAI (creature); - } - - struct npc_cairne_bloodhoofAI : public ScriptedAI - { - npc_cairne_bloodhoofAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 BerserkerChargeTimer; - uint32 CleaveTimer; - uint32 MortalStrikeTimer; - uint32 ThunderclapTimer; - uint32 UppercutTimer; - - void Reset() - { - BerserkerChargeTimer = 30000; - CleaveTimer = 5000; - MortalStrikeTimer = 10000; - ThunderclapTimer = 15000; - UppercutTimer = 10000; - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (BerserkerChargeTimer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - DoCast(target, SPELL_BERSERKER_CHARGE); - BerserkerChargeTimer = 25000; - } else BerserkerChargeTimer -= diff; - - if (UppercutTimer <= diff) - { - DoCast(me->getVictim(), SPELL_UPPERCUT); - UppercutTimer = 20000; - } else UppercutTimer -= diff; - - if (ThunderclapTimer <= diff) - { - DoCast(me->getVictim(), SPELL_THUNDERCLAP); - ThunderclapTimer = 15000; - } else ThunderclapTimer -= diff; - - if (MortalStrikeTimer <= diff) - { - DoCast(me->getVictim(), SPELL_MORTAL_STRIKE); - MortalStrikeTimer = 15000; - } else MortalStrikeTimer -= diff; - - if (CleaveTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CLEAVE); - CleaveTimer = 7000; - } else CleaveTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - -}; - -void AddSC_thunder_bluff() -{ - new npc_cairne_bloodhoof(); -} diff --git a/src/server/scripts/Kalimdor/ungoro_crater.cpp b/src/server/scripts/Kalimdor/ungoro_crater.cpp deleted file mode 100644 index e72c82bee97..00000000000 --- a/src/server/scripts/Kalimdor/ungoro_crater.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Ungoro Crater -SD%Complete: 100 -SDComment: Support for Quest: 4245, 4491 -SDCategory: Ungoro Crater -EndScriptData */ - -/* ContentData -npc_a-me -npc_ringo -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" -#include "SpellInfo.h" - -enum AmeData -{ - SAY_READY = 0, - SAY_AGGRO1 = 1, - SAY_SEARCH = 2, - SAY_AGGRO2 = 3, - SAY_AGGRO3 = 4, - SAY_FINISH = 5, - - SPELL_DEMORALIZINGSHOUT = 13730, - - QUEST_CHASING_AME = 4245, - ENTRY_TARLORD = 6519, - ENTRY_TARLORD1 = 6519, - ENTRY_STOMPER = 6513, -}; - -class npc_ame : public CreatureScript -{ -public: - npc_ame() : CreatureScript("npc_ame") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_CHASING_AME) - { - CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID()); - creature->AI()->Talk(SAY_READY, player->GetGUID()); - creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - // Change faction so mobs attack - creature->setFaction(113); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ameAI(creature); - } - - struct npc_ameAI : public npc_escortAI - { - npc_ameAI(Creature* creature) : npc_escortAI(creature) {} - - uint32 DemoralizingShoutTimer; - - void WaypointReached(uint32 waypointId) - { - if (Player* player = GetPlayerForEscort()) - { - switch (waypointId) - { - case 19: - me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_AGGRO1, player->GetGUID()); - break; - case 28: - Talk(SAY_SEARCH, player->GetGUID()); - break; - case 38: - me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_AGGRO2, player->GetGUID()); - break; - case 49: - me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - Talk(SAY_AGGRO3, player->GetGUID()); - break; - case 55: - Talk(SAY_FINISH, player->GetGUID()); - player->GroupEventHappens(QUEST_CHASING_AME, me); - break; - } - } - } - - void Reset() - { - DemoralizingShoutTimer = 5000; - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_CHASING_AME); - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - if (!UpdateVictim()) - return; - - if (DemoralizingShoutTimer <= diff) - { - DoCast(me->getVictim(), SPELL_DEMORALIZINGSHOUT); - DemoralizingShoutTimer = 70000; - } else DemoralizingShoutTimer -= diff; - } - }; -}; - -/*#### -# npc_ringo -####*/ - -enum Ringo -{ - SAY_RIN_START = 0, - - SAY_FAINT = 1, - - SAY_WAKE = 2, - - SAY_RIN_END_1 = 3, - SAY_SPR_END_2 = 0, - SAY_RIN_END_3 = 4, - EMOTE_RIN_END_4 = 5, - EMOTE_RIN_END_5 = 6, - SAY_RIN_END_6 = 7, - SAY_SPR_END_7 = 1, - EMOTE_RIN_END_8 = 8, - - SPELL_REVIVE_RINGO = 15591, - QUEST_A_LITTLE_HELP = 4491, - NPC_SPRAGGLE = 9997, - FACTION_ESCORTEE = 113 -}; - -class npc_ringo : public CreatureScript -{ -public: - npc_ringo() : CreatureScript("npc_ringo") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_A_LITTLE_HELP) - { - if (npc_ringoAI* ringoAI = CAST_AI(npc_ringo::npc_ringoAI, creature->AI())) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - ringoAI->StartFollow(player, FACTION_ESCORTEE, quest); - } - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ringoAI(creature); - } - - struct npc_ringoAI : public FollowerAI - { - npc_ringoAI(Creature* creature) : FollowerAI(creature) { } - - uint32 FaintTimer; - uint32 EndEventProgress; - uint32 EndEventTimer; - - uint64 SpraggleGUID; - - void Reset() - { - FaintTimer = urand(30000, 60000); - EndEventProgress = 0; - EndEventTimer = 1000; - SpraggleGUID = 0; - } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_SPRAGGLE) - { - if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) - { - if (Player* player = GetLeaderForFollower()) - { - if (player->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE) - player->GroupEventHappens(QUEST_A_LITTLE_HELP, me); - } - - SpraggleGUID = who->GetGUID(); - SetFollowComplete(true); - } - } - } - - void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) - { - if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_REVIVE_RINGO) - ClearFaint(); - } - - void SetFaint() - { - if (!HasFollowState(STATE_FOLLOW_POSTEVENT)) - { - SetFollowPaused(true); - - Talk(SAY_FAINT); - } - - //what does actually happen here? Emote? Aura? - me->SetStandState(UNIT_STAND_STATE_SLEEP); - } - - void ClearFaint() - { - me->SetStandState(UNIT_STAND_STATE_STAND); - - if (HasFollowState(STATE_FOLLOW_POSTEVENT)) - return; - - Talk(SAY_WAKE); - - SetFollowPaused(false); - } - - void UpdateFollowerAI(const uint32 Diff) - { - if (!UpdateVictim()) - { - if (HasFollowState(STATE_FOLLOW_POSTEVENT)) - { - if (EndEventTimer <= Diff) - { - Creature* spraggle = Creature::GetCreature(*me, SpraggleGUID); - if (!spraggle || !spraggle->isAlive()) - { - SetFollowComplete(); - return; - } - - switch (EndEventProgress) - { - case 1: - Talk(SAY_RIN_END_1); - EndEventTimer = 3000; - break; - case 2: - spraggle->AI()->Talk(SAY_SPR_END_2); - EndEventTimer = 5000; - break; - case 3: - Talk(SAY_RIN_END_3); - EndEventTimer = 1000; - break; - case 4: - Talk(EMOTE_RIN_END_4); - SetFaint(); - EndEventTimer = 9000; - break; - case 5: - Talk(EMOTE_RIN_END_5); - ClearFaint(); - EndEventTimer = 1000; - break; - case 6: - Talk(SAY_RIN_END_6); - EndEventTimer = 3000; - break; - case 7: - spraggle->AI()->Talk(SAY_SPR_END_7); - EndEventTimer = 10000; - break; - case 8: - Talk(EMOTE_RIN_END_8); - EndEventTimer = 5000; - break; - case 9: - SetFollowComplete(); - break; - } - - ++EndEventProgress; - } - else - EndEventTimer -= Diff; - } - else if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !HasFollowState(STATE_FOLLOW_PAUSED)) - { - if (FaintTimer <= Diff) - { - SetFaint(); - FaintTimer = urand(60000, 120000); - } - else - FaintTimer -= Diff; - } - - return; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_ungoro_crater() -{ - new npc_ame(); - new npc_ringo(); -} diff --git a/src/server/scripts/Kalimdor/winterspring.cpp b/src/server/scripts/Kalimdor/winterspring.cpp deleted file mode 100644 index 06f01033a25..00000000000 --- a/src/server/scripts/Kalimdor/winterspring.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Winterspring -SD%Complete: Almost Completely Emptied -SDComment: Vendor Rivern Frostwind. -SDCategory: Winterspring -EndScriptData */ - -/* ContentData -npc_rivern_frostwind -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_rivern_frostwind -######*/ - -class npc_rivern_frostwind : public CreatureScript -{ -public: - npc_rivern_frostwind() : CreatureScript("npc_rivern_frostwind") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor() && player->GetReputationRank(589) == REP_EXALTED) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - -}; - -void AddSC_winterspring() -{ - new npc_rivern_frostwind(); -} diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp new file mode 100644 index 00000000000..94c68a1d3ec --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Ashenvale +SD%Complete: 70 +SDComment: Quest support: 6544, 6482 +SDCategory: Ashenvale Forest +EndScriptData */ + +/* ContentData +npc_torek +npc_ruul_snowhoof +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*#### +# npc_torek +####*/ + +enum TorekSays +{ + SAY_READY = 0, + SAY_MOVE = 1, + SAY_PREPARE = 2, + SAY_WIN = 3, + SAY_END = 4, +}; + +enum TorekSpells +{ + SPELL_REND = 11977, + SPELL_THUNDERCLAP = 8078, +}; + +enum TorekMisc +{ + QUEST_TOREK_ASSULT = 6544, + + ENTRY_SPLINTERTREE_RAIDER = 12859, + ENTRY_DURIEL = 12860, + ENTRY_SILVERWING_SENTINEL = 12896, + ENTRY_SILVERWING_WARRIOR = 12897, +}; + +class npc_torek : public CreatureScript +{ + public: + + npc_torek() : CreatureScript("npc_torek") + { + } + + struct npc_torekAI : public npc_escortAI + { + npc_torekAI(Creature* creature) : npc_escortAI(creature) {} + + uint32 Rend_Timer; + uint32 Thunderclap_Timer; + bool Completed; + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 1: + Talk(SAY_MOVE, player->GetGUID()); + break; + case 8: + Talk(SAY_PREPARE, player->GetGUID()); + break; + case 19: + //TODO: verify location and creatures amount. + me->SummonCreature(ENTRY_DURIEL, 1776.73f, -2049.06f, 109.83f, 1.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(ENTRY_SILVERWING_SENTINEL, 1774.64f, -2049.41f, 109.83f, 1.40f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(ENTRY_SILVERWING_WARRIOR, 1778.73f, -2049.50f, 109.83f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 20: + Talk(SAY_WIN, player->GetGUID()); + Completed = true; + player->GroupEventHappens(QUEST_TOREK_ASSULT, me); + break; + case 21: + Talk(SAY_END, player->GetGUID()); + break; + } + } + } + + void Reset() + { + Rend_Timer = 5000; + Thunderclap_Timer = 8000; + Completed = false; + } + + void EnterCombat(Unit* /*who*/) + { + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + + if (!UpdateVictim()) + return; + + if (Rend_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_REND); + Rend_Timer = 20000; + } else Rend_Timer -= diff; + + if (Thunderclap_Timer <= diff) + { + DoCast(me, SPELL_THUNDERCLAP); + Thunderclap_Timer = 30000; + } else Thunderclap_Timer -= diff; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_torekAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_TOREK_ASSULT) + { + //TODO: find companions, make them follow Torek, at any time (possibly done by core/database in future?) + creature->AI()->Talk(SAY_READY, player->GetGUID()); + creature->setFaction(113); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_torekAI, creature->AI())) + pEscortAI->Start(true, true, player->GetGUID()); + } + + return true; + } +}; + +/*#### +# npc_ruul_snowhoof +####*/ + +enum RuulSnowhoof +{ + NPC_THISTLEFUR_URSA = 3921, + NPC_THISTLEFUR_TOTEMIC = 3922, + NPC_THISTLEFUR_PATHFINDER = 3926, + + QUEST_FREEDOM_TO_RUUL = 6482, + + GO_CAGE = 178147 +}; + +Position const RuulSnowhoofSummonsCoord[6] = +{ + {3449.218018f, -587.825073f, 174.978867f, 4.714445f}, + {3446.384521f, -587.830872f, 175.186279f, 4.714445f}, + {3444.218994f, -587.835327f, 175.380600f, 4.714445f}, + {3508.344482f, -492.024261f, 186.929031f, 4.145029f}, + {3506.265625f, -490.531006f, 186.740128f, 4.239277f}, + {3503.682373f, -489.393799f, 186.629684f, 4.349232f} +}; + +class npc_ruul_snowhoof : public CreatureScript +{ + public: + npc_ruul_snowhoof() : CreatureScript("npc_ruul_snowhoof") { } + + struct npc_ruul_snowhoofAI : public npc_escortAI + { + npc_ruul_snowhoofAI(Creature* creature) : npc_escortAI(creature) { } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 0: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) + Cage->SetGoState(GO_STATE_ACTIVE); + break; + case 13: + me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[0], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[1], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[2], TEMPSUMMON_DEAD_DESPAWN, 60000); + break; + case 19: + me->SummonCreature(NPC_THISTLEFUR_TOTEMIC, RuulSnowhoofSummonsCoord[3], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_URSA, RuulSnowhoofSummonsCoord[4], TEMPSUMMON_DEAD_DESPAWN, 60000); + me->SummonCreature(NPC_THISTLEFUR_PATHFINDER, RuulSnowhoofSummonsCoord[5], TEMPSUMMON_DEAD_DESPAWN, 60000); + break; + case 21: + player->GroupEventHappens(QUEST_FREEDOM_TO_RUUL, me); + break; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void Reset() + { + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 20)) + Cage->SetGoState(GO_STATE_READY); + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ruul_snowhoofAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL) + { + creature->setFaction(113); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_ruul_snowhoofAI, (creature->AI()))) + pEscortAI->Start(true, false, player->GetGUID()); + } + + return true; + } +}; + +enum Muglash +{ + SAY_MUG_START1 = 0, + SAY_MUG_START2 = 1, + SAY_MUG_BRAZIER = 2, + SAY_MUG_BRAZIER_WAIT = 3, + SAY_MUG_ON_GUARD = 4, + SAY_MUG_REST = 5, + SAY_MUG_DONE = 6, + SAY_MUG_GRATITUDE = 7, + SAY_MUG_PATROL = 8, + SAY_MUG_RETURN = 9, + + QUEST_VORSHA = 6641, + + GO_NAGA_BRAZIER = 178247, + + NPC_WRATH_RIDER = 3713, + NPC_WRATH_SORCERESS = 3717, + NPC_WRATH_RAZORTAIL = 3712, + + NPC_WRATH_PRIESTESS = 3944, + NPC_WRATH_MYRMIDON = 3711, + NPC_WRATH_SEAWITCH = 3715, + + NPC_VORSHA = 12940, + NPC_MUGLASH = 12717 +}; + +Position const FirstNagaCoord[3] = +{ + {3603.504150f, 1122.631104f, 1.635f, 0.0f}, // rider + {3589.293945f, 1148.664063f, 5.565f, 0.0f}, // sorceress + {3609.925537f, 1168.759521f, -1.168f, 0.0f} // razortail +}; + +Position const SecondNagaCoord[3] = +{ + {3609.925537f, 1168.759521f, -1.168f, 0.0f}, // witch + {3645.652100f, 1139.425415f, 1.322f, 0.0f}, // priest + {3583.602051f, 1128.405762f, 2.347f, 0.0f} // myrmidon +}; + +Position const VorshaCoord = {3633.056885f, 1172.924072f, -5.388f, 0.0f}; + +class npc_muglash : public CreatureScript +{ + public: + npc_muglash() : CreatureScript("npc_muglash") { } + + struct npc_muglashAI : public npc_escortAI + { + npc_muglashAI(Creature* creature) : npc_escortAI(creature) { } + + uint8 WaveId; + uint32 EventTimer; + bool IsBrazierExtinguished; + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 0: + Talk(SAY_MUG_START2, player->GetGUID()); + break; + case 24: + Talk(SAY_MUG_BRAZIER, player->GetGUID()); + + if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_NAGA_BRAZIER, INTERACTION_DISTANCE*2)) + { + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + SetEscortPaused(true); + } + break; + case 25: + Talk(SAY_MUG_GRATITUDE); + player->GroupEventHappens(QUEST_VORSHA, me); + break; + case 26: + Talk(SAY_MUG_PATROL); + break; + case 27: + Talk(SAY_MUG_RETURN); + break; + } + } + } + + void EnterCombat(Unit* /*who*/) + { + if (Player* player = GetPlayerForEscort()) + if (HasEscortState(STATE_ESCORT_PAUSED)) + { + if (urand(0, 1)) + Talk(SAY_MUG_ON_GUARD, player->GetGUID()); + return; + } + } + + void Reset() + { + EventTimer = 10000; + WaveId = 0; + IsBrazierExtinguished = false; + } + + void JustDied(Unit* /*killer*/) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_VORSHA); + } + + void DoWaveSummon() + { + switch (WaveId) + { + case 1: + me->SummonCreature(NPC_WRATH_RIDER, FirstNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_SORCERESS, FirstNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_RAZORTAIL, FirstNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + break; + case 2: + me->SummonCreature(NPC_WRATH_PRIESTESS, SecondNagaCoord[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_MYRMIDON, SecondNagaCoord[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + me->SummonCreature(NPC_WRATH_SEAWITCH, SecondNagaCoord[2], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + break; + case 3: + me->SummonCreature(NPC_VORSHA, VorshaCoord, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + break; + case 4: + SetEscortPaused(false); + Talk(SAY_MUG_DONE); + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (!me->getVictim()) + { + if (HasEscortState(STATE_ESCORT_PAUSED) && IsBrazierExtinguished) + { + if (EventTimer < uiDiff) + { + ++WaveId; + DoWaveSummon(); + EventTimer = 10000; + } + else + EventTimer -= uiDiff; + } + return; + } + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_muglashAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_VORSHA) + { + if (npc_muglashAI* pEscortAI = CAST_AI(npc_muglashAI, creature->AI())) + { + creature->AI()->Talk(SAY_MUG_START1); + creature->setFaction(113); + + pEscortAI->Start(true, false, player->GetGUID()); + } + } + return true; + } +}; + +class go_naga_brazier : public GameObjectScript +{ + public: + go_naga_brazier() : GameObjectScript("go_naga_brazier") { } + + bool OnGossipHello(Player* /*player*/, GameObject* go) + { + if (Creature* creature = GetClosestCreatureWithEntry(go, NPC_MUGLASH, INTERACTION_DISTANCE*2)) + { + if (npc_muglash::npc_muglashAI* pEscortAI = CAST_AI(npc_muglash::npc_muglashAI, creature->AI())) + { + creature->AI()->Talk(SAY_MUG_BRAZIER_WAIT); + + pEscortAI->IsBrazierExtinguished = true; + return false; + } + } + + return true; + } +}; + +void AddSC_ashenvale() +{ + new npc_torek(); + new npc_ruul_snowhoof(); + new npc_muglash(); + new go_naga_brazier(); +} diff --git a/src/server/scripts/Kalimdor/zone_azshara.cpp b/src/server/scripts/Kalimdor/zone_azshara.cpp new file mode 100644 index 00000000000..44f7e1e8172 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_azshara.cpp @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Azshara +SD%Complete: 90 +SDComment: Quest support: 2744, 3141, 9364, 10994 +SDCategory: Azshara +EndScriptData */ + +/* ContentData +mobs_spitelashes +npc_loramus_thalipedes +mob_rizzle_sprysprocket +mob_depth_charge +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" +#include "SpellInfo.h" +#include "WorldSession.h" + +/*###### +## mobs_spitelashes +######*/ + +class mobs_spitelashes : public CreatureScript +{ +public: + mobs_spitelashes() : CreatureScript("mobs_spitelashes") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mobs_spitelashesAI (creature); + } + + struct mobs_spitelashesAI : public ScriptedAI + { + mobs_spitelashesAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 morphtimer; + bool spellhit; + + void Reset() + { + morphtimer = 0; + spellhit = false; + } + + void EnterCombat(Unit* /*who*/) { } + + void SpellHit(Unit* Hitter, const SpellInfo* Spellkind) + { + if (!spellhit && + Hitter->GetTypeId() == TYPEID_PLAYER && + CAST_PLR(Hitter)->GetQuestStatus(9364) == QUEST_STATUS_INCOMPLETE && + (Spellkind->Id == 118 || Spellkind->Id == 12824 || Spellkind->Id == 12825 || Spellkind->Id == 12826)) + { + spellhit=true; + DoCast(me, 29124); //become a sheep + } + } + + void UpdateAI(const uint32 diff) + { + // we mustn't remove the Creature in the same round in which we cast the summon spell, otherwise there will be no summons + if (spellhit && morphtimer >= 5000) + { + me->DespawnOrUnsummon(); + return; + } + // walk 5 seconds before summoning + if (spellhit && morphtimer<5000) + { + morphtimer+=diff; + if (morphtimer >= 5000) + { + DoCast(me, 28406); //summon copies + DoCast(me, 6924); //visual explosion + } + } + if (!UpdateVictim()) + return; + + //TODO: add abilities for the different creatures + DoMeleeAttackIfReady(); + } + }; + +}; + +/*###### +## npc_loramus_thalipedes +######*/ + +#define GOSSIP_HELLO_LT1 "Can you help me?" +#define GOSSIP_HELLO_LT2 "Tell me your story" +#define GOSSIP_SELECT_LT1 "Please continue" +#define GOSSIP_SELECT_LT2 "I do not understand" +#define GOSSIP_SELECT_LT3 "Indeed" +#define GOSSIP_SELECT_LT4 "I will do this with or your help, Loramus" +#define GOSSIP_SELECT_LT5 "Yes" + +class npc_loramus_thalipedes : public CreatureScript +{ +public: + npc_loramus_thalipedes() : CreatureScript("npc_loramus_thalipedes") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(2744); + break; + + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21); + player->SEND_GOSSIP_MENU(1813, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+21: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22); + player->SEND_GOSSIP_MENU(1814, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+22: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23); + player->SEND_GOSSIP_MENU(1815, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+23: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24); + player->SEND_GOSSIP_MENU(1816, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+24: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25); + player->SEND_GOSSIP_MENU(1817, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+25: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(3141); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(2744) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + if (player->GetQuestStatus(3141) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*#### +# mob_rizzle_sprysprocket +####*/ + +enum RizzleSprysprocketData +{ + QUEST_CHASING_THE_MOONSTONE = 10994, + + MOB_DEPTH_CHARGE = 23025, + + SPELL_RIZZLE_BLACKJACK = 39865, + SPELL_RIZZLE_ESCAPE = 39871, + SPELL_RIZZLE_FROST_GRENADE = 40525, + SPELL_DEPTH_CHARGE_TRAP = 38576, + SPELL_PERIODIC_DEPTH_CHARGE = 39912, + SPELL_GIVE_SOUTHFURY_MOONSTONE = 39886, + + SAY_RIZZLE_START = 0, + SAY_RIZZLE_GRENADE = 1, + SAY_RIZZLE_FINAL = 2, + MSG_ESCAPE_NOTICE = 3 +}; + +#define GOSSIP_GET_MOONSTONE "Hand over the Southfury moonstone and I'll let you go." + +Position const WPs[58] = +{ + {3691.97f, -3962.41f, 35.9118f, 3.67f}, + {3675.02f, -3960.49f, 35.9118f, 3.67f}, + {3653.19f, -3958.33f, 33.9118f, 3.59f}, + {3621.12f, -3958.51f, 29.9118f, 3.48f}, + {3604.86f, -3963, 29.9118f, 3.48f}, + {3569.94f, -3970.25f, 29.9118f, 3.44f}, + {3541.03f, -3975.64f, 29.9118f, 3.41f}, + {3510.84f, -3978.71f, 29.9118f, 3.41f}, + {3472.7f, -3997.07f, 29.9118f, 3.35f}, + {3439.15f, -4014.55f, 29.9118f, 3.29f}, + {3412.8f, -4025.87f, 29.9118f, 3.25f}, + {3384.95f, -4038.04f, 29.9118f, 3.24f}, + {3346.77f, -4052.93f, 29.9118f, 3.22f}, + {3299.56f, -4071.59f, 29.9118f, 3.20f}, + {3261.22f, -4080.38f, 30.9118f, 3.19f}, + {3220.68f, -4083.09f, 31.9118f, 3.18f}, + {3187.11f, -4070.45f, 33.9118f, 3.16f}, + {3162.78f, -4062.75f, 33.9118f, 3.15f}, + {3136.09f, -4050.32f, 33.9118f, 3.07f}, + {3119.47f, -4044.51f, 36.0363f, 3.07f}, + {3098.95f, -4019.8f, 33.9118f, 3.07f}, + {3073.07f, -4011.42f, 33.9118f, 3.07f}, + {3051.71f, -3993.37f, 33.9118f, 3.02f}, + {3027.52f, -3978.6f, 33.9118f, 3.00f}, + {3003.78f, -3960.14f, 33.9118f, 2.98f}, + {2977.99f, -3941.98f, 31.9118f, 2.96f}, + {2964.57f, -3932.07f, 30.9118f, 2.96f}, + {2947.9f, -3921.31f, 29.9118f, 2.96f}, + {2924.91f, -3910.8f, 29.9118f, 2.94f}, + {2903.04f, -3896.42f, 29.9118f, 2.93f}, + {2884.75f, -3874.03f, 29.9118f, 2.90f}, + {2868.19f, -3851.48f, 29.9118f, 2.82f}, + {2854.62f, -3819.72f, 29.9118f, 2.80f}, + {2825.53f, -3790.4f, 29.9118f, 2.744f}, + {2804.31f, -3773.05f, 29.9118f, 2.71f}, + {2769.78f, -3763.57f, 29.9118f, 2.70f}, + {2727.23f, -3745.92f, 30.9118f, 2.69f}, + {2680.12f, -3737.49f, 30.9118f, 2.67f}, + {2647.62f, -3739.94f, 30.9118f, 2.66f}, + {2616.6f, -3745.75f, 30.9118f, 2.64f}, + {2589.38f, -3731.97f, 30.9118f, 2.61f}, + {2562.94f, -3722.35f, 31.9118f, 2.56f}, + {2521.05f, -3716.6f, 31.9118f, 2.55f}, + {2485.26f, -3706.67f, 31.9118f, 2.51f}, + {2458.93f, -3696.67f, 31.9118f, 2.51f}, + {2432, -3692.03f, 31.9118f, 2.46f}, + {2399.59f, -3681.97f, 31.9118f, 2.45f}, + {2357.75f, -3666.6f, 31.9118f, 2.44f}, + {2311.99f, -3656.88f, 31.9118f, 2.94f}, + {2263.41f, -3649.55f, 31.9118f, 3.02f}, + {2209.05f, -3641.76f, 31.9118f, 2.99f}, + {2164.83f, -3637.64f, 31.9118f, 3.15f}, + {2122.42f, -3639, 31.9118f, 3.21f}, + {2075.73f, -3643.59f, 31.9118f, 3.22f}, + {2033.59f, -3649.52f, 31.9118f, 3.42f}, + {1985.22f, -3662.99f, 31.9118f, 3.42f}, + {1927.09f, -3679.56f, 33.9118f, 3.42f}, + {1873.57f, -3695.32f, 33.9118f, 3.44f} +}; + +class mob_rizzle_sprysprocket : public CreatureScript +{ +public: + mob_rizzle_sprysprocket() : CreatureScript("mob_rizzle_sprysprocket") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF + 1 && player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_GIVE_SOUTHFURY_MOONSTONE, true); + CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->MustDieTimer = 3000; + CAST_AI(mob_rizzle_sprysprocket::mob_rizzle_sprysprocketAI, creature->AI())->MustDie = true; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) != QUEST_STATUS_INCOMPLETE) + return true; + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GET_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(10811, creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_rizzle_sprysprocketAI (creature); + } + + struct mob_rizzle_sprysprocketAI : public ScriptedAI + { + mob_rizzle_sprysprocketAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 SpellEscapeTimer; + uint32 TeleportTimer; + uint32 CheckTimer; + uint32 GrenadeTimer; + uint32 MustDieTimer; + uint32 CurrWP; + + uint64 PlayerGUID; + + bool MustDie; + bool Escape; + bool ContinueWP; + bool Reached; + + void Reset() + { + SpellEscapeTimer = 1300; + TeleportTimer = 3500; + CheckTimer = 10000; + GrenadeTimer = 30000; + MustDieTimer = 3000; + CurrWP = 0; + + PlayerGUID = 0; + + MustDie = false; + Escape = false; + ContinueWP = false; + Reached = false; + } + + void UpdateAI(const uint32 diff) + { + if (MustDie) + { + if (MustDieTimer <= diff) + { + me->DespawnOrUnsummon(); + return; + } else MustDieTimer -= diff; + } + + if (!Escape) + { + if (!PlayerGUID) + return; + + if (SpellEscapeTimer <= diff) + { + DoCast(me, SPELL_RIZZLE_ESCAPE, false); + SpellEscapeTimer = 10000; + } else SpellEscapeTimer -= diff; + + if (TeleportTimer <= diff) + { + // temp solution - unit can't be teleported by core using spelleffect 5, only players + DoTeleportTo(3706.39f, -3969.15f, 35.9118f); + + //begin swimming and summon depth charges + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (!player) + return; + + Talk(MSG_ESCAPE_NOTICE, player->GetGUID()); + DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE); + me->SetUnitMovementFlags(MOVEMENTFLAG_HOVER | MOVEMENTFLAG_SWIMMING); + me->SetSpeed(MOVE_RUN, 0.85f, true); + me->GetMotionMaster()->MovementExpired(); + me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); + Escape = true; + } else TeleportTimer -= diff; + + return; + } + + if (ContinueWP) + { + me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); + ContinueWP = false; + } + + if (GrenadeTimer <= diff) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player) + { + Talk(SAY_RIZZLE_GRENADE, player->GetGUID()); + DoCast(player, SPELL_RIZZLE_FROST_GRENADE, true); + } + GrenadeTimer = 30000; + } else GrenadeTimer -= diff; + + if (CheckTimer <= diff) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (!player) + { + me->DespawnOrUnsummon(); + return; + } + + if (me->IsWithinDist(player, 10) && me->GetPositionX() > player->GetPositionX() && !Reached) + { + Talk(SAY_RIZZLE_FINAL); + me->SetUInt32Value(UNIT_NPC_FLAGS, 1); + me->setFaction(35); + me->GetMotionMaster()->MoveIdle(); + me->RemoveAurasDueToSpell(SPELL_PERIODIC_DEPTH_CHARGE); + Reached = true; + } + + CheckTimer = 1000; + } else CheckTimer -= diff; + + } + + void SendText(int32 iTextEntry, Player* player) + { + LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); + const char* text = sObjectMgr->GetTrinityString(iTextEntry, loc_idx); + sWorld->SendServerMessage(SERVER_MSG_STRING, text, player); + } + + void AttackStart(Unit* who) + { + if (!who || PlayerGUID) + return; + + if (who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE) + { + PlayerGUID = who->GetGUID(); + Talk(SAY_RIZZLE_START); + DoCast(who, SPELL_RIZZLE_BLACKJACK, false); + return; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id == 57) + { + me->DespawnOrUnsummon(); + return; + } + + ++CurrWP; + ContinueWP = true; + } + }; +}; + +/*#### +# mob_depth_charge +####*/ +class mob_depth_charge : public CreatureScript +{ +public: + mob_depth_charge() : CreatureScript("mob_depth_charge") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_depth_chargeAI (creature); + } + + struct mob_depth_chargeAI : public ScriptedAI + { + mob_depth_chargeAI(Creature* creature) : ScriptedAI(creature) {} + + bool WeMustDie; + uint32 WeMustDieTimer; + + void Reset() + { + me->SetUnitMovementFlags(MOVEMENTFLAG_HOVER | MOVEMENTFLAG_SWIMMING); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + WeMustDie = false; + WeMustDieTimer = 1000; + } + + void UpdateAI(const uint32 diff) + { + if (WeMustDie) + { + if (WeMustDieTimer <= diff) + me->DespawnOrUnsummon(); + else + WeMustDieTimer -= diff; + } + return; + } + + void MoveInLineOfSight(Unit* who) + { + if (!who) + return; + + if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 5)) + { + DoCast(who, SPELL_DEPTH_CHARGE_TRAP); + WeMustDie = true; + return; + } + } + + void AttackStart(Unit* /*who*/) {} + + void EnterCombat(Unit* /*who*/) {} + }; +}; + +void AddSC_azshara() +{ + new mobs_spitelashes(); + new npc_loramus_thalipedes(); + new mob_rizzle_sprysprocket(); + new mob_depth_charge(); +} diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp new file mode 100644 index 00000000000..4b03cd65cad --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp @@ -0,0 +1,770 @@ + /* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Azuremyst_Isle +SD%Complete: 75 +SDComment: Quest support: 9283, 9537, 9582, 9554, 9531, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582. +SDCategory: Azuremyst Isle +EndScriptData */ + +/* ContentData +npc_draenei_survivor +npc_engineer_spark_overgrind +npc_injured_draenei +npc_magwin +npc_geezle +go_ravager_cage +npc_death_ravager +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" + +/*###### +## npc_draenei_survivor +######*/ + +enum draeneiSurvivor +{ + SAY_HEAL = 0, + + SAY_HELP = 1, + + SPELL_IRRIDATION = 35046, + SPELL_STUNNED = 28630 +}; + +class npc_draenei_survivor : public CreatureScript +{ +public: + npc_draenei_survivor() : CreatureScript("npc_draenei_survivor") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_draenei_survivorAI (creature); + } + + struct npc_draenei_survivorAI : public ScriptedAI + { + npc_draenei_survivorAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 pCaster; + + uint32 SayThanksTimer; + uint32 RunAwayTimer; + uint32 SayHelpTimer; + + bool CanSayHelp; + + void Reset() + { + pCaster = 0; + + SayThanksTimer = 0; + RunAwayTimer = 0; + SayHelpTimer = 10000; + + CanSayHelp = true; + + DoCast(me, SPELL_IRRIDATION, true); + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + me->SetHealth(me->CountPctFromMaxHealth(10)); + me->SetStandState(UNIT_STAND_STATE_SLEEP); + } + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* who) + { + if (CanSayHelp && who->GetTypeId() == TYPEID_PLAYER && me->IsFriendlyTo(who) && me->IsWithinDistInMap(who, 25.0f)) + { + //Random switch between 4 texts + Talk(SAY_HELP, who->GetGUID()); + + SayHelpTimer = 20000; + CanSayHelp = false; + } + } + + void SpellHit(Unit* Caster, const SpellInfo* Spell) + { + if (Spell->SpellFamilyFlags[2] & 0x080000000) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + me->SetStandState(UNIT_STAND_STATE_STAND); + + DoCast(me, SPELL_STUNNED, true); + + pCaster = Caster->GetGUID(); + + SayThanksTimer = 5000; + } + } + + void UpdateAI(const uint32 diff) + { + if (SayThanksTimer) + { + if (SayThanksTimer <= diff) + { + me->RemoveAurasDueToSpell(SPELL_IRRIDATION); + + if (Player* player = Unit::GetPlayer(*me, pCaster)) + { + Talk(SAY_HEAL, player->GetGUID()); + + player->TalkedToCreature(me->GetEntry(), me->GetGUID()); + } + + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MovePoint(0, -4115.053711f, -13754.831055f, 73.508949f); + + RunAwayTimer = 10000; + SayThanksTimer = 0; + } else SayThanksTimer -= diff; + + return; + } + + if (RunAwayTimer) + { + if (RunAwayTimer <= diff) + me->DespawnOrUnsummon(); + else + RunAwayTimer -= diff; + + return; + } + + if (SayHelpTimer <= diff) + { + CanSayHelp = true; + SayHelpTimer = 20000; + } else SayHelpTimer -= diff; + } + }; + +}; + +/*###### +## npc_engineer_spark_overgrind +######*/ + +enum Overgrind +{ + SAY_TEXT = 0, + SAY_EMOTE = 1, + ATTACK_YELL = 2, + + AREA_COVE = 3579, + AREA_ISLE = 3639, + QUEST_GNOMERCY = 9537, + FACTION_HOSTILE = 14, + SPELL_DYNAMITE = 7978 +}; + +#define GOSSIP_FIGHT "Traitor! You will be brought to justice!" + +class npc_engineer_spark_overgrind : public CreatureScript +{ +public: + npc_engineer_spark_overgrind() : CreatureScript("npc_engineer_spark_overgrind") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_HOSTILE); + CAST_AI(npc_engineer_spark_overgrind::npc_engineer_spark_overgrindAI, creature->AI())->AttackStart(player); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_GNOMERCY) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_engineer_spark_overgrindAI (creature); + } + + struct npc_engineer_spark_overgrindAI : public ScriptedAI + { + npc_engineer_spark_overgrindAI(Creature* creature) : ScriptedAI(creature) + { + NormFaction = creature->getFaction(); + NpcFlags = creature->GetUInt32Value(UNIT_NPC_FLAGS); + + if (creature->GetAreaId() == AREA_COVE || creature->GetAreaId() == AREA_ISLE) + IsTreeEvent = true; + } + + uint32 NormFaction; + uint32 NpcFlags; + + uint32 DynamiteTimer; + uint32 EmoteTimer; + + bool IsTreeEvent; + + void Reset() + { + DynamiteTimer = 8000; + EmoteTimer = urand(120000, 150000); + + me->setFaction(NormFaction); + me->SetUInt32Value(UNIT_NPC_FLAGS, NpcFlags); + + IsTreeEvent = false; + } + + void EnterCombat(Unit* who) + { + Talk(ATTACK_YELL, who->GetGUID()); + } + + void UpdateAI(const uint32 diff) + { + if (!me->isInCombat() && !IsTreeEvent) + { + if (EmoteTimer <= diff) + { + Talk(SAY_TEXT); + Talk(SAY_EMOTE); + EmoteTimer = urand(120000, 150000); + } else EmoteTimer -= diff; + } + else if (IsTreeEvent) + return; + + if (!UpdateVictim()) + return; + + if (DynamiteTimer <= diff) + { + DoCast(me->getVictim(), SPELL_DYNAMITE); + DynamiteTimer = 8000; + } else DynamiteTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*###### +## npc_injured_draenei +######*/ + +class npc_injured_draenei : public CreatureScript +{ +public: + npc_injured_draenei() : CreatureScript("npc_injured_draenei") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_injured_draeneiAI (creature); + } + + struct npc_injured_draeneiAI : public ScriptedAI + { + npc_injured_draeneiAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + me->SetHealth(me->CountPctFromMaxHealth(15)); + switch (urand(0, 1)) + { + case 0: + me->SetStandState(UNIT_STAND_STATE_SIT); + break; + + case 1: + me->SetStandState(UNIT_STAND_STATE_SLEEP); + break; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* /*who*/) {} + + void UpdateAI(const uint32 /*diff*/) {} + }; + +}; + +/*###### +## npc_magwin +######*/ + +enum Magwin +{ + SAY_START = 0, + SAY_AGGRO = 1, + SAY_PROGRESS = 2, + SAY_END1 = 3, + SAY_END2 = 4, + EMOTE_HUG = 5, + + QUEST_A_CRY_FOR_SAY_HELP = 9528 +}; + +class npc_magwin : public CreatureScript +{ +public: + npc_magwin() : CreatureScript("npc_magwin") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_A_CRY_FOR_SAY_HELP) + { + creature->setFaction(113); + if (npc_escortAI* pEscortAI = CAST_AI(npc_escortAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_magwinAI(creature); + } + + struct npc_magwinAI : public npc_escortAI + { + npc_magwinAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 0: + Talk(SAY_START, player->GetGUID()); + break; + case 17: + Talk(SAY_PROGRESS, player->GetGUID()); + break; + case 28: + Talk(SAY_END1, player->GetGUID()); + break; + case 29: + Talk(EMOTE_HUG, player->GetGUID()); + Talk(SAY_END2, player->GetGUID()); + player->GroupEventHappens(QUEST_A_CRY_FOR_SAY_HELP, me); + break; + } + } + } + + void EnterCombat(Unit* who) + { + Talk(SAY_AGGRO, who->GetGUID()); + } + + void Reset() {} + }; + +}; + +/*###### +## npc_geezle +######*/ + +enum Geezle +{ + QUEST_TREES_COMPANY = 9531, + + SPELL_TREE_DISGUISE = 30298, + + GEEZLE_SAY_1 = 0, + SPARK_SAY_2 = 3, + SPARK_SAY_3 = 4, + GEEZLE_SAY_4 = 1, + SPARK_SAY_5 = 5, + SPARK_SAY_6 = 6, + GEEZLE_SAY_7 = 2, + + EMOTE_SPARK = 7, + + MOB_SPARK = 17243, + GO_NAGA_FLAG = 181694 +}; + +Position const SparkPos = {-5029.91f, -11291.79f, 8.096f, 0.0f}; + +class npc_geezle : public CreatureScript +{ +public: + npc_geezle() : CreatureScript("npc_geezle") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_geezleAI(creature); + } + + struct npc_geezleAI : public ScriptedAI + { + npc_geezleAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 SparkGUID; + + uint8 Step; + uint32 SayTimer; + + bool EventStarted; + + void Reset() + { + SparkGUID = 0; + Step = 0; + StartEvent(); + } + + void EnterCombat(Unit* /*who*/){} + + void StartEvent() + { + Step = 0; + EventStarted = true; + if (Creature* Spark = me->SummonCreature(MOB_SPARK, SparkPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000)) + { + SparkGUID = Spark->GetGUID(); + Spark->setActive(true); + Spark->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + SayTimer = 8000; + } + + uint32 NextStep(uint8 Step) + { + Creature* Spark = Unit::GetCreature(*me, SparkGUID); + if (!Spark) + return 99999999; + + switch (Step) + { + case 0: + Spark->GetMotionMaster()->MovePoint(0, -5080.70f, -11253.61f, 0.56f); + me->GetMotionMaster()->MovePoint(0, -5092.26f, -11252, 0.71f); + return 9000; + case 1: + DespawnNagaFlag(true); + Spark->AI()->Talk(EMOTE_SPARK); + return 1000; + case 2: + Talk(GEEZLE_SAY_1, SparkGUID); + Spark->SetInFront(me); + me->SetInFront(Spark); + return 5000; + case 3: + Spark->AI()->Talk(SPARK_SAY_2); + return 7000; + case 4: + Spark->AI()->Talk(SPARK_SAY_3); + return 8000; + case 5: + Talk(GEEZLE_SAY_4, SparkGUID); + return 8000; + case 6: + Spark->AI()->Talk(SPARK_SAY_5); + return 9000; + case 7: + Spark->AI()->Talk(SPARK_SAY_6); + return 8000; + case 8: + Talk(GEEZLE_SAY_7, SparkGUID); + return 2000; + case 9: + me->GetMotionMaster()->MoveTargetedHome(); + Spark->GetMotionMaster()->MovePoint(0, SparkPos); + CompleteQuest(); + return 9000; + case 10: + Spark->DisappearAndDie(); + DespawnNagaFlag(false); + me->DisappearAndDie(); + default: return 99999999; + } + } + + // will complete Tree's company quest for all nearby players that are disguised as trees + void CompleteQuest() + { + float radius = 50.0f; + std::list players; + Trinity::AnyPlayerInObjectRangeCheck checker(me, radius); + Trinity::PlayerListSearcher searcher(me, players, checker); + me->VisitNearbyWorldObject(radius, searcher); + + for (std::list::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if ((*itr)->GetQuestStatus(QUEST_TREES_COMPANY) == QUEST_STATUS_INCOMPLETE && (*itr)->HasAura(SPELL_TREE_DISGUISE)) + (*itr)->KilledMonsterCredit(MOB_SPARK, 0); + } + + void DespawnNagaFlag(bool despawn) + { + std::list FlagList; + me->GetGameObjectListWithEntryInGrid(FlagList, GO_NAGA_FLAG, 100.0f); + + if (!FlagList.empty()) + { + for (std::list::const_iterator itr = FlagList.begin(); itr != FlagList.end(); ++itr) + { + if (despawn) + (*itr)->SetLootState(GO_JUST_DEACTIVATED); + else + (*itr)->Respawn(); + } + } + else + sLog->outError(LOG_FILTER_TSCR, "SD2 ERROR: FlagList is empty!"); + } + + void UpdateAI(const uint32 diff) + { + if (SayTimer <= diff) + { + if (EventStarted) + SayTimer = NextStep(Step++); + } + else + SayTimer -= diff; + } + }; + +}; + +enum RavegerCage +{ + NPC_DEATH_RAVAGER = 17556, + + SPELL_REND = 13443, + SPELL_ENRAGING_BITE = 30736, + + QUEST_STRENGTH_ONE = 9582 +}; + +class go_ravager_cage : public GameObjectScript +{ +public: + go_ravager_cage() : GameObjectScript("go_ravager_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + if (player->GetQuestStatus(QUEST_STRENGTH_ONE) == QUEST_STATUS_INCOMPLETE) + { + if (Creature* ravager = go->FindNearestCreature(NPC_DEATH_RAVAGER, 5.0f, true)) + { + ravager->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + ravager->SetReactState(REACT_AGGRESSIVE); + ravager->AI()->AttackStart(player); + } + } + return true; + } +}; + +class npc_death_ravager : public CreatureScript +{ +public: + npc_death_ravager() : CreatureScript("npc_death_ravager") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_death_ravagerAI(creature); + } + + struct npc_death_ravagerAI : public ScriptedAI + { + npc_death_ravagerAI(Creature* creature) : ScriptedAI(creature){} + + uint32 RendTimer; + uint32 EnragingBiteTimer; + + void Reset() + { + RendTimer = 30000; + EnragingBiteTimer = 20000; + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (RendTimer <= diff) + { + DoCast(me->getVictim(), SPELL_REND); + RendTimer = 30000; + } + else RendTimer -= diff; + + if (EnragingBiteTimer <= diff) + { + DoCast(me->getVictim(), SPELL_ENRAGING_BITE); + EnragingBiteTimer = 15000; + } + else EnragingBiteTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*######## +## Quest: The Prophecy of Akida +########*/ + +enum BristlelimbCage +{ + QUEST_THE_PROPHECY_OF_AKIDA = 9544, + NPC_STILLPINE_CAPITIVE = 17375, + GO_BRISTELIMB_CAGE = 181714, + + CAPITIVE_SAY = 0, + + POINT_INIT = 1, + EVENT_DESPAWN = 1, +}; + +class npc_stillpine_capitive : public CreatureScript +{ + public: + npc_stillpine_capitive() : CreatureScript("npc_stillpine_capitive") { } + + struct npc_stillpine_capitiveAI : public ScriptedAI + { + npc_stillpine_capitiveAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + if (GameObject* cage = me->FindNearestGameObject(GO_BRISTELIMB_CAGE, 5.0f)) + { + cage->SetLootState(GO_JUST_DEACTIVATED); + cage->SetGoState(GO_STATE_READY); + } + _events.Reset(); + _player = NULL; + _movementComplete = false; + } + + void StartMoving(Player* owner) + { + if (owner) + { + Talk(CAPITIVE_SAY, owner->GetGUID()); + _player = owner; + } + Position pos; + me->GetNearPosition(pos, 3.0f, 0.0f); + me->GetMotionMaster()->MovePoint(POINT_INIT, pos); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE || id != POINT_INIT) + return; + + if (_player) + _player->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); + + _movementComplete = true; + _events.ScheduleEvent(EVENT_DESPAWN, 3500); + } + + void UpdateAI(uint32 const diff) + { + if (!_movementComplete) + return; + + _events.Update(diff); + + if (_events.ExecuteEvent() == EVENT_DESPAWN) + me->DespawnOrUnsummon(); + } + + private: + Player* _player; + EventMap _events; + bool _movementComplete; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_stillpine_capitiveAI(creature); + } +}; + +class go_bristlelimb_cage : public GameObjectScript +{ + public: + go_bristlelimb_cage() : GameObjectScript("go_bristlelimb_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->SetGoState(GO_STATE_READY); + if (player->GetQuestStatus(QUEST_THE_PROPHECY_OF_AKIDA) == QUEST_STATUS_INCOMPLETE) + { + if (Creature* capitive = go->FindNearestCreature(NPC_STILLPINE_CAPITIVE, 5.0f, true)) + { + go->ResetDoorOrButton(); + CAST_AI(npc_stillpine_capitive::npc_stillpine_capitiveAI, capitive->AI())->StartMoving(player); + return false; + } + } + return true; + } +}; + +void AddSC_azuremyst_isle() +{ + new npc_draenei_survivor(); + new npc_engineer_spark_overgrind(); + new npc_injured_draenei(); + new npc_magwin(); + new npc_geezle(); + new npc_death_ravager(); + new go_ravager_cage(); + new npc_stillpine_capitive(); + new go_bristlelimb_cage(); +} diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp new file mode 100644 index 00000000000..102a9494a65 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Bloodmyst_Isle +SD%Complete: 80 +SDComment: Quest support: 9670, 9756(gossip items text needed). +SDCategory: Bloodmyst Isle +EndScriptData */ + +/* ContentData +mob_webbed_creature +npc_captured_sunhawk_agent +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## mob_webbed_creature +######*/ + +//possible creatures to be spawned +uint32 const possibleSpawns[32] = {17322, 17661, 17496, 17522, 17340, 17352, 17333, 17524, 17654, 17348, 17339, 17345, 17359, 17353, 17336, 17550, 17330, 17701, 17321, 17680, 17325, 17320, 17683, 17342, 17715, 17334, 17341, 17338, 17337, 17346, 17344, 17327}; + +class mob_webbed_creature : public CreatureScript +{ +public: + mob_webbed_creature() : CreatureScript("mob_webbed_creature") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_webbed_creatureAI (creature); + } + + struct mob_webbed_creatureAI : public ScriptedAI + { + mob_webbed_creatureAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + + void EnterCombat(Unit* /*who*/) {} + + void JustDied(Unit* killer) + { + uint32 spawnCreatureID = 0; + + switch (urand(0, 2)) + { + case 0: + spawnCreatureID = 17681; + if (Player* player = killer->ToPlayer()) + player->KilledMonsterCredit(spawnCreatureID, 0); + break; + case 1: + case 2: + spawnCreatureID = possibleSpawns[urand(0, 30)]; + break; + } + + if (spawnCreatureID) + me->SummonCreature(spawnCreatureID, 0.0f, 0.0f, 0.0f, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + } + }; + +}; + +/*###### +## npc_captured_sunhawk_agent +######*/ + +#define C_SUNHAWK_TRIGGER 17974 + +#define GOSSIP_HELLO_CSA "[PH] " +#define GOSSIP_SELECT_CSA1 "[PH] " +#define GOSSIP_SELECT_CSA2 "[PH] " +#define GOSSIP_SELECT_CSA3 "[PH] " +#define GOSSIP_SELECT_CSA4 "[PH] " +#define GOSSIP_SELECT_CSA5 "[PH] " + +class npc_captured_sunhawk_agent : public CreatureScript +{ +public: + npc_captured_sunhawk_agent() : CreatureScript("npc_captured_sunhawk_agent") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(9137, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(9138, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(9139, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(9140, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_CSA5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(9141, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->CLOSE_GOSSIP_MENU(); + player->TalkedToCreature(C_SUNHAWK_TRIGGER, creature->GetGUID()); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->HasAura(31609) && player->GetQuestStatus(9756) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_CSA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(9136, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(9134, creature->GetGUID()); + + return true; + } + +}; + +/*###### +## Quest 9667: Saving Princess Stillpine +######*/ + +enum Stillpine +{ + QUEST_SAVING_PRINCESS_STILLPINE = 9667, + NPC_PRINCESS_STILLPINE = 17682, + GO_PRINCESS_STILLPINES_CAGE = 181928, + SPELL_OPENING_PRINCESS_STILLPINE_CREDIT = 31003, + SAY_DIRECTION = 0 +}; + +class go_princess_stillpines_cage : public GameObjectScript +{ +public: + go_princess_stillpines_cage() : GameObjectScript("go_princess_stillpines_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->SetGoState(GO_STATE_READY); + if (Creature* stillpine = go->FindNearestCreature(NPC_PRINCESS_STILLPINE, 25, true)) + { + stillpine->GetMotionMaster()->MovePoint(1, go->GetPositionX(), go->GetPositionY()-15, go->GetPositionZ()); + player->CastedCreatureOrGO(NPC_PRINCESS_STILLPINE, 0, SPELL_OPENING_PRINCESS_STILLPINE_CREDIT); + } + return true; + } +}; + +class npc_princess_stillpine : public CreatureScript +{ +public: + npc_princess_stillpine() : CreatureScript("npc_princess_stillpine") { } + + struct npc_princess_stillpineAI : public ScriptedAI + { + npc_princess_stillpineAI(Creature* creature) : ScriptedAI(creature) {} + + void MovementInform(uint32 type, uint32 id) + { + if (type == POINT_MOTION_TYPE && id == 1) + { + Talk(SAY_DIRECTION); + me->DespawnOrUnsummon(); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_princess_stillpineAI(creature); + } +}; + +void AddSC_bloodmyst_isle() +{ + new mob_webbed_creature(); + new npc_captured_sunhawk_agent(); + new npc_princess_stillpine(); + new go_princess_stillpines_cage(); +} diff --git a/src/server/scripts/Kalimdor/zone_darkshore.cpp b/src/server/scripts/Kalimdor/zone_darkshore.cpp new file mode 100644 index 00000000000..09f061148d3 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_darkshore.cpp @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Darkshore +SD%Complete: 100 +SDComment: Quest support: 731, 2078, 5321 +SDCategory: Darkshore +EndScriptData */ + +/* ContentData +npc_kerlonian +npc_prospector_remtravel +npc_threshwackonator +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "ScriptedFollowerAI.h" +#include "Player.h" +#include "SpellInfo.h" + +/*#### +# npc_kerlonian +####*/ + +enum Kerlonian +{ + SAY_KER_START = 0, + EMOTE_KER_SLEEP = 1, + SAY_KER_SLEEP = 2, + SAY_KER_ALERT_1 = 3, + SAY_KER_END = 4, + EMOTE_KER_AWAKEN = 5, + + SPELL_SLEEP_VISUAL = 25148, + SPELL_AWAKEN = 17536, + QUEST_SLEEPER_AWAKENED = 5321, + NPC_LILADRIS = 11219, //attackers entries unknown + FACTION_KER_ESCORTEE = 113 +}; + +//TODO: make concept similar as "ringo" -escort. Find a way to run the scripted attacks, _if_ player are choosing road. +class npc_kerlonian : public CreatureScript +{ +public: + npc_kerlonian() : CreatureScript("npc_kerlonian") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_SLEEPER_AWAKENED) + { + if (npc_kerlonianAI* pKerlonianAI = CAST_AI(npc_kerlonian::npc_kerlonianAI, creature->AI())) + { + creature->SetStandState(UNIT_STAND_STATE_STAND); + creature->AI()->Talk(SAY_KER_START, player->GetGUID()); + pKerlonianAI->StartFollow(player, FACTION_KER_ESCORTEE, quest); + } + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kerlonianAI(creature); + } + + struct npc_kerlonianAI : public FollowerAI + { + npc_kerlonianAI(Creature* creature) : FollowerAI(creature) { } + + uint32 FallAsleepTimer; + + void Reset() + { + FallAsleepTimer = urand(10000, 45000); + } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_LILADRIS) + { + if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE*5)) + { + if (Player* player = GetLeaderForFollower()) + { + if (player->GetQuestStatus(QUEST_SLEEPER_AWAKENED) == QUEST_STATUS_INCOMPLETE) + player->GroupEventHappens(QUEST_SLEEPER_AWAKENED, me); + + Talk(SAY_KER_END); + } + + SetFollowComplete(); + } + } + } + + void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) + { + if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_AWAKEN) + ClearSleeping(); + } + + void SetSleeping() + { + SetFollowPaused(true); + + Talk(EMOTE_KER_SLEEP); + + Talk(SAY_KER_SLEEP); + + me->SetStandState(UNIT_STAND_STATE_SLEEP); + DoCast(me, SPELL_SLEEP_VISUAL, false); + } + + void ClearSleeping() + { + me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL); + me->SetStandState(UNIT_STAND_STATE_STAND); + + Talk(EMOTE_KER_AWAKEN); + + SetFollowPaused(false); + } + + void UpdateFollowerAI(const uint32 Diff) + { + if (!UpdateVictim()) + { + if (!HasFollowState(STATE_FOLLOW_INPROGRESS)) + return; + + if (!HasFollowState(STATE_FOLLOW_PAUSED)) + { + if (FallAsleepTimer <= Diff) + { + SetSleeping(); + FallAsleepTimer = urand(25000, 90000); + } + else + FallAsleepTimer -= Diff; + } + + return; + } + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*#### +# npc_prospector_remtravel +####*/ + +enum Remtravel +{ + SAY_REM_START = 0, + SAY_REM_AGGRO = 1, + SAY_REM_RAMP1_1 = 2, + SAY_REM_RAMP1_2 = 3, + SAY_REM_BOOK = 4, + SAY_REM_TENT1_1 = 5, + SAY_REM_TENT1_2 = 6, + SAY_REM_MOSS = 7, + EMOTE_REM_MOSS = 8, + SAY_REM_MOSS_PROGRESS = 9, + SAY_REM_PROGRESS = 10, + SAY_REM_REMEMBER = 11, + EMOTE_REM_END = 12, + + FACTION_ESCORTEE = 10, + QUEST_ABSENT_MINDED_PT2 = 731, + NPC_GRAVEL_SCOUT = 2158, + NPC_GRAVEL_BONE = 2159, + NPC_GRAVEL_GEO = 2160 +}; + +class npc_prospector_remtravel : public CreatureScript +{ +public: + npc_prospector_remtravel() : CreatureScript("npc_prospector_remtravel") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_ABSENT_MINDED_PT2) + { + if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_remtravel::npc_prospector_remtravelAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID()); + + creature->setFaction(FACTION_ESCORTEE); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_prospector_remtravelAI(creature); + } + + struct npc_prospector_remtravelAI : public npc_escortAI + { + npc_prospector_remtravelAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 0: + Talk(SAY_REM_START, player->GetGUID()); + break; + case 5: + Talk(SAY_REM_RAMP1_1, player->GetGUID()); + break; + case 6: + DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 9: + Talk(SAY_REM_RAMP1_2, player->GetGUID()); + break; + case 14: + //depend quest rewarded? + Talk(SAY_REM_BOOK, player->GetGUID()); + break; + case 15: + Talk(SAY_REM_TENT1_1, player->GetGUID()); + break; + case 16: + DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 17: + Talk(SAY_REM_TENT1_2, player->GetGUID()); + break; + case 26: + Talk(SAY_REM_MOSS, player->GetGUID()); + break; + case 27: + Talk(EMOTE_REM_MOSS, player->GetGUID()); + break; + case 28: + Talk(SAY_REM_MOSS_PROGRESS, player->GetGUID()); + break; + case 29: + DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 31: + Talk(SAY_REM_PROGRESS, player->GetGUID()); + break; + case 41: + Talk(SAY_REM_REMEMBER, player->GetGUID()); + break; + case 42: + Talk(EMOTE_REM_END, player->GetGUID()); + player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me); + break; + } + } + } + + void Reset() {} + + void EnterCombat(Unit* who) + { + if (urand(0, 1)) + Talk(SAY_REM_AGGRO, who->GetGUID()); + } + + void JustSummoned(Creature* /*pSummoned*/) + { + //unsure if it should be any + //pSummoned->AI()->AttackStart(me); + } + }; + +}; + +/*#### +# npc_threshwackonator +####*/ + +enum Threshwackonator +{ + EMOTE_START = 0, + SAY_AT_CLOSE = 1, + QUEST_GYROMAST_REV = 2078, + NPC_GELKAK = 6667, + FACTION_HOSTILE = 14 +}; + +#define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key" + +class npc_threshwackonator : public CreatureScript +{ +public: + npc_threshwackonator() : CreatureScript("npc_threshwackonator") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + + if (npc_threshwackonatorAI* pThreshAI = CAST_AI(npc_threshwackonator::npc_threshwackonatorAI, creature->AI())) + { + creature->AI()->Talk(EMOTE_START); + pThreshAI->StartFollow(player); + } + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_GYROMAST_REV) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INSERT_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_threshwackonatorAI(creature); + } + + struct npc_threshwackonatorAI : public FollowerAI + { + npc_threshwackonatorAI(Creature* creature) : FollowerAI(creature) { } + + void Reset() { } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_GELKAK) + { + if (me->IsWithinDistInMap(who, 10.0f)) + { + Talk(SAY_AT_CLOSE, who->GetGUID()); + DoAtEnd(); + } + } + } + + void DoAtEnd() + { + me->setFaction(FACTION_HOSTILE); + + if (Player* pHolder = GetLeaderForFollower()) + me->AI()->AttackStart(pHolder); + + SetFollowComplete(); + } + }; + +}; + +void AddSC_darkshore() +{ + new npc_kerlonian(); + new npc_prospector_remtravel(); + new npc_threshwackonator(); +} diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp new file mode 100644 index 00000000000..8f55bb6102c --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Desolace +SD%Complete: 100 +SDComment: Quest support: 5561 +SDCategory: Desolace +EndScriptData */ + +/* ContentData +npc_aged_dying_ancient_kodo +go_iruxos +npc_dalinda_malem +go_demon_portal +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "SpellInfo.h" + +enum DyingKodo +{ + // signed for 9999 + SAY_SMEED_HOME = 0, + + QUEST_KODO = 5561, + + NPC_SMEED = 11596, + NPC_AGED_KODO = 4700, + NPC_DYING_KODO = 4701, + NPC_ANCIENT_KODO = 4702, + NPC_TAMED_KODO = 11627, + + SPELL_KODO_KOMBO_ITEM = 18153, + SPELL_KODO_KOMBO_PLAYER_BUFF = 18172, //spells here have unclear function, but using them at least for visual parts and checks + SPELL_KODO_KOMBO_DESPAWN_BUFF = 18377, + SPELL_KODO_KOMBO_GOSSIP = 18362 + +}; + +class npc_aged_dying_ancient_kodo : public CreatureScript +{ +public: + npc_aged_dying_ancient_kodo() : CreatureScript("npc_aged_dying_ancient_kodo") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) && creature->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) + { + //the expected quest objective + player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); + + player->RemoveAurasDueToSpell(SPELL_KODO_KOMBO_PLAYER_BUFF); + creature->GetMotionMaster()->MoveIdle(); + } + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool EffectDummyCreature(Unit* pCaster, uint32 spellId, uint32 effIndex, Creature* creatureTarget) + { + //always check spellid and effectindex + if (spellId == SPELL_KODO_KOMBO_ITEM && effIndex == 0) + { + //no effect if player/creature already have aura from spells + if (pCaster->HasAura(SPELL_KODO_KOMBO_PLAYER_BUFF) || creatureTarget->HasAura(SPELL_KODO_KOMBO_DESPAWN_BUFF)) + return true; + + if (creatureTarget->GetEntry() == NPC_AGED_KODO || + creatureTarget->GetEntry() == NPC_DYING_KODO || + creatureTarget->GetEntry() == NPC_ANCIENT_KODO) + { + pCaster->CastSpell(pCaster, SPELL_KODO_KOMBO_PLAYER_BUFF, true); + + creatureTarget->UpdateEntry(NPC_TAMED_KODO); + creatureTarget->CastSpell(creatureTarget, SPELL_KODO_KOMBO_DESPAWN_BUFF, false); + + if (creatureTarget->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + creatureTarget->GetMotionMaster()->MoveIdle(); + + creatureTarget->GetMotionMaster()->MoveFollow(pCaster, PET_FOLLOW_DIST, creatureTarget->GetFollowAngle()); + } + + //always return true when we are handling this spell and effect + return true; + } + return false; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_aged_dying_ancient_kodoAI(creature); + } + + struct npc_aged_dying_ancient_kodoAI : public ScriptedAI + { + npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { Reset(); } + + uint32 DespawnTimer; + + void Reset() + { + DespawnTimer = 0; + } + + void MoveInLineOfSight(Unit* who) + { + if (who->GetEntry() == NPC_SMEED) + { + if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) + return; + + if (me->IsWithinDistInMap(who, 10.0f)) + { + if (Creature* talker = who->ToCreature()) + talker->AI()->Talk(SAY_SMEED_HOME); + + //spell have no implemented effect (dummy), so useful to notify spellHit + DoCast(me, SPELL_KODO_KOMBO_GOSSIP, true); + } + } + } + + void SpellHit(Unit* /*pCaster*/, SpellInfo const* pSpell) + { + if (pSpell->Id == SPELL_KODO_KOMBO_GOSSIP) + { + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + DespawnTimer = 60000; + } + } + + void UpdateAI(const uint32 diff) + { + //timer should always be == 0 unless we already updated entry of creature. Then not expect this updated to ever be in combat. + if (DespawnTimer && DespawnTimer <= diff) + { + if (!me->getVictim() && me->isAlive()) + { + Reset(); + me->setDeathState(JUST_DIED); + me->Respawn(); + return; + } + } else DespawnTimer -= diff; + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*###### +## go_iruxos +## Hand of Iruxos +######*/ + +enum Iruxos +{ + QUEST_HAND_IRUXOS = 5381, + NPC_DEMON_SPIRIT = 11876, +}; + +class go_iruxos : public GameObjectScript +{ + public: + go_iruxos() : GameObjectScript("go_iruxos") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_HAND_IRUXOS) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_SPIRIT, 25.0f, true)) + player->SummonCreature(NPC_DEMON_SPIRIT, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + + return true; + } +}; + +/*###### +## npc_dalinda_malem. Quest 1440 +######*/ + +enum Dalinda +{ + QUEST_RETURN_TO_VAHLARRIEL = 1440 +}; + +class npc_dalinda : public CreatureScript +{ +public: + npc_dalinda() : CreatureScript("npc_dalinda") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_RETURN_TO_VAHLARRIEL) + { + if (npc_escortAI* pEscortAI = CAST_AI(npc_dalinda::npc_dalindaAI, creature->AI())) + { + pEscortAI->Start(true, false, player->GetGUID()); + creature->setFaction(113); + } + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_dalindaAI(creature); + } + + struct npc_dalindaAI : public npc_escortAI + { + npc_dalindaAI(Creature* creature) : npc_escortAI(creature) { } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + + switch (waypointId) + { + case 1: + me->IsStandState(); + break; + case 15: + if (player) + player->GroupEventHappens(QUEST_RETURN_TO_VAHLARRIEL, me); + break; + } + } + + void EnterCombat(Unit* /*who*/) { } + + void Reset() {} + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_RETURN_TO_VAHLARRIEL); + return; + } + + void UpdateAI(const uint32 Diff) + { + npc_escortAI::UpdateAI(Diff); + if (!UpdateVictim()) + return; + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## go_demon_portal +######*/ + +enum DemonPortal +{ + NPC_DEMON_GUARDIAN = 11937, + + QUEST_PORTAL_OF_THE_LEGION = 5581, +}; + +class go_demon_portal : public GameObjectScript +{ + public: + go_demon_portal() : GameObjectScript("go_demon_portal") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true)) + { + if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0)) + guardian->AI()->AttackStart(player); + } + + return true; + } +}; + +void AddSC_desolace() +{ + new npc_aged_dying_ancient_kodo(); + new go_iruxos(); + new npc_dalinda(); + new go_demon_portal(); +} diff --git a/src/server/scripts/Kalimdor/zone_durotar.cpp b/src/server/scripts/Kalimdor/zone_durotar.cpp new file mode 100644 index 00000000000..fa6b830c1ae --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_durotar.cpp @@ -0,0 +1,589 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Vehicle.h" +#include "SpellScript.h" +#include "Player.h" + +/*###### +##Quest 5441: Lazy Peons +##npc_lazy_peon +######*/ + +enum LazyPeonYells +{ + SAY_SPELL_HIT = 0 +}; + +enum LazyPeon +{ + QUEST_LAZY_PEONS = 5441, + GO_LUMBERPILE = 175784, + SPELL_BUFF_SLEEP = 17743, + SPELL_AWAKEN_PEON = 19938 +}; + +class npc_lazy_peon : public CreatureScript +{ +public: + npc_lazy_peon() : CreatureScript("npc_lazy_peon") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lazy_peonAI(creature); + } + + struct npc_lazy_peonAI : public ScriptedAI + { + npc_lazy_peonAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + + uint32 RebuffTimer; + bool work; + + void Reset() + { + PlayerGUID = 0; + RebuffTimer = 0; + work = false; + } + + void MovementInform(uint32 /*type*/, uint32 id) + { + if (id == 1) + work = true; + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id == SPELL_AWAKEN_PEON && caster->GetTypeId() == TYPEID_PLAYER + && CAST_PLR(caster)->GetQuestStatus(QUEST_LAZY_PEONS) == QUEST_STATUS_INCOMPLETE) + { + caster->ToPlayer()->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); + Talk(SAY_SPELL_HIT, caster->GetGUID()); + me->RemoveAllAuras(); + if (GameObject* Lumberpile = me->FindNearestGameObject(GO_LUMBERPILE, 20)) + me->GetMotionMaster()->MovePoint(1, Lumberpile->GetPositionX()-1, Lumberpile->GetPositionY(), Lumberpile->GetPositionZ()); + } + } + + void UpdateAI(const uint32 Diff) + { + if (work == true) + me->HandleEmoteCommand(EMOTE_ONESHOT_WORK_CHOPWOOD); + if (RebuffTimer <= Diff) + { + DoCast(me, SPELL_BUFF_SLEEP); + RebuffTimer = 300000; //Rebuff agian in 5 minutes + } + else + RebuffTimer -= Diff; + if (!UpdateVictim()) + return; + DoMeleeAttackIfReady(); + } + }; +}; + +enum Texts +{ + // Tiger Matriarch Credit + SAY_MATRIARCH_AGGRO = 0, + + // Troll Volunteer + SAY_VOLUNTEER_START = 0, + SAY_VOLUNTEER_END = 1, +}; + +enum Spells +{ + // Tiger Matriarch Credit + SPELL_SUMMON_MATRIARCH = 75187, + SPELL_NO_SUMMON_AURA = 75213, + SPELL_DETECT_INVIS = 75180, + SPELL_SUMMON_ZENTABRA_TRIGGER = 75212, + + // Tiger Matriarch + SPELL_POUNCE = 61184, + SPELL_FURIOUS_BITE = 75164, + SPELL_SUMMON_ZENTABRA = 75181, + SPELL_SPIRIT_OF_THE_TIGER_RIDER = 75166, + SPELL_EJECT_PASSENGERS = 50630, + + // Troll Volunteer + SPELL_VOLUNTEER_AURA = 75076, + SPELL_PETACT_AURA = 74071, + SPELL_QUEST_CREDIT = 75106, + SPELL_MOUNTING_CHECK = 75420, + SPELL_TURNIN = 73953, + SPELL_AOE_TURNIN = 75107, + + // Vol'jin War Drums + SPELL_MOTIVATE_1 = 75088, + SPELL_MOTIVATE_2 = 75086, +}; + +enum Creatures +{ + // Tiger Matriarch Credit + NPC_TIGER_VEHICLE = 40305, + + // Troll Volunteer + NPC_URUZIN = 40253, + NPC_VOLUNTEER_1 = 40264, + NPC_VOLUNTEER_2 = 40260, + + // Vol'jin War Drums + NPC_CITIZEN_1 = 40256, + NPC_CITIZEN_2 = 40257, +}; + +enum Events +{ + // Tiger Matriarch Credit + EVENT_CHECK_SUMMON_AURA = 1, + + // Tiger Matriarch + EVENT_POUNCE = 2, + EVENT_NOSUMMON = 3, +}; + +enum Points +{ + POINT_URUZIN = 4026400, +}; + +class npc_tiger_matriarch_credit : public CreatureScript +{ + public: + npc_tiger_matriarch_credit() : CreatureScript("npc_tiger_matriarch_credit") { } + + struct npc_tiger_matriarch_creditAI : public Scripted_NoMovementAI + { + npc_tiger_matriarch_creditAI(Creature* creature) : Scripted_NoMovementAI(creature) + { + events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 2000); + } + + void UpdateAI(uint32 const diff) + { + events.Update(diff); + + if (events.ExecuteEvent() == EVENT_CHECK_SUMMON_AURA) + { + std::list tigers; + GetCreatureListWithEntryInGrid(tigers, me, NPC_TIGER_VEHICLE, 15.0f); + if (!tigers.empty()) + { + for (std::list::iterator itr = tigers.begin(); itr != tigers.end(); ++itr) + { + if (!(*itr)->isSummon()) + continue; + + if (Unit* summoner = (*itr)->ToTempSummon()->GetSummoner()) + if (!summoner->HasAura(SPELL_NO_SUMMON_AURA) && !summoner->HasAura(SPELL_SUMMON_ZENTABRA_TRIGGER) + && !summoner->isInCombat()) + { + me->AddAura(SPELL_NO_SUMMON_AURA, summoner); + me->AddAura(SPELL_DETECT_INVIS, summoner); + summoner->CastSpell(summoner, SPELL_SUMMON_MATRIARCH, true); + Talk(SAY_MATRIARCH_AGGRO, summoner->GetGUID()); + } + } + } + + events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 5000); + } + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tiger_matriarch_creditAI(creature); + } +}; + +class npc_tiger_matriarch : public CreatureScript +{ + public: + npc_tiger_matriarch() : CreatureScript("npc_tiger_matriarch") {} + + struct npc_tiger_matriarchAI : public ScriptedAI + { + npc_tiger_matriarchAI(Creature* creature) : ScriptedAI(creature), + _tigerGuid(0) + { + } + + void EnterCombat(Unit* /*target*/) + { + _events.Reset(); + _events.ScheduleEvent(EVENT_POUNCE, 100); + _events.ScheduleEvent(EVENT_NOSUMMON, 50000); + } + + void IsSummonedBy(Unit* summoner) + { + if (summoner->GetTypeId() != TYPEID_PLAYER || !summoner->GetVehicle()) + return; + + _tigerGuid = summoner->GetVehicle()->GetBase()->GetGUID(); + if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid)) + { + me->AddThreat(tiger, 500000.0f); + DoCast(me, SPELL_FURIOUS_BITE); + } + } + + void KilledUnit(Unit* victim) + { + if (victim->GetTypeId() != TYPEID_UNIT || !victim->isSummon()) + return; + + if (Unit* vehSummoner = victim->ToTempSummon()->GetSummoner()) + { + vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA); + vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS); + vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); + vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); + } + me->DespawnOrUnsummon(); + } + + void DamageTaken(Unit* attacker, uint32& damage) + { + if (!attacker->isSummon()) + return; + + if (HealthBelowPct(20)) + { + damage = 0; + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (Unit* vehSummoner = attacker->ToTempSummon()->GetSummoner()) + { + vehSummoner->AddAura(SPELL_SUMMON_ZENTABRA_TRIGGER, vehSummoner); + vehSummoner->CastSpell(vehSummoner, SPELL_SUMMON_ZENTABRA, true); + attacker->CastSpell(attacker, SPELL_EJECT_PASSENGERS, true); + vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA); + vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS); + vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER); + vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER); + } + + me->DespawnOrUnsummon(); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (!_tigerGuid) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_POUNCE: + DoCastVictim(SPELL_POUNCE); + _events.ScheduleEvent(EVENT_POUNCE, 30000); + break; + case EVENT_NOSUMMON: // Reapply SPELL_NO_SUMMON_AURA + if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid)) + { + if (tiger->isSummon()) + if (Unit* vehSummoner = tiger->ToTempSummon()->GetSummoner()) + me->AddAura(SPELL_NO_SUMMON_AURA, vehSummoner); + } + _events.ScheduleEvent(EVENT_NOSUMMON, 50000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + uint64 _tigerGuid; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tiger_matriarchAI(creature); + } +}; + +// These models was found in sniff. +// TODO: generalize these models with race from dbc +uint32 const trollmodel[] = +{11665, 11734, 11750, 12037, 12038, 12042, 12049, 12849, 13529, 14759, 15570, 15701, +15702, 1882, 1897, 1976, 2025, 27286, 2734, 2735, 4084, 4085, 4087, 4089, 4231, 4357, +4358, 4360, 4361, 4362, 4363, 4370, 4532, 4537, 4540, 4610, 6839, 7037, 9767, 9768}; + +class npc_troll_volunteer : public CreatureScript +{ + public: + npc_troll_volunteer() : CreatureScript("npc_troll_volunteer") { } + + struct npc_troll_volunteerAI : public ScriptedAI + { + npc_troll_volunteerAI(Creature* creature) : ScriptedAI(creature) + { + } + + void InitializeAI() + { + if (me->isDead() || !me->GetOwner()) + return; + + Reset(); + + switch (urand(0, 3)) + { + case 0: + _mountModel = 6471; + break; + case 1: + _mountModel = 6473; + break; + case 2: + _mountModel = 6469; + break; + default: + _mountModel = 6472; + break; + } + me->SetDisplayId(trollmodel[urand(0, 39)]); + if (Player* player = me->GetOwner()->ToPlayer()) + me->GetMotionMaster()->MoveFollow(player, 5.0f, float(rand_norm() + 1.0f) * M_PI / 3.0f * 4.0f); + } + + void Reset() + { + _complete = false; + me->AddAura(SPELL_VOLUNTEER_AURA, me); + me->AddAura(SPELL_MOUNTING_CHECK, me); + DoCast(me, SPELL_PETACT_AURA); + me->SetReactState(REACT_PASSIVE); + Talk(SAY_VOLUNTEER_START); + } + + // This is needed for mount check aura to know what mountmodel the npc got stored + uint32 GetMountId() + { + return _mountModel; + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + if (id == POINT_URUZIN) + me->DespawnOrUnsummon(); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) + { + if (spell->Id == SPELL_AOE_TURNIN && caster->GetEntry() == NPC_URUZIN && !_complete) + { + _complete = true; // Preventing from giving credit twice + DoCast(me, SPELL_TURNIN); + DoCast(me, SPELL_QUEST_CREDIT); + me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK); + me->Dismount(); + Talk(SAY_VOLUNTEER_END); + me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); + } + } + + private: + uint32 _mountModel; + bool _complete; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_troll_volunteerAI(creature); + } +}; + +typedef npc_troll_volunteer::npc_troll_volunteerAI VolunteerAI; + +class spell_mount_check : public SpellScriptLoader +{ + public: + spell_mount_check() : SpellScriptLoader("spell_mount_check") {} + + class spell_mount_check_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mount_check_AuraScript) + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTING_CHECK)) + return false; + return true; + } + + void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) + { + Unit* target = GetTarget(); + Unit* owner = target->GetOwner(); + + if (!owner) + return; + + if (owner->IsMounted() && !target->IsMounted()) + { + if (VolunteerAI* volunteerAI = CAST_AI(VolunteerAI, target->GetAI())) + target->Mount(volunteerAI->GetMountId()); + } + else if (!owner->IsMounted() && target->IsMounted()) + target->Dismount(); + + target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); + target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mount_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_mount_check_AuraScript(); + } +}; + +class spell_voljin_war_drums : public SpellScriptLoader +{ + public: + spell_voljin_war_drums() : SpellScriptLoader("spell_voljin_war_drums") {} + + class spell_voljin_war_drums_SpellScript : public SpellScript + { + PrepareSpellScript(spell_voljin_war_drums_SpellScript) + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_1)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_2)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (Unit* target = GetHitUnit()) + { + uint32 motivate = 0; + if (target->GetEntry() == NPC_CITIZEN_1) + motivate = SPELL_MOTIVATE_1; + else if (target->GetEntry() == NPC_CITIZEN_2) + motivate = SPELL_MOTIVATE_2; + if (motivate) + caster->CastSpell(target, motivate, false); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_voljin_war_drums_SpellScript(); + } +}; + +enum VoodooSpells +{ + SPELL_BREW = 16712, // Special Brew + SPELL_GHOSTLY = 16713, // Ghostly + SPELL_HEX1 = 16707, // Hex + SPELL_HEX2 = 16708, // Hex + SPELL_HEX3 = 16709, // Hex + SPELL_GROW = 16711, // Grow + SPELL_LAUNCH = 16716, // Launch (Whee!) +}; + +// 17009 +class spell_voodoo : public SpellScriptLoader +{ + public: + spell_voodoo() : SpellScriptLoader("spell_voodoo") {} + + class spell_voodoo_SpellScript : public SpellScript + { + PrepareSpellScript(spell_voodoo_SpellScript) + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_BREW) || !sSpellMgr->GetSpellInfo(SPELL_GHOSTLY) || + !sSpellMgr->GetSpellInfo(SPELL_HEX1) || !sSpellMgr->GetSpellInfo(SPELL_HEX2) || + !sSpellMgr->GetSpellInfo(SPELL_HEX3) || !sSpellMgr->GetSpellInfo(SPELL_GROW) || + !sSpellMgr->GetSpellInfo(SPELL_LAUNCH)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + uint32 spellid = RAND(SPELL_BREW, SPELL_GHOSTLY, RAND(SPELL_HEX1, SPELL_HEX2, SPELL_HEX3), SPELL_GROW, SPELL_LAUNCH); + if (Unit* target = GetHitUnit()) + GetCaster()->CastSpell(target, spellid, false); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_voodoo_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_voodoo_SpellScript(); + } +}; + +void AddSC_durotar() +{ + new npc_lazy_peon(); + new npc_tiger_matriarch_credit(); + new npc_tiger_matriarch(); + new npc_troll_volunteer(); + new spell_mount_check(); + new spell_voljin_war_drums(); + new spell_voodoo(); +} diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp new file mode 100644 index 00000000000..37941227c78 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp @@ -0,0 +1,780 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Dustwallow_Marsh +SD%Complete: 95 +SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle +SDCategory: Dustwallow Marsh +EndScriptData */ + +/* ContentData +mobs_risen_husk_spirit +npc_lady_jaina_proudmoore +npc_nat_pagle +npc_private_hendel +npc_cassa_crimsonwing - handled by npc_taxi +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" +#include "SpellScript.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## mobs_risen_husk_spirit +######*/ + +enum HauntingWitchHill +{ + // Quest + QUEST_WHATS_HAUNTING_WITCH_HILL = 11180, + + // General spells + SPELL_SUMMON_RESTLESS_APPARITION = 42511, + SPELL_WITCH_HILL_INFORMATION_CREDIT = 42512, + + // Risen Husk specific + SPELL_CONSUME_FLESH = 37933, + NPC_RISEN_HUSK = 23555, + + // Risen Spirit specific + SPELL_INTANGIBLE_PRESENCE = 43127, + NPC_RISEN_SPIRIT = 23554, + + // Events + EVENT_CONSUME_FLESH = 0, + EVENT_INTANGIBLE_PRESENCE = 1, +}; + +class mobs_risen_husk_spirit : public CreatureScript +{ + public: + mobs_risen_husk_spirit() : CreatureScript("mobs_risen_husk_spirit") { } + + struct mobs_risen_husk_spiritAI : public ScriptedAI + { + mobs_risen_husk_spiritAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() + { + events.Reset(); + if (me->GetEntry() == NPC_RISEN_HUSK) + events.ScheduleEvent(EVENT_CONSUME_FLESH, 5000); + else if (me->GetEntry() == NPC_RISEN_SPIRIT) + events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 5000); + } + + void JustDied(Unit* killer) + { + if (killer->GetTypeId() == TYPEID_PLAYER) + { + if (killer->ToPlayer()->GetQuestStatus(QUEST_WHATS_HAUNTING_WITCH_HILL) == QUEST_STATUS_INCOMPLETE) + { + DoCast(me, SPELL_SUMMON_RESTLESS_APPARITION, true); + DoCast(killer, SPELL_WITCH_HILL_INFORMATION_CREDIT, true); + } + } + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CONSUME_FLESH: + DoCastVictim(SPELL_CONSUME_FLESH); + events.ScheduleEvent(EVENT_CONSUME_FLESH, 15000); + break; + case EVENT_INTANGIBLE_PRESENCE: + DoCastVictim(SPELL_INTANGIBLE_PRESENCE); + events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 15000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new mobs_risen_husk_spiritAI (creature); + } +}; + +/*###### +## npc_theramor_guard +######*/ + +enum TheramoreGuard +{ + QUEST_DISCREDITING_THE_DESERTERS = 11133, + + NPC_THERAMORE_GUARD = 4979, + + SPELL_DOCTORED_LEAFLET = 42725, + SPELL_PROPAGANDIZED = 42246, + + SAY_QUEST1 = 0, + SAY_QUEST2 = 1, + SAY_QUEST3 = 2 +}; + +#define GOSSIP_ITEM_THERAMORE_GUARD "You look like an intelligent person. Why don't you read one of these leaflets and give it some thought?" + +class npc_theramore_guard : public CreatureScript +{ +public: + npc_theramore_guard() : CreatureScript("npc_theramore_guard") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_DISCREDITING_THE_DESERTERS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THERAMORE_GUARD, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + + if (action == GOSSIP_SENDER_INFO) + { + player->CLOSE_GOSSIP_MENU(); + player->KilledMonsterCredit(NPC_THERAMORE_GUARD, 0); + creature->AI()->Talk(SAY_QUEST1); + creature->CastSpell(creature, SPELL_DOCTORED_LEAFLET, false); + creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->YellTimer = 4000; + CAST_AI(npc_theramore_guard::npc_theramore_guardAI, creature->AI())->bYellTimer = true; + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_theramore_guardAI(creature); + } + + struct npc_theramore_guardAI : public ScriptedAI + { + npc_theramore_guardAI(Creature* creature) : ScriptedAI(creature) { } + + uint32 YellTimer; + uint32 Step; + bool bYellTimer; + + void Reset() + { + bYellTimer = false; + Step = 0; + } + + void UpdateAI(const uint32 Diff) + { + if (!me->HasAura(SPELL_PROPAGANDIZED)) + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + if (bYellTimer && YellTimer <= Diff) + { + switch (Step) + { + case 0: + Talk(SAY_QUEST2); + YellTimer = 3000; + ++Step; + break; + case 1: + Talk(SAY_QUEST3); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); + Step = 0; + bYellTimer = false; + break; + } + } + else + YellTimer -= Diff; + } + }; +}; + +/*###### +## npc_lady_jaina_proudmoore +######*/ + +enum LadyJaina +{ + QUEST_JAINAS_AUTOGRAPH = 558, + SPELL_JAINAS_AUTOGRAPH = 23122 +}; + +#define GOSSIP_ITEM_JAINA "I know this is rather silly but i have a young ward who is a bit shy and would like your autograph." + +class npc_lady_jaina_proudmoore : public CreatureScript +{ +public: + npc_lady_jaina_proudmoore() : CreatureScript("npc_lady_jaina_proudmoore") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_SENDER_INFO) + { + player->SEND_GOSSIP_MENU(7012, creature->GetGUID()); + player->CastSpell(player, SPELL_JAINAS_AUTOGRAPH, false); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_JAINAS_AUTOGRAPH) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_JAINA, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_nat_pagle +######*/ + +enum NatPagle +{ + QUEST_NATS_MEASURING_TAPE = 8227 +}; + +class npc_nat_pagle : public CreatureScript +{ +public: + npc_nat_pagle() : CreatureScript("npc_nat_pagle") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor() && player->GetQuestRewardStatus(QUEST_NATS_MEASURING_TAPE)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(7640, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(7638, creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_private_hendel +######*/ + +enum Hendel +{ + SAY_PROGRESS_1_TER = 0, + SAY_PROGRESS_2_HEN = 1, + SAY_PROGRESS_3_TER = 2, + SAY_PROGRESS_4_TER = 3, + EMOTE_SURRENDER = 4, + + QUEST_MISSING_DIPLO_PT16 = 1324, + FACTION_HOSTILE = 168, //guessed, may be different + + NPC_SENTRY = 5184, //helps hendel + NPC_JAINA = 4968, //appears once hendel gives up + NPC_TERVOSH = 4967 +}; + +//TODO: develop this further, end event not created +class npc_private_hendel : public CreatureScript +{ +public: + npc_private_hendel() : CreatureScript("npc_private_hendel") { } + + bool OnQuestAccept(Player* /*player*/, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT16) + creature->setFaction(FACTION_HOSTILE); + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_private_hendelAI(creature); + } + + struct npc_private_hendelAI : public ScriptedAI + { + npc_private_hendelAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() + { + me->RestoreFaction(); + } + + void AttackedBy(Unit* pAttacker) + { + if (me->getVictim()) + return; + + if (me->IsFriendlyTo(pAttacker)) + return; + + AttackStart(pAttacker); + } + + void DamageTaken(Unit* pDoneBy, uint32 &Damage) + { + if (Damage > me->GetHealth() || me->HealthBelowPctDamaged(20, Damage)) + { + Damage = 0; + + if (Player* player = pDoneBy->GetCharmerOrOwnerPlayerOrPlayerItself()) + player->GroupEventHappens(QUEST_MISSING_DIPLO_PT16, me); + + Talk(EMOTE_SURRENDER); + EnterEvadeMode(); + } + } + }; + +}; + +/*###### +## npc_zelfrax +######*/ + +Position const MovePosition = {-2967.030f, -3872.1799f, 35.620f, 0.0f}; + +enum Zelfrax +{ + SAY_ZELFRAX1 = 0, + SAY_ZELFRAX2 = 1 +}; + +class npc_zelfrax : public CreatureScript +{ +public: + npc_zelfrax() : CreatureScript("npc_zelfrax") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_zelfraxAI(creature); + } + + struct npc_zelfraxAI : public ScriptedAI + { + npc_zelfraxAI(Creature* creature) : ScriptedAI(creature) + { + MoveToDock(); + } + + void AttackStart(Unit* who) + { + if (!who) + return; + + if (me->Attack(who, true)) + { + me->SetInCombatWith(who); + who->SetInCombatWith(me); + + if (IsCombatMovementAllowed()) + me->GetMotionMaster()->MoveChase(who); + } + } + + void MovementInform(uint32 Type, uint32 /*Id*/) + { + if (Type != POINT_MOTION_TYPE) + return; + + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + SetCombatMovement(true); + + if (me->isInCombat()) + if (Unit* unit = me->getVictim()) + me->GetMotionMaster()->MoveChase(unit); + } + + void MoveToDock() + { + SetCombatMovement(false); + me->GetMotionMaster()->MovePoint(0, MovePosition); + Talk(SAY_ZELFRAX1); + Talk(SAY_ZELFRAX2); + } + + void UpdateAI(uint32 const /*Diff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*###### +## npc_stinky +######*/ + +enum Stinky +{ + QUEST_STINKYS_ESCAPE_H = 1270, + QUEST_STINKYS_ESCAPE_A = 1222, + SAY_QUEST_ACCEPTED = 0, + SAY_STAY_1 = 1, + SAY_STAY_2 = 2, + SAY_STAY_3 = 3, + SAY_STAY_4 = 4, + SAY_STAY_5 = 5, + SAY_STAY_6 = 6, + SAY_QUEST_COMPLETE = 7, + SAY_ATTACKED_1 = 8, + EMOTE_DISAPPEAR = 9 +}; + +class npc_stinky : public CreatureScript +{ +public: + npc_stinky() : CreatureScript("npc_stinky") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_stinkyAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_STINKYS_ESCAPE_H || quest->GetQuestId() == QUEST_STINKYS_ESCAPE_A) + { + if (npc_stinkyAI* pEscortAI = CAST_AI(npc_stinky::npc_stinkyAI, creature->AI())) + { + creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE); + creature->SetStandState(UNIT_STAND_STATE_STAND); + creature->AI()->Talk(SAY_QUEST_ACCEPTED); + pEscortAI->Start(false, false, player->GetGUID()); + } + } + return true; + } + + struct npc_stinkyAI : public npc_escortAI + { + npc_stinkyAI(Creature* creature) : npc_escortAI(creature) { } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 7: + Talk(SAY_STAY_1, player->GetGUID()); + break; + case 11: + Talk(SAY_STAY_2, player->GetGUID()); + break; + case 25: + Talk(SAY_STAY_3, player->GetGUID()); + break; + case 26: + Talk(SAY_STAY_4, player->GetGUID()); + break; + case 27: + Talk(SAY_STAY_5, player->GetGUID()); + break; + case 28: + Talk(SAY_STAY_6, player->GetGUID()); + me->SetStandState(UNIT_STAND_STATE_KNEEL); + break; + case 29: + me->SetStandState(UNIT_STAND_STATE_STAND); + break; + case 37: + Talk(SAY_QUEST_COMPLETE, player->GetGUID()); + me->SetSpeed(MOVE_RUN, 1.2f, true); + me->SetWalk(false); + if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H)) + player->GroupEventHappens(QUEST_STINKYS_ESCAPE_H, me); + if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A)) + player->GroupEventHappens(QUEST_STINKYS_ESCAPE_A, me); + break; + case 39: + Talk(EMOTE_DISAPPEAR); + break; + } + } + + void EnterCombat(Unit* who) + { + Talk(SAY_ATTACKED_1, who->GetGUID()); + } + + void Reset() {} + + void JustDied(Unit* /*killer*/) + { + Player* player = GetPlayerForEscort(); + if (player && HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H)) + player->FailQuest(QUEST_STINKYS_ESCAPE_H); + + if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A)) + player->FailQuest(QUEST_STINKYS_ESCAPE_A); + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +enum SpellScripts +{ + SPELL_OOZE_ZAP = 42489, + SPELL_OOZE_ZAP_CHANNEL_END = 42485, + SPELL_OOZE_CHANNEL_CREDIT = 42486, + SPELL_ENERGIZED = 42492, +}; + +class spell_ooze_zap : public SpellScriptLoader +{ + public: + spell_ooze_zap() : SpellScriptLoader("spell_ooze_zap") { } + + class spell_ooze_zap_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ooze_zap_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP)) + return false; + return true; + } + + SpellCastResult CheckRequirement() + { + if (!GetCaster()->HasAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue())) + return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; // This is actually correct + + if (!GetExplTargetUnit()) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (GetHitUnit()) + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + OnCheckCast += SpellCheckCastFn(spell_ooze_zap_SpellScript::CheckRequirement); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_ooze_zap_SpellScript(); + } +}; + +class spell_ooze_zap_channel_end : public SpellScriptLoader +{ + public: + spell_ooze_zap_channel_end() : SpellScriptLoader("spell_ooze_zap_channel_end") { } + + class spell_ooze_zap_channel_end_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ooze_zap_channel_end_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_OOZE_ZAP_CHANNEL_END)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (Player* player = GetCaster()->ToPlayer()) + player->CastSpell(player, SPELL_OOZE_CHANNEL_CREDIT, true); + GetHitUnit()->Kill(GetHitUnit()); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_ooze_zap_channel_end_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_ooze_zap_channel_end_SpellScript(); + } +}; + +class spell_energize_aoe : public SpellScriptLoader +{ + public: + spell_energize_aoe() : SpellScriptLoader("spell_energize_aoe") { } + + class spell_energize_aoe_SpellScript : public SpellScript + { + PrepareSpellScript(spell_energize_aoe_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ENERGIZED)) + return false; + return true; + } + + void FilterTargets(std::list& targets) + { + for (std::list::iterator itr = targets.begin(); itr != targets.end();) + { + if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE) + ++itr; + else + targets.erase(itr++); + } + targets.push_back(GetCaster()); + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetCaster(), uint32(GetEffectValue()), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_energize_aoe_SpellScript(); + } +}; + +/*###### +## go_blackhoof_cage +######*/ + +enum PrisonersOfTheGrimTotems +{ + NPC_THERAMORE_PRISONER = 23720, + SAY_FREE = 0, +}; + +class go_blackhoof_cage : public GameObjectScript +{ +public: + go_blackhoof_cage() : GameObjectScript("go_blackhoof_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + if (Creature* prisoner = go->FindNearestCreature(NPC_THERAMORE_PRISONER, 1.0f)) + { + if (player) + player->KilledMonsterCredit(NPC_THERAMORE_PRISONER, 0); + + prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote) + prisoner->DespawnOrUnsummon(6000); + } + return true; + } +}; + +void AddSC_dustwallow_marsh() +{ + new mobs_risen_husk_spirit(); + new npc_lady_jaina_proudmoore(); + new npc_nat_pagle(); + new npc_private_hendel(); + new npc_zelfrax(); + new npc_stinky(); + new npc_theramore_guard(); + new spell_ooze_zap(); + new spell_ooze_zap_channel_end(); + new spell_energize_aoe(); + new go_blackhoof_cage(); +} diff --git a/src/server/scripts/Kalimdor/zone_felwood.cpp b/src/server/scripts/Kalimdor/zone_felwood.cpp new file mode 100644 index 00000000000..e23eaa961bb --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_felwood.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Felwood +SD%Complete: 95 +SDComment: Quest support: 4101, 4102 +SDCategory: Felwood +EndScriptData */ + +/* ContentData +npcs_riverbreeze_and_silversky +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npcs_riverbreeze_and_silversky +######*/ + +#define GOSSIP_ITEM_BEACON "Please make me a Cenarion Beacon" + +enum RiverbreezeAndSilversky +{ + SPELL_CENARION_BEACON = 15120, + + NPC_ARATHANDRIS_SILVERSKY = 9528, + NPC_MAYBESS_RIVERBREEZE = 9529, + + QUEST_CLEASING_FELWOOD_A = 4101, + QUEST_CLEASING_FELWOOD_H = 4102 +}; + +class npcs_riverbreeze_and_silversky : public CreatureScript +{ +public: + npcs_riverbreeze_and_silversky() : CreatureScript("npcs_riverbreeze_and_silversky") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_CENARION_BEACON, false); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + uint32 creatureId = creature->GetEntry(); + + if (creatureId == NPC_ARATHANDRIS_SILVERSKY) + { + if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_A)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(2848, creature->GetGUID()); + } else if (player->GetTeam() == HORDE) + player->SEND_GOSSIP_MENU(2845, creature->GetGUID()); + else + player->SEND_GOSSIP_MENU(2844, creature->GetGUID()); + } + + if (creatureId == NPC_MAYBESS_RIVERBREEZE) + { + if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_H)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(2849, creature->GetGUID()); + } else if (player->GetTeam() == ALLIANCE) + player->SEND_GOSSIP_MENU(2843, creature->GetGUID()); + else + player->SEND_GOSSIP_MENU(2842, creature->GetGUID()); + } + + return true; + } +}; + +void AddSC_felwood() +{ + new npcs_riverbreeze_and_silversky(); +} diff --git a/src/server/scripts/Kalimdor/zone_feralas.cpp b/src/server/scripts/Kalimdor/zone_feralas.cpp new file mode 100644 index 00000000000..b2326de86ab --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_feralas.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Feralas +SD%Complete: 100 +SDComment: Quest support: 3520, 2767, Special vendor Gregan Brewspewer +SDCategory: Feralas +EndScriptData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" +#include "SpellScript.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npc_gregan_brewspewer +######*/ + +#define GOSSIP_HELLO "Buy somethin', will ya?" + +class npc_gregan_brewspewer : public CreatureScript +{ +public: + npc_gregan_brewspewer() : CreatureScript("npc_gregan_brewspewer") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(2434, creature->GetGUID()); + } + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor() && player->GetQuestStatus(3909) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(2433, creature->GetGUID()); + return true; + } + +}; + +/*###### +## npc_oox22fe +######*/ + +enum OOX +{ + SAY_OOX_START = 0, + SAY_OOX_AGGRO = 1, + SAY_OOX_AMBUSH = 2, + SAY_OOX_END = 3, + + NPC_YETI = 7848, + NPC_GORILLA = 5260, + NPC_WOODPAW_REAVER = 5255, + NPC_WOODPAW_BRUTE = 5253, + NPC_WOODPAW_ALPHA = 5258, + NPC_WOODPAW_MYSTIC = 5254, + + QUEST_RESCUE_OOX22FE = 2767, + FACTION_ESCORTEE_A = 774, + FACTION_ESCORTEE_H = 775 +}; + +class npc_oox22fe : public CreatureScript +{ +public: + npc_oox22fe() : CreatureScript("npc_oox22fe") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_RESCUE_OOX22FE) + { + creature->AI()->Talk(SAY_OOX_START); + //change that the npc is not lying dead on the ground + creature->SetStandState(UNIT_STAND_STATE_STAND); + + if (player->GetTeam() == ALLIANCE) + creature->setFaction(FACTION_ESCORTEE_A); + + if (player->GetTeam() == HORDE) + creature->setFaction(FACTION_ESCORTEE_H); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_oox22fe::npc_oox22feAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_oox22feAI(creature); + } + + struct npc_oox22feAI : public npc_escortAI + { + npc_oox22feAI(Creature* creature) : npc_escortAI(creature) { } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + // First Ambush(3 Yetis) + case 11: + Talk(SAY_OOX_AMBUSH); + me->SummonCreature(NPC_YETI, -4841.01f, 1593.91f, 73.42f, 3.98f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_YETI, -4837.61f, 1568.58f, 78.21f, 3.13f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_YETI, -4841.89f, 1569.95f, 76.53f, 0.68f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + break; + //Second Ambush(3 Gorillas) + case 21: + Talk(SAY_OOX_AMBUSH); + me->SummonCreature(NPC_GORILLA, -4595.81f, 2005.99f, 53.08f, 3.74f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_GORILLA, -4597.53f, 2008.31f, 52.70f, 3.78f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_GORILLA, -4599.37f, 2010.59f, 52.77f, 3.84f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + break; + //Third Ambush(4 Gnolls) + case 30: + Talk(SAY_OOX_AMBUSH); + me->SummonCreature(NPC_WOODPAW_REAVER, -4425.14f, 2075.87f, 47.77f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_WOODPAW_BRUTE, -4426.68f, 2077.98f, 47.57f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_WOODPAW_MYSTIC, -4428.33f, 2080.24f, 47.43f, 3.87f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + me->SummonCreature(NPC_WOODPAW_ALPHA, -4430.04f, 2075.54f, 46.83f, 3.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); + break; + case 37: + Talk(SAY_OOX_END); + // Award quest credit + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_RESCUE_OOX22FE, me); + break; + } + } + + void Reset() + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + me->SetStandState(UNIT_STAND_STATE_DEAD); + } + + void EnterCombat(Unit* /*who*/) + { + //For an small probability the npc says something when he get aggro + if (urand(0, 9) > 7) + Talk(SAY_OOX_AGGRO); + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + }; + +}; + +/*###### +## npc_screecher_spirit +######*/ + +class npc_screecher_spirit : public CreatureScript +{ +public: + npc_screecher_spirit() : CreatureScript("npc_screecher_spirit") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + player->SEND_GOSSIP_MENU(2039, creature->GetGUID()); + player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + return true; + } + +}; + +enum GordunniTrap +{ + GO_GORDUNNI_DIRT_MOUND = 144064, +}; + +class spell_gordunni_trap : public SpellScriptLoader +{ + public: + spell_gordunni_trap() : SpellScriptLoader("spell_gordunni_trap") { } + + class spell_gordunni_trap_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gordunni_trap_SpellScript); + + void HandleDummy() + { + if (Unit* caster = GetCaster()) + if (GameObject* chest = caster->SummonGameObject(GO_GORDUNNI_DIRT_MOUND, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0)) + chest->SetSpellId(GetSpellInfo()->Id); + } + + void Register() + { + OnCast += SpellCastFn(spell_gordunni_trap_SpellScript::HandleDummy); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gordunni_trap_SpellScript(); + } +}; + +/*###### +## AddSC +######*/ + +void AddSC_feralas() +{ + new npc_gregan_brewspewer(); + new npc_oox22fe(); + new npc_screecher_spirit(); + new spell_gordunni_trap(); +} diff --git a/src/server/scripts/Kalimdor/zone_moonglade.cpp b/src/server/scripts/Kalimdor/zone_moonglade.cpp new file mode 100644 index 00000000000..e41ffae03e6 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_moonglade.cpp @@ -0,0 +1,714 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Moonglade +SD%Complete: 100 +SDComment: Quest support: 30, 272, 5929, 5930, 10965. Special Flight Paths for Druid class. +SDCategory: Moonglade +EndScriptData */ + +/* ContentData +npc_bunthen_plainswind +npc_great_bear_spirit +npc_silva_filnaveth +npc_clintar_spirit +npc_clintar_dreamwalker +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "ScriptedGossip.h" +#include "Player.h" +#include "SpellInfo.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" + +/*###### +## npc_bunthen_plainswind +######*/ + +enum Bunthen +{ + QUEST_SEA_LION_HORDE = 30, + QUEST_SEA_LION_ALLY = 272, + TAXI_PATH_ID_ALLY = 315, + TAXI_PATH_ID_HORDE = 316 +}; + +#define GOSSIP_ITEM_THUNDER "I'd like to fly to Thunder Bluff." +#define GOSSIP_ITEM_AQ_END "Do you know where I can find Half Pendant of Aquatic Endurance?" + +class npc_bunthen_plainswind : public CreatureScript +{ +public: + npc_bunthen_plainswind() : CreatureScript("npc_bunthen_plainswind") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + player->CLOSE_GOSSIP_MENU(); + if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) + player->ActivateTaxiPathTo(TAXI_PATH_ID_HORDE); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->SEND_GOSSIP_MENU(5373, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + player->SEND_GOSSIP_MENU(5376, creature->GetGUID()); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->getClass() != CLASS_DRUID) + player->SEND_GOSSIP_MENU(4916, creature->GetGUID()); + else if (player->GetTeam() != HORDE) + { + if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + + player->SEND_GOSSIP_MENU(4917, creature->GetGUID()); + } + else if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THUNDER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + + player->SEND_GOSSIP_MENU(4918, creature->GetGUID()); + } + return true; + } + +}; + +/*###### +## npc_great_bear_spirit +######*/ + +#define GOSSIP_BEAR1 "What do you represent, spirit?" +#define GOSSIP_BEAR2 "I seek to understand the importance of strength of the body." +#define GOSSIP_BEAR3 "I seek to understand the importance of strength of the heart." +#define GOSSIP_BEAR4 "I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw." + +class npc_great_bear_spirit : public CreatureScript +{ +public: + npc_great_bear_spirit() : CreatureScript("npc_great_bear_spirit") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(4721, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(4733, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(4734, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + player->SEND_GOSSIP_MENU(4735, creature->GetGUID()); + if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(5929); + if (player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(5930); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + //ally or horde quest + if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->SEND_GOSSIP_MENU(4719, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(4718, creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_silva_filnaveth +######*/ + +#define GOSSIP_ITEM_RUTHERAN "I'd like to fly to Rut'theran Village." +#define GOSSIP_ITEM_AQ_AGI "Do you know where I can find Half Pendant of Aquatic Agility?" + +class npc_silva_filnaveth : public CreatureScript +{ +public: + npc_silva_filnaveth() : CreatureScript("npc_silva_filnaveth") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + player->CLOSE_GOSSIP_MENU(); + if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) + player->ActivateTaxiPathTo(TAXI_PATH_ID_ALLY); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->SEND_GOSSIP_MENU(5374, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + player->SEND_GOSSIP_MENU(5375, creature->GetGUID()); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->getClass() != CLASS_DRUID) + player->SEND_GOSSIP_MENU(4913, creature->GetGUID()); + else if (player->GetTeam() != ALLIANCE) + { + if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + + player->SEND_GOSSIP_MENU(4915, creature->GetGUID()); + } + else if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RUTHERAN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + + player->SEND_GOSSIP_MENU(4914, creature->GetGUID()); + } + return true; + } + +}; + +/*###### +## npc_clintar_spirit +######*/ + +float const Clintar_spirit_WP[41][5] = +{ + //pos_x pos_y pos_z orien waitTime + {7465.28f, -3115.46f, 439.327f, 0.83f, 4000}, + {7476.49f, -3101, 443.457f, 0.89f, 0}, + {7486.57f, -3085.59f, 439.478f, 1.07f, 0}, + {7472.19f, -3085.06f, 443.142f, 3.07f, 0}, + {7456.92f, -3085.91f, 438.862f, 3.24f, 0}, + {7446.68f, -3083.43f, 438.245f, 2.40f, 0}, + {7446.17f, -3080.21f, 439.826f, 1.10f, 6000}, + {7452.41f, -3085.8f, 438.984f, 5.78f, 0}, + {7469.11f, -3084.94f, 443.048f, 6.25f, 0}, + {7483.79f, -3085.44f, 439.607f, 6.25f, 0}, + {7491.14f, -3090.96f, 439.983f, 5.44f, 0}, + {7497.62f, -3098.22f, 436.854f, 5.44f, 0}, + {7498.72f, -3113.41f, 434.596f, 4.84f, 0}, + {7500.06f, -3122.51f, 434.749f, 5.17f, 0}, + {7504.96f, -3131.53f, 434.475f, 4.74f, 0}, + {7504.31f, -3133.53f, 435.693f, 3.84f, 6000}, + {7504.55f, -3133.27f, 435.476f, 0.68f, 15000}, + {7501.99f, -3126.01f, 434.93f, 1.83f, 0}, + {7490.76f, -3114.97f, 434.431f, 2.51f, 0}, + {7479.64f, -3105.51f, 431.123f, 1.83f, 0}, + {7474.63f, -3086.59f, 428.994f, 1.83f, 2000}, + {7472.96f, -3074.18f, 427.566f, 1.57f, 0}, + {7472.25f, -3063, 428.268f, 1.55f, 0}, + {7473.46f, -3054.22f, 427.588f, 0.36f, 0}, + {7475.08f, -3053.6f, 428.653f, 0.36f, 6000}, + {7474.66f, -3053.56f, 428.433f, 3.19f, 4000}, + {7471.81f, -3058.84f, 427.073f, 4.29f, 0}, + {7472.16f, -3064.91f, 427.772f, 4.95f, 0}, + {7471.56f, -3085.36f, 428.924f, 4.72f, 0}, + {7473.56f, -3093.48f, 429.294f, 5.04f, 0}, + {7478.94f, -3104.29f, 430.638f, 5.23f, 0}, + {7484.46f, -3109.61f, 432.769f, 5.79f, 0}, + {7490.23f, -3111.08f, 434.431f, 0.02f, 0}, + {7496.29f, -3108, 434.783f, 1.15f, 0}, + {7497.46f, -3100.66f, 436.191f, 1.50f, 0}, + {7495.64f, -3093.39f, 438.349f, 2.10f, 0}, + {7492.44f, -3086.01f, 440.267f, 1.38f, 0}, + {7498.26f, -3076.44f, 440.808f, 0.71f, 0}, + {7506.4f, -3067.35f, 443.64f, 0.77f, 0}, + {7518.37f, -3057.42f, 445.584f, 0.74f, 0}, + {7517.51f, -3056.3f, 444.568f, 2.49f, 4500} +}; + +Position const AspectRavenSummon = {7472.96f, -3074.18f, 427.566f, 0.0f}; +Position const ClintarSpiritSummon = {7459.2275f, -3122.5632f, 438.9842f, 0.8594f}; + +enum ClintarSpirit +{ + ASPECT_RAVEN = 22915, + + // Texts for EnterCombat, the event and the end of the event are missing + CLINTAR_SPIRIT_SAY_START = 0, +}; + +class npc_clintar_spirit : public CreatureScript +{ +public: + npc_clintar_spirit() : CreatureScript("npc_clintar_spirit") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_clintar_spiritAI (creature); + } + + struct npc_clintar_spiritAI : public npc_escortAI + { + public: + npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature) + { + PlayerGUID = 0; + } + + uint8 Step; + uint32 CurrWP; + uint32 EventTimer; + uint32 checkPlayerTimer; + + uint64 PlayerGUID; + + bool EventOnWait; + + void Reset() + { + if (!PlayerGUID) + { + Step = 0; + CurrWP = 0; + EventTimer = 0; + PlayerGUID = 0; + checkPlayerTimer = 1000; + EventOnWait = false; + } + } + + void IsSummonedBy(Unit* /*summoner*/) + { + std::list playerOnQuestList; + Trinity::AnyPlayerInObjectRangeCheck checker(me, 5.0f); + Trinity::PlayerListSearcher searcher(me, playerOnQuestList, checker); + me->VisitNearbyWorldObject(5.0f, searcher); + for (std::list::const_iterator itr = playerOnQuestList.begin(); itr != playerOnQuestList.end(); ++itr) + { + // Check if found player target has active quest + if (Player* player = (*itr)) + { + if (player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) + { + StartEvent(player); + break; + } + } + else + break; + } + } + + void JustDied(Unit* /*killer*/) + { + if (!PlayerGUID) + return; + + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) + { + player->FailQuest(10965); + PlayerGUID = 0; + Reset(); + } + } + + void EnterEvadeMode() + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->isInCombat() && player->getAttackerForHelper()) + { + AttackStart(player->getAttackerForHelper()); + return; + } + npc_escortAI::EnterEvadeMode(); + } + + void StartEvent(Player* player) + { + if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE) + { + for (uint8 i = 0; i < 41; ++i) + { + AddWaypoint(i, Clintar_spirit_WP[i][0], Clintar_spirit_WP[i][1], Clintar_spirit_WP[i][2], (uint32)Clintar_spirit_WP[i][4]); + } + PlayerGUID = player->GetGUID(); + Start(true, false, PlayerGUID); + } + return; + } + + void UpdateAI(uint32 const diff) + { + npc_escortAI::UpdateAI(diff); + + if (!PlayerGUID) + { + me->setDeathState(JUST_DIED); + return; + } + + if (!me->isInCombat() && !EventOnWait) + { + if (checkPlayerTimer <= diff) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->isInCombat() && player->getAttackerForHelper()) + AttackStart(player->getAttackerForHelper()); + checkPlayerTimer = 1000; + } else checkPlayerTimer -= diff; + } + + if (EventOnWait && EventTimer <= diff) + { + + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (!player || (player && player->GetQuestStatus(10965) == QUEST_STATUS_NONE)) + { + me->setDeathState(JUST_DIED); + return; + } + + switch (CurrWP) + { + case 0: + switch (Step) + { + case 0: + Talk(CLINTAR_SPIRIT_SAY_START, PlayerGUID); + EventTimer = 8000; + Step = 1; + break; + case 1: + EventOnWait = false; + break; + } + break; + case 6: + switch (Step) + { + case 0: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); + EventTimer = 5000; + Step = 1; + break; + case 1: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + // Needs text + EventOnWait = false; + break; + } + break; + case 15: + switch (Step) + { + case 0: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); + EventTimer = 5000; + Step = 1; + break; + case 1: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + EventOnWait = false; + break; + } + break; + case 16: + switch (Step) + { + case 0: + // Needs text + EventTimer = 15000; + Step = 1; + break; + case 1: + EventOnWait = false; + break; + } + break; + case 20: + switch (Step) + { + case 0: + if (Creature* mob = me->SummonCreature(ASPECT_RAVEN, AspectRavenSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000)) + { + mob->AddThreat(me, 10000.0f); + mob->AI()->AttackStart(me); + } + EventTimer = 2000; + Step = 1; + break; + case 1: + EventOnWait = false; + break; + } + break; + case 24: + switch (Step) + { + case 0: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133); + EventTimer = 5000; + Step = 1; + break; + case 1: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + EventOnWait = false; + break; + } + break; + case 25: + switch (Step) + { + case 0: + // Needs text + EventTimer = 4000; + Step = 1; + break; + case 1: + EventOnWait = false; + break; + } + break; + case 40: + switch (Step) + { + case 0: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2); + // Needs text + player->CompleteQuest(10965); + EventTimer = 1500; + Step = 1; + break; + case 1: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + EventTimer = 3000; + Step = 2; + break; + case 2: + player->TalkedToCreature(me->GetEntry(), me->GetGUID()); + PlayerGUID = 0; + Reset(); + me->setDeathState(JUST_DIED); + break; + } + break; + default: + EventOnWait = false; + break; + } + + } else if (EventOnWait) EventTimer -= diff; + } + + void WaypointReached(uint32 waypointId) + { + CurrWP = waypointId; + EventTimer = 0; + Step = 0; + EventOnWait = true; + } + }; + +}; + +/*#### +# npc_omen +####*/ + +enum Omen +{ + NPC_OMEN = 15467, + + SPELL_OMEN_CLEAVE = 15284, + SPELL_OMEN_STARFALL = 26540, + SPELL_OMEN_SUMMON_SPOTLIGHT = 26392, + SPELL_ELUNE_CANDLE = 26374, + + GO_ELUNE_TRAP_1 = 180876, + GO_ELUNE_TRAP_2 = 180877, + + EVENT_CAST_CLEAVE = 1, + EVENT_CAST_STARFALL = 2, + EVENT_DESPAWN = 3, +}; + +class npc_omen : public CreatureScript +{ +public: + npc_omen() : CreatureScript("npc_omen") { } + + struct npc_omenAI : public ScriptedAI + { + npc_omenAI(Creature* creature) : ScriptedAI(creature) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->GetMotionMaster()->MovePoint(1, 7549.977f, -2855.137f, 456.9678f); + } + + EventMap events; + + void MovementInform(uint32 type, uint32 pointId) + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == 1) + { + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + if (Player* player = me->SelectNearestPlayer(40.0f)) + AttackStart(player); + } + } + + void EnterCombat(Unit* /*attacker*/) + { + events.Reset(); + events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(3000, 5000)); + events.ScheduleEvent(EVENT_CAST_STARFALL, urand(8000, 10000)); + } + + void JustDied(Unit* /*killer*/) + { + DoCast(SPELL_OMEN_SUMMON_SPOTLIGHT); + } + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + { + if (spell->Id == SPELL_ELUNE_CANDLE) + { + if (me->HasAura(SPELL_OMEN_STARFALL)) + me->RemoveAurasDueToSpell(SPELL_OMEN_STARFALL); + + events.RescheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000)); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_CAST_CLEAVE: + DoCastVictim(SPELL_OMEN_CLEAVE); + events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(8000, 10000)); + break; + case EVENT_CAST_STARFALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_OMEN_STARFALL); + events.ScheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000)); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_omenAI(creature); + } +}; + +class npc_giant_spotlight : public CreatureScript +{ +public: + npc_giant_spotlight() : CreatureScript("npc_giant_spotlight") { } + + struct npc_giant_spotlightAI : public ScriptedAI + { + npc_giant_spotlightAI(Creature* creature) : ScriptedAI(creature) {} + + EventMap events; + + void Reset() + { + events.Reset(); + events.ScheduleEvent(EVENT_DESPAWN, 5*MINUTE*IN_MILLISECONDS); + } + + void UpdateAI(const uint32 diff) + { + events.Update(diff); + + if (events.ExecuteEvent() == EVENT_DESPAWN) + { + if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_1, 5.0f)) + trap->RemoveFromWorld(); + + if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_2, 5.0f)) + trap->RemoveFromWorld(); + + if (Creature* omen = me->FindNearestCreature(NPC_OMEN, 5.0f, false)) + omen->DespawnOrUnsummon(); + + me->DespawnOrUnsummon(); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_giant_spotlightAI(creature); + } +}; + +void AddSC_moonglade() +{ + new npc_bunthen_plainswind(); + new npc_great_bear_spirit(); + new npc_silva_filnaveth(); + new npc_clintar_spirit(); + new npc_omen(); + new npc_giant_spotlight(); +} diff --git a/src/server/scripts/Kalimdor/zone_mulgore.cpp b/src/server/scripts/Kalimdor/zone_mulgore.cpp new file mode 100644 index 00000000000..aca55284b67 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_mulgore.cpp @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Mulgore +SD%Complete: 100 +SDComment: Support for quest: 11129, 772 +SDCategory: Mulgore +EndScriptData */ + +/* ContentData +npc_skorn_whitecloud +npc_kyle_frenzied +npc_plains_vision +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" +#include "SpellInfo.h" + +/*###### +# npc_skorn_whitecloud +######*/ + +#define GOSSIP_SW "Tell me a story, Skorn." + +class npc_skorn_whitecloud : public CreatureScript +{ +public: + npc_skorn_whitecloud() : CreatureScript("npc_skorn_whitecloud") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + player->SEND_GOSSIP_MENU(523, creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (!player->GetQuestRewardStatus(770)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(522, creature->GetGUID()); + + return true; + } + +}; + +/*##### +# npc_kyle_frenzied +######*/ + +enum KyleFrenzied +{ + EMOTE_SEE_LUNCH = 0, + EMOTE_EAT_LUNCH = 1, + EMOTE_DANCE = 2, + + SPELL_LUNCH = 42222, + NPC_KYLE_FRENZIED = 23616, + NPC_KYLE_FRIENDLY = 23622, + POINT_ID = 1 +}; + +class npc_kyle_frenzied : public CreatureScript +{ +public: + npc_kyle_frenzied() : CreatureScript("npc_kyle_frenzied") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kyle_frenziedAI (creature); + } + + struct npc_kyle_frenziedAI : public ScriptedAI + { + npc_kyle_frenziedAI(Creature* creature) : ScriptedAI(creature) {} + + bool EventActive; + bool IsMovingToLunch; + uint64 PlayerGUID; + uint32 EventTimer; + uint8 EventPhase; + + void Reset() + { + EventActive = false; + IsMovingToLunch = false; + PlayerGUID = 0; + EventTimer = 5000; + EventPhase = 0; + + if (me->GetEntry() == NPC_KYLE_FRIENDLY) + me->UpdateEntry(NPC_KYLE_FRENZIED); + } + + void SpellHit(Unit* Caster, SpellInfo const* Spell) + { + if (!me->getVictim() && !EventActive && Spell->Id == SPELL_LUNCH) + { + if (Caster->GetTypeId() == TYPEID_PLAYER) + PlayerGUID = Caster->GetGUID(); + + if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + { + me->GetMotionMaster()->MovementExpired(); + me->GetMotionMaster()->MoveIdle(); + me->StopMoving(); + } + + EventActive = true; + Talk(EMOTE_SEE_LUNCH); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_CREATURE_SPECIAL); + } + } + + void MovementInform(uint32 Type, uint32 PointId) + { + if (Type != POINT_MOTION_TYPE || !EventActive) + return; + + if (PointId == POINT_ID) + IsMovingToLunch = false; + } + + void UpdateAI(const uint32 diff) + { + if (EventActive) + { + if (IsMovingToLunch) + return; + + if (EventTimer <= diff) + { + EventTimer = 5000; + ++EventPhase; + + switch (EventPhase) + { + case 1: + if (Unit* unit = Unit::GetUnit(*me, PlayerGUID)) + { + if (GameObject* go = unit->GetGameObject(SPELL_LUNCH)) + { + IsMovingToLunch = true; + me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()); + } + } + break; + case 2: + Talk(EMOTE_EAT_LUNCH); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); + break; + case 3: + if (Player* unit = Unit::GetPlayer(*me, PlayerGUID)) + unit->TalkedToCreature(me->GetEntry(), me->GetGUID()); + + me->UpdateEntry(NPC_KYLE_FRIENDLY); + break; + case 4: + EventTimer = 30000; + Talk(EMOTE_DANCE); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCESPECIAL); + break; + case 5: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); + Reset(); + me->GetMotionMaster()->Clear(); + break; + } + } + else + EventTimer -= diff; + } + } + }; + +}; + +/*##### +# npc_plains_vision +######*/ + +Position const wpPlainVision[50] = +{ + {-2226.32f, -408.095f, -9.36235f, 0.0f}, + {-2203.04f, -437.212f, -5.72498f, 0.0f}, + {-2163.91f, -457.851f, -7.09049f, 0.0f}, + {-2123.87f, -448.137f, -9.29591f, 0.0f}, + {-2104.66f, -427.166f, -6.49513f, 0.0f}, + {-2101.48f, -422.826f, -5.3567f, 0.0f}, + {-2097.56f, -417.083f, -7.16716f, 0.0f}, + {-2084.87f, -398.626f, -9.88973f, 0.0f}, + {-2072.71f, -382.324f, -10.2488f, 0.0f}, + {-2054.05f, -356.728f, -6.22468f, 0.0f}, + {-2051.8f, -353.645f, -5.35791f, 0.0f}, + {-2049.08f, -349.912f, -6.15723f, 0.0f}, + {-2030.6f, -310.724f, -9.59302f, 0.0f}, + {-2002.15f, -249.308f, -10.8124f, 0.0f}, + {-1972.85f, -195.811f, -10.6316f, 0.0f}, + {-1940.93f, -147.652f, -11.7055f, 0.0f}, + {-1888.06f, -81.943f, -11.4404f, 0.0f}, + {-1837.05f, -34.0109f, -12.258f, 0.0f}, + {-1796.12f, -14.6462f, -10.3581f, 0.0f}, + {-1732.61f, -4.27746f, -10.0213f, 0.0f}, + {-1688.94f, -0.829945f, -11.7103f, 0.0f}, + {-1681.32f, 13.0313f, -9.48056f, 0.0f}, + {-1677.04f, 36.8349f, -7.10318f, 0.0f}, + {-1675.2f, 68.559f, -8.95384f, 0.0f}, + {-1676.57f, 89.023f, -9.65104f, 0.0f}, + {-1678.16f, 110.939f, -10.1782f, 0.0f}, + {-1677.86f, 128.681f, -5.73869f, 0.0f}, + {-1675.27f, 144.324f, -3.47916f, 0.0f}, + {-1671.7f, 163.169f, -1.23098f, 0.0f}, + {-1666.61f, 181.584f, 5.26145f, 0.0f}, + {-1661.51f, 196.154f, 8.95252f, 0.0f}, + {-1655.47f, 210.811f, 8.38727f, 0.0f}, + {-1647.07f, 226.947f, 5.27755f, 0.0f}, + {-1621.65f, 232.91f, 2.69579f, 0.0f}, + {-1600.23f, 237.641f, 2.98539f, 0.0f}, + {-1576.07f, 242.546f, 4.66541f, 0.0f}, + {-1554.57f, 248.494f, 6.60377f, 0.0f}, + {-1547.53f, 259.302f, 10.6741f, 0.0f}, + {-1541.7f, 269.847f, 16.4418f, 0.0f}, + {-1539.83f, 278.989f, 21.0597f, 0.0f}, + {-1540.16f, 290.219f, 27.8247f, 0.0f}, + {-1538.99f, 298.983f, 34.0032f, 0.0f}, + {-1540.38f, 307.337f, 41.3557f, 0.0f}, + {-1536.61f, 314.884f, 48.0179f, 0.0f}, + {-1532.42f, 323.277f, 55.6667f, 0.0f}, + {-1528.77f, 329.774f, 61.1525f, 0.0f}, + {-1525.65f, 333.18f, 63.2161f, 0.0f}, + {-1517.01f, 350.713f, 62.4286f, 0.0f}, + {-1511.39f, 362.537f, 62.4539f, 0.0f}, + {-1508.68f, 366.822f, 62.733f, 0.0f} +}; + +class npc_plains_vision : public CreatureScript +{ +public: + npc_plains_vision() : CreatureScript("npc_plains_vision") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_plains_visionAI (creature); + } + + struct npc_plains_visionAI : public ScriptedAI + { + npc_plains_visionAI(Creature* creature) : ScriptedAI(creature) {} + + bool newWaypoint; + uint8 WayPointId; + uint8 amountWP; + + void Reset() + { + WayPointId = 0; + newWaypoint = true; + amountWP = 49; + } + + void EnterCombat(Unit* /*who*/){} + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id < amountWP) + { + ++WayPointId; + newWaypoint = true; + } + else + { + me->setDeathState(JUST_DIED); + me->RemoveCorpse(); + } + } + + void UpdateAI(const uint32 /*diff*/) + { + if (newWaypoint) + { + me->GetMotionMaster()->MovePoint(WayPointId, wpPlainVision[WayPointId]); + newWaypoint = false; + } + } + }; + +}; + +/*##### +# +######*/ + +void AddSC_mulgore() +{ + new npc_skorn_whitecloud(); + new npc_kyle_frenzied(); + new npc_plains_vision(); +} diff --git a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp new file mode 100644 index 00000000000..42ef9843a4e --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Orgrimmar +SD%Complete: 100 +SDComment: Quest support: 2460, 6566 +SDCategory: Orgrimmar +EndScriptData */ + +/* ContentData +npc_shenthul +npc_thrall_warchief +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*###### +## npc_shenthul +######*/ + +enum Shenthul +{ + QUEST_SHATTERED_SALUTE = 2460 +}; + +class npc_shenthul : public CreatureScript +{ +public: + npc_shenthul() : CreatureScript("npc_shenthul") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_SHATTERED_SALUTE) + { + CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->CanTalk = true; + CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->PlayerGUID = player->GetGUID(); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_shenthulAI (creature); + } + + struct npc_shenthulAI : public ScriptedAI + { + npc_shenthulAI(Creature* creature) : ScriptedAI(creature) {} + + bool CanTalk; + bool CanEmote; + uint32 SaluteTimer; + uint32 ResetTimer; + uint64 PlayerGUID; + + void Reset() + { + CanTalk = false; + CanEmote = false; + SaluteTimer = 6000; + ResetTimer = 0; + PlayerGUID = 0; + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (CanEmote) + { + if (ResetTimer <= diff) + { + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + { + if (player->GetTypeId() == TYPEID_PLAYER && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE) + player->FailQuest(QUEST_SHATTERED_SALUTE); + } + Reset(); + } else ResetTimer -= diff; + } + + if (CanTalk && !CanEmote) + { + if (SaluteTimer <= diff) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + CanEmote = true; + ResetTimer = 60000; + } else SaluteTimer -= diff; + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + + void ReceiveEmote(Player* player, uint32 emote) + { + if (emote == TEXT_EMOTE_SALUTE && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE) + { + if (CanEmote) + { + player->AreaExploredOrEventHappens(QUEST_SHATTERED_SALUTE); + Reset(); + } + } + } + }; + +}; + +/*###### +## npc_thrall_warchief +######*/ + +enum ThrallWarchief +{ + QUEST_6566 = 6566, + + SPELL_CHAIN_LIGHTNING = 16033, + SPELL_SHOCK = 16034 +}; + +#define GOSSIP_HTW "Please share your wisdom with me, Warchief." +#define GOSSIP_STW1 "What discoveries?" +#define GOSSIP_STW2 "Usurper?" +#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?" +#define GOSSIP_STW4 "I... I did not think of it that way, Warchief." +#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance." +#define GOSSIP_STW6 "Of course, Warchief!" + +//TODO: verify abilities/timers +class npc_thrall_warchief : public CreatureScript +{ +public: + npc_thrall_warchief() : CreatureScript("npc_thrall_warchief") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(5733, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(5734, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(5735, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(5736, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(5737, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); + player->SEND_GOSSIP_MENU(5738, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(QUEST_6566); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_thrall_warchiefAI (creature); + } + + struct npc_thrall_warchiefAI : public ScriptedAI + { + npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 ChainLightningTimer; + uint32 ShockTimer; + + void Reset() + { + ChainLightningTimer = 2000; + ShockTimer = 8000; + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (ChainLightningTimer <= diff) + { + DoCast(me->getVictim(), SPELL_CHAIN_LIGHTNING); + ChainLightningTimer = 9000; + } else ChainLightningTimer -= diff; + + if (ShockTimer <= diff) + { + DoCast(me->getVictim(), SPELL_SHOCK); + ShockTimer = 15000; + } else ShockTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; + +}; + +void AddSC_orgrimmar() +{ + new npc_shenthul(); + new npc_thrall_warchief(); +} diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp new file mode 100644 index 00000000000..58665224bdd --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -0,0 +1,1515 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Silithus +SD%Complete: 100 +SDComment: Quest support: 7785, 8304, 8507. +SDCategory: Silithus +EndScriptData */ + +/* ContentData +npc_highlord_demitrian +npcs_rutgar_and_frankal +quest_a_pawn_on_the_eternal_pawn +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Group.h" +#include "Player.h" + +/*### +## npc_highlord_demitrian +###*/ + +#define GOSSIP_DEMITRIAN1 "What do you know of it?" +#define GOSSIP_DEMITRIAN2 "I am listening, Demitrian." +#define GOSSIP_DEMITRIAN3 "Continue, please." +#define GOSSIP_DEMITRIAN4 "A battle?" +#define GOSSIP_DEMITRIAN5 "" +#define GOSSIP_DEMITRIAN6 "Caught unaware? How?" +#define GOSSIP_DEMITRIAN7 "So what did Ragnaros do next?" + +class npc_highlord_demitrian : public CreatureScript +{ +public: + npc_highlord_demitrian() : CreatureScript("npc_highlord_demitrian") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(6842, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(6843, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(6844, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(6867, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(6868, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(6869, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->SEND_GOSSIP_MENU(6870, creature->GetGUID()); + + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 19016, 1); + if (msg == EQUIP_ERR_OK) + player->StoreNewItem(dest, 19016, true); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(7785) == QUEST_STATUS_NONE && + (player->HasItemCount(18563, 1, false) || player->HasItemCount(18564, 1, false))) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DEMITRIAN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(6812, creature->GetGUID()); + return true; + } + +}; + +/*### +## npcs_rutgar_and_frankal +###*/ + +//gossip item text best guess +#define GOSSIP_ITEM1 "I seek information about Natalia" + +#define GOSSIP_ITEM2 "That sounds dangerous!" +#define GOSSIP_ITEM3 "What did you do?" +#define GOSSIP_ITEM4 "Who?" +#define GOSSIP_ITEM5 "Women do that. What did she demand?" +#define GOSSIP_ITEM6 "What do you mean?" +#define GOSSIP_ITEM7 "What happened next?" + +#define GOSSIP_ITEM11 "Yes, please continue" +#define GOSSIP_ITEM12 "What language?" +#define GOSSIP_ITEM13 "The Priestess attacked you?!" +#define GOSSIP_ITEM14 "I should ask the monkey about this" +#define GOSSIP_ITEM15 "Then what..." + +enum RutgarAndFrankal //trigger creatures to kill +{ + TRIGGER_FRANKAL = 15221, + TRIGGER_RUTGAR = 15222 +}; + +class npcs_rutgar_and_frankal : public CreatureScript +{ +public: + npcs_rutgar_and_frankal() : CreatureScript("npcs_rutgar_and_frankal") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(7755, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(7756, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(7757, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(7758, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + player->SEND_GOSSIP_MENU(7759, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + player->SEND_GOSSIP_MENU(7760, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 6: + player->SEND_GOSSIP_MENU(7761, creature->GetGUID()); + //'kill' our trigger to update quest status + player->KilledMonsterCredit(TRIGGER_RUTGAR, 0); + break; + + case GOSSIP_ACTION_INFO_DEF + 9: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); + player->SEND_GOSSIP_MENU(7762, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 10: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM12, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); + player->SEND_GOSSIP_MENU(7763, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 11: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM13, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12); + player->SEND_GOSSIP_MENU(7764, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 12: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM14, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13); + player->SEND_GOSSIP_MENU(7765, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 13: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM15, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14); + player->SEND_GOSSIP_MENU(7766, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 14: + player->SEND_GOSSIP_MENU(7767, creature->GetGUID()); + //'kill' our trigger to update quest status + player->KilledMonsterCredit(TRIGGER_FRANKAL, 0); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(8304) == QUEST_STATUS_INCOMPLETE && + creature->GetEntry() == 15170 && + !player->GetReqKillOrCastCurrentCount(8304, TRIGGER_RUTGAR)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + if (player->GetQuestStatus(8304) == QUEST_STATUS_INCOMPLETE && + creature->GetEntry() == 15171 && + player->GetReqKillOrCastCurrentCount(8304, TRIGGER_RUTGAR)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+9); + + player->SEND_GOSSIP_MENU(7754, creature->GetGUID()); + + return true; + } + +}; + +/*#### +# quest_a_pawn_on_the_eternal_board (Defines) +####*/ +enum EternalBoard +{ + QUEST_A_PAWN_ON_THE_ETERNAL_BOARD = 8519, + + FACTION_HOSTILE = 14, + FACTION_FRIENDLY = 35, + + C_ANACHRONOS = 15381, + C_FANDRAL_STAGHELM = 15382, + C_ARYGOS = 15380, + C_MERITHRA = 15378, + C_CAELESTRASZ = 15379, + + ANACHRONOS_SAY_1 = 0, + ANACHRONOS_SAY_2 = 1, + ANACHRONOS_SAY_3 = 2, + ANACHRONOS_SAY_4 = 3, + ANACHRONOS_SAY_5 = 4, + ANACHRONOS_SAY_6 = 5, + ANACHRONOS_SAY_7 = 6, + ANACHRONOS_SAY_8 = 7, + ANACHRONOS_SAY_9 = 8, + ANACHRONOS_SAY_10 = 9, + ANACHRONOS_EMOTE_1 = 10, + ANACHRONOS_EMOTE_2 = 11, + ANACHRONOS_EMOTE_3 = 12, + + FANDRAL_SAY_1 = 0, + FANDRAL_SAY_2 = 1, + FANDRAL_SAY_3 = 2, + FANDRAL_SAY_4 = 3, + FANDRAL_SAY_5 = 4, + FANDRAL_SAY_6 = 5, + FANDRAL_EMOTE_1 = 6, + FANDRAL_EMOTE_2 = 7, + + CAELESTRASZ_SAY_1 = 0, + CAELESTRASZ_SAY_2 = 1, + CAELESTRASZ_YELL_1 = 2, + + ARYGOS_SAY_1 = 0, + ARYGOS_YELL_1 = 1, + ARYGOS_EMOTE_1 = 2, + + MERITHRA_SAY_1 = 0, + MERITHRA_SAY_2 = 1, + MERITHRA_YELL_1 = 2, + MERITHRA_EMOTE_1 = 3, + + GO_GATE_OF_AHN_QIRAJ = 176146, + GO_GLYPH_OF_AHN_QIRAJ = 176148, + GO_ROOTS_OF_AHN_QIRAJ = 176147 +}; +/*##### +# Quest: A Pawn on the Eternal Board +#####*/ + +/* ContentData +A Pawn on the Eternal Board - creatures, gameobjects and defines +mob_qiraj_war_spawn : Adds that are summoned in the Qiraj gates battle. +npc_anachronos_the_ancient : Creature that controls the event. +npc_anachronos_quest_trigger: controls the spawning of the BG War mobs. +go_crystalline_tear : GameObject that begins the event and hands out quest +TO DO: get correct spell IDs and timings for spells cast upon dragon transformations +TO DO: Dragons should use the HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF) after transformation, but for some unknown reason it doesnt work. +EndContentData */ + +#define EVENT_AREA_RADIUS 65 //65yds +#define EVENT_COOLDOWN 500000 //in ms. appear after event completed or failed (should be = Adds despawn time) + +struct QuestCinematic +{ + int32 TextId; + uint32 Creature, Timer; +}; + +// Creature 0 - Anachronos, 1 - Fandral, 2 - Arygos, 3 - Merithra, 4 - Caelestrasz +static QuestCinematic EventAnim[]= +{ + {ANACHRONOS_SAY_1, 0, 2000}, + {FANDRAL_SAY_1, 1, 4000}, + {MERITHRA_EMOTE_1, 3, 500}, + {MERITHRA_SAY_1, 3, 500}, + {ARYGOS_EMOTE_1, 2, 2000}, + {CAELESTRASZ_SAY_1, 4, 8000}, + {MERITHRA_SAY_2, 3, 6000}, + {0, 3, 2000}, + {MERITHRA_YELL_1, 3, 2500}, + {0, 3, 3000}, //Morph + {0, 3, 4000}, //EmoteLiftoff + {0, 3, 4000}, // spell + {0, 3, 1250}, //fly + {0, 3, 250}, //remove flags + {ARYGOS_SAY_1, 2, 3000}, + {0, 3, 2000}, + {ARYGOS_YELL_1, 2, 3000}, + {0, 3, 3000}, //Morph + {0, 3, 4000}, //EmoteLiftoff + {0, 3, 4000}, // spell + {0, 3, 1000}, //fly + {0, 3, 1000}, //remove flags + {CAELESTRASZ_SAY_2, 4, 5000}, + {0, 3, 3000}, + {CAELESTRASZ_YELL_1, 4, 3000}, + {0, 3, 3000}, //Morph + {0, 3, 4000}, //EmoteLiftoff + {0, 3, 2500}, // spell + {ANACHRONOS_SAY_2, 0, 2000}, + {0, 3, 250}, //fly + {0, 3, 25}, //remove flags + {FANDRAL_SAY_2, 1, 3000}, + {ANACHRONOS_SAY_3, 0, 10000}, //Both run through the armies + {0, 3, 2000}, // Sands will stop + {0, 3, 8000}, // Summon Gate + {ANACHRONOS_SAY_4, 0, 4000}, + {0, 0, 2000}, //spell 1-> Arcane cosmetic (Mobs freeze) + {0, 0, 5000}, //Spell 2-> Arcane long cosmetic (barrier appears) (Barrier -> Glyphs) + {0, 0, 7000}, //BarrieR + {0, 0, 4000}, //Glyphs + {ANACHRONOS_SAY_5, 0, 2000}, + {0, 0, 4000}, // Roots + {FANDRAL_SAY_3, 1, 3000}, //Root Text + {FANDRAL_EMOTE_1, 1, 3000}, //falls knee + {ANACHRONOS_SAY_6, 0, 3000}, + {ANACHRONOS_SAY_7, 0, 3000}, + {ANACHRONOS_SAY_8, 0, 8000}, + {ANACHRONOS_EMOTE_1, 0, 1000}, //Give Scepter + {FANDRAL_SAY_4, 1, 3000}, + {FANDRAL_SAY_5, 1, 3000}, //->Equip hammer~Scepter, throw it at door + {FANDRAL_EMOTE_2, 1, 3000}, //Throw hammer at door. + {ANACHRONOS_SAY_9, 0, 3000}, + {FANDRAL_SAY_6, 1, 3000}, //fandral goes away + {ANACHRONOS_EMOTE_2, 0, 3000}, + {ANACHRONOS_EMOTE_3, 0, 3000}, + {0, 0, 2000}, + {0, 0, 2000}, + {0, 0, 4000}, + {ANACHRONOS_SAY_10, 0, 3000}, + {0, 0, 2000}, + {0, 0, 3000}, + {0, 0, 15000}, + {0, 0, 5000}, + {0, 0, 3500}, + {0, 0, 5000}, + {0, 0, 3500}, + {0, 0, 5000}, + {0, 0, 0} +}; + +//Cordinates for Spawns +Position const SpawnLocation[] = +{ + {-8085.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8085.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8085.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1424.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1422.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + // 2 waves of warriors + {-8082.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1525.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1527.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8082.0f, 1523.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1521.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1519.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8088.0f, 1510.0f, 2.61f, 0.0f}, //Anubisath Conqueror + {-8084.0f, 1520.0f, 2.61f, 0.0f}, //Anubisath Conqueror + {-8088.0f, 1530.0f, 2.61f, 0.0f}, //Anubisath Conqueror + + {-8080.0f, 1513.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8082.0f, 1523.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8085.0f, 1518.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8082.0f, 1516.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8085.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8080.0f, 1528.0f, 2.61f, 0.0f}, //Qiraj Wasp + + {-8082.0f, 1513.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8079.0f, 1523.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8080.0f, 1531.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8079.0f, 1516.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8082.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8080.0f, 1518.0f, 2.61f, 0.0f}, //Qiraj Wasp + + {-8081.0f, 1514.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1526.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1512.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8082.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1528.0f, 2.61f, 0.0f}, //Qiraj Tank + + {-8082.0f, 1513.0f, 2.61f, 3.141592f}, //Anubisath Conqueror + {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Anubisath Conqueror + {-8082.0f, 1527.0f, 2.61f, 3.141592f}, //Anubisath Conqueror +}; + +struct WaveData +{ + uint8 SpawnCount, UsedSpawnPoint; + uint32 CreatureId, SpawnTimer, YellTimer, DespTimer; + int32 WaveTextId; +}; + +static WaveData WavesInfo[5] = +{ + {30, 0, 15423, 0, 0, 24000, 0}, // Kaldorei Soldier + { 3, 35, 15424, 0, 0, 24000, 0}, // Anubisath Conqueror + {12, 38, 15414, 0, 0, 24000, 0}, // Qiraji Wasps + { 6, 50, 15422, 0, 0, 24000, 0}, // Qiraji Tanks + {15, 15, 15423, 0, 0, 24000, 0} // Kaldorei Soldier + +}; + +struct SpawnSpells +{ + uint32 Timer1, Timer2, SpellId; +}; + +static SpawnSpells SpawnCast[4] = +{ + {100000, 2000, 33652}, // Stop Time + {38500, 300000, 28528}, // Poison Cloud + {58000, 300000, 35871}, // Frost Debuff (need correct spell) + {80950, 300000, 42075}, // Fire Explosion (need correct spell however this one looks cool) +}; +/*##### +# npc_anachronos_the_ancient +######*/ +class npc_anachronos_the_ancient : public CreatureScript +{ +public: + npc_anachronos_the_ancient() : CreatureScript("npc_anachronos_the_ancient") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_anachronos_the_ancientAI(creature); + } + + struct npc_anachronos_the_ancientAI : public ScriptedAI + { + npc_anachronos_the_ancientAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 AnimationTimer; + uint8 AnimationCount; + + uint64 AnachronosQuestTriggerGUID; + uint64 MerithraGUID; + uint64 ArygosGUID; + uint64 CaelestraszGUID; + uint64 FandralGUID; + uint64 PlayerGUID; + bool eventEnd; + + void Reset() + { + AnimationTimer = 1500; + AnimationCount = 0; + AnachronosQuestTriggerGUID = 0; + MerithraGUID = 0; + ArygosGUID = 0; + CaelestraszGUID = 0; + FandralGUID = 0; + PlayerGUID = 0; + eventEnd = false; + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void HandleAnimation() + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (!player) + return; + + Creature* Fandral = player->FindNearestCreature(C_FANDRAL_STAGHELM, 100.0f, me); + Creature* Arygos = player->FindNearestCreature(C_ARYGOS, 100.0f, me); + Creature* Caelestrasz = player->FindNearestCreature(C_CAELESTRASZ, 100.0f, me); + Creature* Merithra = player->FindNearestCreature(C_MERITHRA, 100.0f, me); + + if (!Fandral || !Arygos || !Caelestrasz || !Merithra) + return; + + AnimationTimer = EventAnim[AnimationCount].Timer; + if (eventEnd == false) + { + switch (AnimationCount) + { + case 0: + Talk(ANACHRONOS_SAY_1,Fandral->GetGUID()); + break; + case 1: + Fandral->SetTarget(me->GetGUID()); + Fandral->AI()->Talk(FANDRAL_SAY_1, me->GetGUID()); + break; + case 2: + Fandral->SetTarget(0); + Merithra->AI()->Talk(MERITHRA_EMOTE_1); + break; + case 3: + Merithra->AI()->Talk(MERITHRA_SAY_1); + break; + case 4: + Arygos->AI()->Talk(ARYGOS_EMOTE_1); + break; + case 5: + Caelestrasz->SetTarget(Fandral->GetGUID()); + Caelestrasz->AI()->Talk(CAELESTRASZ_SAY_1); + break; + case 6: + Merithra->AI()->Talk(MERITHRA_SAY_2); + break; + case 7: + Caelestrasz->SetTarget(0); + Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); + break; + case 8: + Merithra->AI()->Talk(MERITHRA_YELL_1); + break; + case 9: + Merithra->CastSpell(Merithra, 25105, true); + break; + case 10: + Merithra->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + Merithra->SetDisableGravity(true); + Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 3); + break; + case 11: + Merithra->CastSpell(Merithra, 24818, false); + break; + case 12: + Merithra->GetMotionMaster()->MoveCharge(-8100, 1530, 50, 42); + break; + case 13: + break; + case 14: + Arygos->AI()->Talk(ARYGOS_SAY_1); + Merithra->SetVisible(false); + break; + case 15: + Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); + Merithra->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); + break; + case 16: + Arygos->AI()->Talk(ARYGOS_YELL_1); + break; + case 17: + Arygos->CastSpell(Arygos, 25107, true); + break; + case 18: + Arygos->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + Arygos->SetDisableGravity(true); + Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 42); + break; + case 19: + Arygos->CastSpell(Arygos, 50505, false); + break; + case 20: + Arygos->GetMotionMaster()->MoveCharge(-8095, 1530, 50, 42); + break; + case 21: + break; + case 22: + Caelestrasz->AI()->Talk(CAELESTRASZ_SAY_2, Fandral->GetGUID()); + break; + case 23: + Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); + Arygos->SetVisible(false); + Arygos->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 10); + break; + case 24: + Caelestrasz->AI()->Talk(CAELESTRASZ_YELL_1); + break; + case 25: + Caelestrasz->CastSpell(Caelestrasz, 25106, true); + break; + case 26: + Caelestrasz->HandleEmoteCommand(254); + Caelestrasz->SetDisableGravity(true); + Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 7.61f, 4); + break; + case 27: + Caelestrasz->CastSpell(Caelestrasz, 54293, false); + break; + case 28: + Talk(ANACHRONOS_SAY_2, Fandral->GetGUID()); + break; + case 29: + Caelestrasz->GetMotionMaster()->MoveCharge(-8095, 1530, 50, 42); + Fandral->AI()->Talk(FANDRAL_SAY_2); + break; + case 30: + break; + case 31: + Talk(ANACHRONOS_SAY_3, Fandral->GetGUID()); + break; + case 32: + Caelestrasz->SetVisible(false); + Caelestrasz->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); + Fandral->GetMotionMaster()->MoveCharge(-8108, 1529, 2.77f, 8); + me->GetMotionMaster()->MoveCharge(-8113, 1525, 2.77f, 8); + break;//both run to the gate + case 33: + Talk(ANACHRONOS_SAY_4); + Caelestrasz->GetMotionMaster()->MoveCharge(-8050, 1473, 65, 15); + break; //Text: sands will stop + case 34: + DoCast(player, 23017, true);//Arcane Channeling + break; + case 35: + me->CastSpell(-8088, 1520.43f, 2.67f, 25158, true); + break; + case 36: + DoCast(player, 25159, true); + break; + case 37: + me->SummonGameObject(GO_GATE_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); + break; + case 38: + DoCast(player, 25166, true); + me->SummonGameObject(GO_GLYPH_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); + break; + case 39: + Talk(ANACHRONOS_SAY_5, Fandral->GetGUID()); + break; + case 40: + Fandral->CastSpell(me, 25167, true); + break; + case 41: + Fandral->SummonGameObject(GO_ROOTS_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); + Fandral->AI()->Talk(FANDRAL_SAY_3); + break; + case 42: + me->CastStop(); + Fandral->AI()->Talk(FANDRAL_EMOTE_1); + break; + case 43: + Fandral->CastStop(); + break; + case 44: + Talk(ANACHRONOS_SAY_6); + break; + case 45: + Talk(ANACHRONOS_SAY_7); + break; + case 46: + Talk(ANACHRONOS_SAY_8); + me->GetMotionMaster()->MoveCharge(-8110, 1527, 2.77f, 4); + break; + case 47: + Talk(ANACHRONOS_EMOTE_1); + break; + case 48: + Fandral->AI()->Talk(FANDRAL_SAY_4, me->GetGUID()); + break; + case 49: + Fandral->AI()->Talk(FANDRAL_SAY_5, me->GetGUID()); + break; + case 50: + Fandral->AI()->Talk(FANDRAL_EMOTE_2); + Fandral->CastSpell(-8127, 1525, 17.5f, 33806, true); + break; + case 51: + { + uint32 entries[4] = { 15423, 15424, 15414, 15422 }; + Unit* mob = NULL; + for (uint8 i = 0; i < 4; ++i) + { + mob = player->FindNearestCreature(entries[i], 50, me); + while (mob) + { + mob->RemoveFromWorld(); + mob = player->FindNearestCreature(15423, 50, me); + } + } + break; + } + case 52: + Fandral->GetMotionMaster()->MoveCharge(-8028.75f, 1538.795f, 2.61f, 4); + Fandral->AI()->Talk(ANACHRONOS_SAY_9, me->GetGUID()); + break; + case 53: + Fandral->AI()->Talk(FANDRAL_SAY_6); + break; + case 54: + Talk(ANACHRONOS_EMOTE_2); + break; + case 55: + Fandral->SetVisible(false); + break; + case 56: + Talk(ANACHRONOS_EMOTE_3); + me->GetMotionMaster()->MoveCharge(-8116, 1522, 3.65f, 4); + break; + case 57: + me->GetMotionMaster()->MoveCharge(-8116.7f, 1527, 3.7f, 4); + break; + case 58: + me->GetMotionMaster()->MoveCharge(-8112.67f, 1529.9f, 2.86f, 4); + break; + case 59: + me->GetMotionMaster()->MoveCharge(-8117.99f, 1532.24f, 3.94f, 4); + break; + case 60: + if (player) + Talk(ANACHRONOS_SAY_10, player->GetGUID()); + me->GetMotionMaster()->MoveCharge(-8113.46f, 1524.16f, 2.89f, 4); + break; + case 61: + me->GetMotionMaster()->MoveCharge(-8057.1f, 1470.32f, 2.61f, 6); + if (player->IsInRange(me, 0, 15)) + player->GroupEventHappens(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD, me); + break; + case 62: + me->SetDisplayId(15500); + break; + case 63: + me->HandleEmoteCommand(254); + me->SetDisableGravity(true); + break; + case 64: + me->GetMotionMaster()->MoveCharge(-8000, 1400, 150, 9); + break; + case 65: + me->SetVisible(false); + if (Creature* AnachronosQuestTrigger = (Unit::GetCreature(*me, AnachronosQuestTriggerGUID))) + { + Talk(ARYGOS_YELL_1); + AnachronosQuestTrigger->AI()->EnterEvadeMode(); + eventEnd=true; + } + break; + } + } + ++AnimationCount; + } + void UpdateAI(const uint32 diff) + { + if (AnimationTimer) + { + if (AnimationTimer <= diff) + HandleAnimation(); + else AnimationTimer -= diff; + } + if (AnimationCount < 65) + me->CombatStop(); + if (AnimationCount == 65 || eventEnd) + me->AI()->EnterEvadeMode(); + } + }; + +}; + +/*###### +# mob_qiraj_war_spawn +######*/ + +class mob_qiraj_war_spawn : public CreatureScript +{ +public: + mob_qiraj_war_spawn() : CreatureScript("mob_qiraj_war_spawn") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_qiraj_war_spawnAI(creature); + } + + struct mob_qiraj_war_spawnAI : public ScriptedAI + { + mob_qiraj_war_spawnAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 MobGUID; + uint64 PlayerGUID; + uint32 SpellTimer1, SpellTimer2, SpellTimer3, SpellTimer4; + bool Timers; + bool hasTarget; + + void Reset() + { + MobGUID = 0; + PlayerGUID = 0; + Timers = false; + hasTarget = false; + } + + void EnterCombat(Unit* /*who*/) {} + void JustDied(Unit* /*slayer*/); + + void UpdateAI(const uint32 diff) + { + if (!Timers) + { + if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) //all but Kaldorei Soldiers + { + SpellTimer1 = SpawnCast[1].Timer1; + SpellTimer2 = SpawnCast[2].Timer1; + SpellTimer3 = SpawnCast[3].Timer1; + } + if (me->GetEntry() == 15423 || me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + SpellTimer4 = SpawnCast[0].Timer1; + Timers = true; + } + if (me->GetEntry() == 15424 || me->GetEntry() == 15422|| me->GetEntry() == 15414) + { + if (SpellTimer1 <= diff) + { + DoCast(me, SpawnCast[1].SpellId); + DoCast(me, 24319); + SpellTimer1 = SpawnCast[1].Timer2; + } else SpellTimer1 -= diff; + if (SpellTimer2 <= diff) + { + DoCast(me, SpawnCast[2].SpellId); + SpellTimer2 = SpawnCast[2].Timer2; + } else SpellTimer2 -= diff; + if (SpellTimer3 <= diff) + { + DoCast(me, SpawnCast[3].SpellId); + SpellTimer3 = SpawnCast[3].Timer2; + } else SpellTimer3 -= diff; + } + if (me->GetEntry() == 15423 || me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + { + if (SpellTimer4 <= diff) + { + me->RemoveAllAttackers(); + me->AttackStop(); + DoCast(me, 15533); + SpellTimer4 = SpawnCast[0].Timer2; + } else SpellTimer4 -= diff; + } + if (!hasTarget) + { + Unit* target = NULL; + if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + target = me->FindNearestCreature(15423, 20, true); + if (me->GetEntry() == 15423) + { + uint8 tar = urand(0, 2); + + if (tar == 0) + target = me->FindNearestCreature(15422, 20, true); + else if (tar == 1) + target = me->FindNearestCreature(15424, 20, true); + else if (tar == 2) + target = me->FindNearestCreature(15414, 20, true); + } + hasTarget = true; + if (target) + me->AI()->AttackStart(target); + } + if (!(me->FindNearestCreature(15379, 60))) + DoCast(me, 33652); + + if (!UpdateVictim()) + { + hasTarget = false; + return; + } + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*##### +# npc_anachronos_quest_trigger +#####*/ + +class npc_anachronos_quest_trigger : public CreatureScript +{ +public: + npc_anachronos_quest_trigger() : CreatureScript("npc_anachronos_quest_trigger") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_anachronos_quest_triggerAI(creature); + } + + struct npc_anachronos_quest_triggerAI : public ScriptedAI + { + npc_anachronos_quest_triggerAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + + uint32 WaveTimer; + uint32 AnnounceTimer; + + int8 LiveCount; + uint8 WaveCount; + + bool EventStarted; + bool Announced; + bool Failed; + + void Reset() + { + PlayerGUID = 0; + + WaveTimer = 2000; + AnnounceTimer = 1000; + LiveCount = 0; + WaveCount = 0; + + EventStarted = false; + Announced = false; + Failed = false; + + me->SetVisible(false); + } + + void SummonNextWave() + { + uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; + uint8 count = locIndex + WavesInfo[WaveCount].SpawnCount; + + for (uint8 i = locIndex; i <= count; ++i) + { + uint32 desptimer = WavesInfo[WaveCount].DespTimer; + + if (Creature* spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, SpawnLocation[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, desptimer)) + { + if (spawn->GetEntry() == 15423) + spawn->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15427+rand()%4); + if (i >= 30) WaveCount = 1; + if (i >= 33) WaveCount = 2; + if (i >= 45) WaveCount = 3; + if (i >= 51) WaveCount = 4; + + if (WaveCount < 5) //1-4 Wave + { + if (mob_qiraj_war_spawn::mob_qiraj_war_spawnAI* spawnAI = CAST_AI(mob_qiraj_war_spawn::mob_qiraj_war_spawnAI, spawn->AI())) + { + spawnAI->MobGUID = me->GetGUID(); + spawnAI->PlayerGUID = PlayerGUID; + } + } + } + } + + WaveTimer = WavesInfo[WaveCount].SpawnTimer; + AnnounceTimer = WavesInfo[WaveCount].YellTimer; + } + + void CheckEventFail() + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + + if (!player) + return; + + if (Group* EventGroup = player->GetGroup()) + { + Player* groupMember; + + uint8 GroupMemberCount = 0; + uint8 DeadMemberCount = 0; + uint8 FailedMemberCount = 0; + + Group::MemberSlotList const members = EventGroup->GetMemberSlots(); + + for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) + { + groupMember = (Unit::GetPlayer(*me, itr->guid)); + if (!groupMember) + continue; + if (!groupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && groupMember->GetQuestStatus(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) == QUEST_STATUS_INCOMPLETE) + { + groupMember->FailQuest(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD); + ++FailedMemberCount; + } + ++GroupMemberCount; + + if (groupMember->isDead()) + ++DeadMemberCount; + } + + if (GroupMemberCount == FailedMemberCount || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS)) + Failed = true; //only so event can restart + } + } + + void LiveCounter() + { + --LiveCount; + if (!LiveCount) + Announced = false; + } + + void UpdateAI(const uint32 diff) + { + if (!PlayerGUID || !EventStarted) + return; + + if (WaveCount < 4) + { + if (!Announced && AnnounceTimer <= diff) + { + Talk(WavesInfo[WaveCount].WaveTextId); + Announced = true; + } else AnnounceTimer -= diff; + + if (WaveTimer <= diff) + SummonNextWave(); + else WaveTimer -= diff; + } + CheckEventFail(); + if (WaveCount == 4 || Failed) + EnterEvadeMode(); + }; + }; + +}; + +void mob_qiraj_war_spawn::mob_qiraj_war_spawnAI::JustDied(Unit* /*slayer*/) +{ + me->RemoveCorpse(); + + if (!MobGUID) + return; + + if (Creature* mob = Unit::GetCreature(*me, MobGUID)) + if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, mob->AI())) + triggerAI->LiveCounter(); + +}; + +/*##### +# go_crystalline_tear +######*/ + +class go_crystalline_tear : public GameObjectScript +{ +public: + go_crystalline_tear() : GameObjectScript("go_crystalline_tear") { } + + bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) + { + if (Creature* trigger = go->FindNearestCreature(15454, 100, player)) + { + Unit* Merithra = trigger->SummonCreature(15378, -8034.535f, 1535.14f, 2.61f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Caelestrasz = trigger->SummonCreature(15379, -8032.767f, 1533.148f, 2.61f, 1.5f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Arygos = trigger->SummonCreature(15380, -8034.52f, 1537.843f, 2.61f, 5.7f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + /* Unit* Fandral = */ trigger->SummonCreature(15382, -8028.462f, 1535.843f, 2.61f, 3.141592f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Creature* Anachronos = trigger->SummonCreature(15381, -8028.75f, 1538.795f, 2.61f, 4, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + + if (Merithra) + { + Merithra->SetUInt32Value(UNIT_NPC_FLAGS, 0); + Merithra->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Merithra->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15420); + Merithra->setFaction(35); + } + + if (Caelestrasz) + { + Caelestrasz->SetUInt32Value(UNIT_NPC_FLAGS, 0); + Caelestrasz->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Caelestrasz->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15419); + Caelestrasz->setFaction(35); + } + + if (Arygos) + { + Arygos->SetUInt32Value(UNIT_NPC_FLAGS, 0); + Arygos->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Arygos->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15418); + Arygos->setFaction(35); + } + + if (Anachronos) + { + if (npc_anachronos_the_ancient::npc_anachronos_the_ancientAI* anachronosAI = CAST_AI(npc_anachronos_the_ancient::npc_anachronos_the_ancientAI, Anachronos->AI())) + anachronosAI->PlayerGUID = player->GetGUID(); + + if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, trigger->AI())) + { + triggerAI->Failed = false; + triggerAI->PlayerGUID = player->GetGUID(); + triggerAI->EventStarted = true; + triggerAI->Announced = true; + } + } + } + } + return true; + } + +}; + +/*### +## go_wind_stone +###*/ + +enum WSSpells +{ + SPELL_PUNISHMENT = 24803, + SPELL_SPAWN_IN = 25035, + + AURA_TWILIGHT_SET = 24746, + AURA_MEDALLION = 24748, + AURA_RING = 24782, + + SPELL_TEMPLAR_RANDOM = 24745, + SPELL_TEMPLAR_FIRE = 24747, + SPELL_TEMPLAR_AIR = 24757, + SPELL_TEMPLAR_EARTH = 24759, + SPELL_TEMPLAR_WATER = 24761, + + SPELL_DUKE_RANDOM = 24762, + SPELL_DUKE_FIRE = 24766, + SPELL_DUKE_AIR = 24769, + SPELL_DUKE_EARTH = 24771, + SPELL_DUKE_WATER = 24773, + + SPELL_ROYAL_RANDOM = 24785, + SPELL_ROYAL_FIRE = 24787, + SPELL_ROYAL_AIR = 24791, + SPELL_ROYAL_EARTH = 24792, + SPELL_ROYAL_WATER = 24793 +}; + +enum WSGossip +{ + GOSSIPID_LESSER_WS = 6540, + GOSSIPID_WS = 6542, + GOSSIPID_GREATER_WS = 6543 +}; + +enum WSCreatures +{ + NPC_TEMPLAR_FIRE = 15209, + NPC_TEMPLAR_WATER = 15211, + NPC_TEMPLAR_AIR = 15212, + NPC_TEMPLAR_EARTH = 15307, + + NPC_DUKE_FIRE = 15206, + NPC_DUKE_WATER = 15207, + NPC_DUKE_EARTH = 15208, + NPC_DUKE_AIR = 15220, + + NPC_ROYAL_FIRE = 15203, + NPC_ROYAL_AIR = 15204, + NPC_ROYAL_EARTH = 15205, + NPC_ROYAL_WATER = 15305 +}; + +enum WSItems +{ + ITEM_TEMPLAR_FIRE = 20416, + ITEM_TEMPLAR_EARTH = 20419, + ITEM_TEMPLAR_WATER = 20420, + ITEM_TEMPLAR_AIR = 20418, + + ITEM_DUKE_FIRE = 20432, + ITEM_DUKE_EARTH = 20435, + ITEM_DUKE_WATER = 20436, + ITEM_DUKE_AIR = 20433, + + ITEM_ROYAL_FIRE = 20447, + ITEM_ROYAL_EARTH = 20449, + ITEM_ROYAL_WATER = 20450, + ITEM_ROYAL_AIR = 20448, +}; + +enum WS +{ + TEMPLAR = 0, + DUKE = 1, + ROYAL = 2, + + FIRE = 0x1, + WATER = 0x2, + EARTH = 0x4, + AIR = 0x8 +}; + +enum WSTexts +{ + SAY_TEMPLAR_AGGRO = 0, + SAY_DUKE_AGGRO = 0, + YELL_ROYAL_AGGRO = 0 +}; + +#define GOSSIP_TEMPLAR_RANDOM "I am no cultist, you monster! Come to me and face your destruction!" +#define GOSSIP_TEMPLAR_FIRE "Crimson Templar! I hold your signet! Heed my call!" +#define GOSSIP_TEMPLAR_EARTH "Earthen Templar! I hold your signet! Heed my call!" +#define GOSSIP_TEMPLAR_AIR "Hoary Templar! I hold your signet! Heed my call!" +#define GOSSIP_TEMPLAR_WATER "Azure Templar! I hold your signet! Heed my call!" + +#define GOSSIP_DUKE_RANDOM "You will listen to this, vile duke! I am not your Twilight's Hammer lapdog! I am here to challenge you! Come! Come, and meet your death..." +#define GOSSIP_DUKE_FIRE "Duke of Cynders! I hold your signet! Heed my call!" +#define GOSSIP_DUKE_EARTH "The Duke of Shards! I hold your signet! Heed my call!" +#define GOSSIP_DUKE_AIR "The Duke of Zephyrs! I hold your signet! Heed my call!" +#define GOSSIP_DUKE_WATER "The Duke of Fathoms! I hold your signet! Heed my call!" + +#define GOSSIP_ROYAL_RANDOM "The day of the judgement has come, fiend! I challenge you to battle!" +#define GOSSIP_ROYAL_FIRE "Prince Skaldrenox! I hold your signet! Heed my call!" +#define GOSSIP_ROYAL_EARTH "Baron Kazum! I hold your signet! Heed my call!" +#define GOSSIP_ROYAL_AIR "High Marshal Whirlaxis! I hold your signet! Heed my call!" +#define GOSSIP_ROYAL_WATER "Lord Skwol! I hold your signet! Heed my call!" + +class go_wind_stone : public GameObjectScript +{ + public: + go_wind_stone() : GameObjectScript("go_wind_stone") { } + + private: + uint8 GetPlayerRank(Player* player) // For random summoning + { + bool setAura = player->HasAura(AURA_TWILIGHT_SET); + bool medallionAura = player->HasAura(AURA_MEDALLION); + bool ringAura = player->HasAura(AURA_RING); + + if (setAura && medallionAura && ringAura) + return 3; + else if (setAura && medallionAura) + return 2; + else if (setAura) + return 1; + else + return 0; + } + + uint8 GetItems(Player* player, WS type) + { + uint8 result = 0x0; + + switch (type) + { + case TEMPLAR: + { + if (player->HasItemCount(ITEM_TEMPLAR_FIRE)) + result |= FIRE; + if (player->HasItemCount(ITEM_TEMPLAR_WATER)) + result |= WATER; + if (player->HasItemCount(ITEM_TEMPLAR_EARTH)) + result |= EARTH; + if (player->HasItemCount(ITEM_TEMPLAR_AIR)) + result |= AIR; + break; + } + case DUKE: + { + if (player->HasItemCount(ITEM_DUKE_FIRE)) + result |= FIRE; + if (player->HasItemCount(ITEM_DUKE_WATER)) + result |= WATER; + if (player->HasItemCount(ITEM_DUKE_EARTH)) + result |= EARTH; + if (player->HasItemCount(ITEM_DUKE_AIR)) + result |= AIR; + break; + } + case ROYAL: + { + if (player->HasItemCount(ITEM_ROYAL_FIRE)) + result |= FIRE; + if (player->HasItemCount(ITEM_ROYAL_WATER)) + result |= WATER; + if (player->HasItemCount(ITEM_ROYAL_EARTH)) + result |= EARTH; + if (player->HasItemCount(ITEM_ROYAL_AIR)) + result |= AIR; + break; + } + default: + break; + } + return result; + } + + void SummonNPC(GameObject* go, Player* player, uint32 npc, uint32 spell) + { + go->CastSpell(player, spell); + TempSummon* summons = go->SummonCreature(npc, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), player->GetOrientation() - M_PI, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10 * 60 * 1000); + summons->CastSpell(summons, SPELL_SPAWN_IN, false); + switch (summons->GetEntry()) + { + case NPC_TEMPLAR_FIRE: + case NPC_TEMPLAR_WATER: + case NPC_TEMPLAR_AIR: + case NPC_TEMPLAR_EARTH: + summons->AI()->Talk(SAY_TEMPLAR_AGGRO); + break; + + case NPC_DUKE_FIRE: + case NPC_DUKE_WATER: + case NPC_DUKE_EARTH: + case NPC_DUKE_AIR: + summons->AI()->Talk(SAY_DUKE_AGGRO); + break; + case NPC_ROYAL_FIRE: + case NPC_ROYAL_AIR: + case NPC_ROYAL_EARTH: + case NPC_ROYAL_WATER: + summons->AI()->Talk(YELL_ROYAL_AGGRO); + break; + } + summons->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + summons->SendMeleeAttackStart(player); + summons->CombatStart(player); + } + + public: + bool OnGossipHello(Player* player, GameObject* go) + { + uint8 rank = GetPlayerRank(player); + + uint32 gossipId = go->GetGOInfo()->GetGossipMenuId(); + switch (gossipId) + { + case GOSSIPID_LESSER_WS: + { + if (rank >= 1) // 1 or 2 or 3 + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_RANDOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + else + { + go->CastSpell(player, SPELL_PUNISHMENT); + break; + } + + uint8 item = GetItems(player, TEMPLAR); + if (item & FIRE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_FIRE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + if (item & WATER) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_WATER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + if (item & EARTH) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_EARTH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + if (item & AIR) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TEMPLAR_AIR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + break; + } + case GOSSIPID_WS: + { + if (rank >= 2) // 2 or 3 + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_RANDOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + else + { + go->CastSpell(player, SPELL_PUNISHMENT); + break; + } + + uint8 item = GetItems(player, DUKE); + if (item & FIRE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_FIRE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); + if (item & WATER) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_WATER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8); + if (item & EARTH) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_EARTH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); + if (item & AIR) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_DUKE_AIR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); + break; + } + case GOSSIPID_GREATER_WS: + { + if (rank == 3) // 3 + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_RANDOM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); + else + { + go->CastSpell(player, SPELL_PUNISHMENT); + break; + } + + uint8 item = GetItems(player, ROYAL); + if (item & FIRE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_FIRE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12); + if (item & WATER) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_WATER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13); + if (item & EARTH) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_EARTH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14); + if (item & AIR) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ROYAL_AIR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15); + break; + } + default: + break; + } + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(gossipId, go), go->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + player->PlayerTalkClass->SendCloseGossip(); + + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + SummonNPC(go, player, RAND(NPC_TEMPLAR_WATER, NPC_TEMPLAR_FIRE, NPC_TEMPLAR_EARTH, NPC_TEMPLAR_AIR), SPELL_TEMPLAR_RANDOM); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + SummonNPC(go, player, NPC_TEMPLAR_FIRE, SPELL_TEMPLAR_FIRE); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + SummonNPC(go, player, NPC_TEMPLAR_WATER, SPELL_TEMPLAR_WATER); + break; + case GOSSIP_ACTION_INFO_DEF + 4: + SummonNPC(go, player, NPC_TEMPLAR_EARTH, SPELL_TEMPLAR_EARTH); + break; + case GOSSIP_ACTION_INFO_DEF + 5: + SummonNPC(go, player, NPC_TEMPLAR_AIR, SPELL_TEMPLAR_AIR); + break; + + case GOSSIP_ACTION_INFO_DEF + 6: + SummonNPC(go, player, RAND(NPC_DUKE_FIRE, NPC_DUKE_WATER, NPC_DUKE_EARTH, NPC_DUKE_AIR), SPELL_DUKE_RANDOM); + break; + case GOSSIP_ACTION_INFO_DEF + 7: + SummonNPC(go, player, NPC_DUKE_FIRE, SPELL_DUKE_FIRE); + break; + case GOSSIP_ACTION_INFO_DEF + 8: + SummonNPC(go, player, NPC_DUKE_WATER, SPELL_DUKE_WATER); + break; + case GOSSIP_ACTION_INFO_DEF + 9: + SummonNPC(go, player, NPC_DUKE_EARTH, SPELL_DUKE_EARTH); + break; + case GOSSIP_ACTION_INFO_DEF + 10: + SummonNPC(go, player, NPC_DUKE_AIR, SPELL_DUKE_AIR); + break; + + case GOSSIP_ACTION_INFO_DEF + 11: + SummonNPC(go, player, RAND(NPC_ROYAL_FIRE, NPC_ROYAL_AIR, NPC_ROYAL_EARTH, NPC_ROYAL_WATER), SPELL_ROYAL_RANDOM); + break; + case GOSSIP_ACTION_INFO_DEF + 12: + SummonNPC(go, player, NPC_ROYAL_FIRE, SPELL_ROYAL_FIRE); + break; + case GOSSIP_ACTION_INFO_DEF + 13: + SummonNPC(go, player, NPC_ROYAL_WATER, SPELL_ROYAL_WATER); + break; + case GOSSIP_ACTION_INFO_DEF + 14: + SummonNPC(go, player, NPC_ROYAL_EARTH, SPELL_ROYAL_EARTH); + break; + case GOSSIP_ACTION_INFO_DEF + 15: + SummonNPC(go, player, NPC_ROYAL_AIR, SPELL_ROYAL_AIR); + break; + + default: + break; + } + return true; + } +}; + +void AddSC_silithus() +{ + new go_crystalline_tear(); + new npc_anachronos_quest_trigger(); + new npc_anachronos_the_ancient(); + new mob_qiraj_war_spawn(); + new npc_highlord_demitrian(); + new npcs_rutgar_and_frankal(); + new go_wind_stone(); +} diff --git a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp new file mode 100644 index 00000000000..26c92c7404c --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Stonetalon_Mountains +SD%Complete: 95 +SDComment: Quest support: 6627, 6523 +SDCategory: Stonetalon Mountains +EndScriptData */ + +/* ContentData +npc_braug_dimspirit +npc_kaya_flathoof +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_braug_dimspirit +######*/ + +#define GOSSIP_HBD1 "Ysera" +#define GOSSIP_HBD2 "Neltharion" +#define GOSSIP_HBD3 "Nozdormu" +#define GOSSIP_HBD4 "Alexstrasza" +#define GOSSIP_HBD5 "Malygos" + +class npc_braug_dimspirit : public CreatureScript +{ +public: + npc_braug_dimspirit() : CreatureScript("npc_braug_dimspirit") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, 6766, false); + + } + if (action == GOSSIP_ACTION_INFO_DEF+2) + { + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(6627); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(6627) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(5820, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(5819, creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_kaya_flathoof +######*/ + +enum Kaya +{ + FACTION_ESCORTEE_H = 775, + + NPC_GRIMTOTEM_RUFFIAN = 11910, + NPC_GRIMTOTEM_BRUTE = 11912, + NPC_GRIMTOTEM_SORCERER = 11913, + + SAY_START = 0, + SAY_AMBUSH = 1, + SAY_END = 2, + + QUEST_PROTECT_KAYA = 6523 +}; + +class npc_kaya_flathoof : public CreatureScript +{ +public: + npc_kaya_flathoof() : CreatureScript("npc_kaya_flathoof") { } + + struct npc_kaya_flathoofAI : public npc_escortAI + { + npc_kaya_flathoofAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 16: + Talk(SAY_AMBUSH); + me->SummonCreature(NPC_GRIMTOTEM_BRUTE, -48.53f, -503.34f, -46.31f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_GRIMTOTEM_RUFFIAN, -38.85f, -503.77f, -45.90f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + me->SummonCreature(NPC_GRIMTOTEM_SORCERER, -36.37f, -496.23f, -45.71f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 18: + me->SetInFront(player); + Talk(SAY_END); + player->GroupEventHappens(QUEST_PROTECT_KAYA, me); + break; + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void Reset(){} + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_PROTECT_KAYA) + { + if (npc_escortAI* pEscortAI = CAST_AI(npc_kaya_flathoof::npc_kaya_flathoofAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + + creature->AI()->Talk(SAY_START); + creature->setFaction(113); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kaya_flathoofAI(creature); + } + +}; + +/*###### +## AddSC +######*/ + +void AddSC_stonetalon_mountains() +{ + new npc_braug_dimspirit(); + new npc_kaya_flathoof(); +} diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp new file mode 100644 index 00000000000..0648e40416d --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp @@ -0,0 +1,685 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Tanaris +SD%Complete: 80 +SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor +SDCategory: Tanaris +EndScriptData */ + +/* ContentData +mob_aquementas +npc_custodian_of_time +npc_marin_noggenfogger +npc_steward_of_time +npc_stone_watcher_of_norgannon +npc_OOX17 +npc_tooga +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "ScriptedFollowerAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## mob_aquementas +######*/ + +enum Aquementas +{ + AGGRO_YELL_AQUE = 0, + + SPELL_AQUA_JET = 13586, + SPELL_FROST_SHOCK = 15089 +}; + +class mob_aquementas : public CreatureScript +{ +public: + mob_aquementas() : CreatureScript("mob_aquementas") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_aquementasAI (creature); + } + + struct mob_aquementasAI : public ScriptedAI + { + mob_aquementasAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 SendItemTimer; + uint32 SwitchFactionTimer; + bool isFriendly; + + uint32 FrostShockTimer; + uint32 AquaJetTimer; + + void Reset() + { + SendItemTimer = 0; + SwitchFactionTimer = 10000; + me->setFaction(35); + isFriendly = true; + + AquaJetTimer = 5000; + FrostShockTimer = 1000; + } + + void SendItem(Unit* receiver) + { + if (CAST_PLR(receiver)->HasItemCount(11169, 1, false) && + CAST_PLR(receiver)->HasItemCount(11172, 11, false) && + CAST_PLR(receiver)->HasItemCount(11173, 1, false) && + !CAST_PLR(receiver)->HasItemCount(11522, 1, true)) + { + ItemPosCountVec dest; + uint8 msg = CAST_PLR(receiver)->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 11522, 1, NULL); + if (msg == EQUIP_ERR_OK) + CAST_PLR(receiver)->StoreNewItem(dest, 11522, 1, true); + } + } + + void EnterCombat(Unit* who) + { + Talk(AGGRO_YELL_AQUE, who->GetGUID()); + } + + void UpdateAI(const uint32 diff) + { + if (isFriendly) + { + if (SwitchFactionTimer <= diff) + { + me->setFaction(91); + isFriendly = false; + } else SwitchFactionTimer -= diff; + } + + if (!UpdateVictim()) + return; + + if (!isFriendly) + { + if (SendItemTimer <= diff) + { + if (me->getVictim()->GetTypeId() == TYPEID_PLAYER) + SendItem(me->getVictim()); + SendItemTimer = 5000; + } else SendItemTimer -= diff; + } + + if (FrostShockTimer <= diff) + { + DoCast(me->getVictim(), SPELL_FROST_SHOCK); + FrostShockTimer = 15000; + } else FrostShockTimer -= diff; + + if (AquaJetTimer <= diff) + { + DoCast(me, SPELL_AQUA_JET); + AquaJetTimer = 15000; + } else AquaJetTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; + +}; + +/*###### +## npc_custodian_of_time +######*/ + +enum CustodianOfTime +{ + WHISPER_CUSTODIAN_1 = 0, + WHISPER_CUSTODIAN_2 = 1, + WHISPER_CUSTODIAN_3 = 2, + WHISPER_CUSTODIAN_4 = 3, + WHISPER_CUSTODIAN_5 = 4, + WHISPER_CUSTODIAN_6 = 5, + WHISPER_CUSTODIAN_7 = 6, + WHISPER_CUSTODIAN_8 = 7, + WHISPER_CUSTODIAN_9 = 8, + WHISPER_CUSTODIAN_10 = 9, + WHISPER_CUSTODIAN_11 = 10, + WHISPER_CUSTODIAN_12 = 11, + WHISPER_CUSTODIAN_13 = 12, + WHISPER_CUSTODIAN_14 = 13 +}; + +class npc_custodian_of_time : public CreatureScript +{ +public: + npc_custodian_of_time() : CreatureScript("npc_custodian_of_time") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_custodian_of_timeAI(creature); + } + + struct npc_custodian_of_timeAI : public npc_escortAI + { + npc_custodian_of_timeAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 0: + Talk(WHISPER_CUSTODIAN_1, player->GetGUID()); + break; + case 1: + Talk(WHISPER_CUSTODIAN_2, player->GetGUID()); + break; + case 2: + Talk(WHISPER_CUSTODIAN_3, player->GetGUID()); + break; + case 3: + Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); + break; + case 5: + Talk(WHISPER_CUSTODIAN_5, player->GetGUID()); + break; + case 6: + Talk(WHISPER_CUSTODIAN_6, player->GetGUID()); + break; + case 7: + Talk(WHISPER_CUSTODIAN_7, player->GetGUID()); + break; + case 8: + Talk(WHISPER_CUSTODIAN_8, player->GetGUID()); + break; + case 9: + Talk(WHISPER_CUSTODIAN_9, player->GetGUID()); + break; + case 10: + Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); + break; + case 13: + Talk(WHISPER_CUSTODIAN_10, player->GetGUID()); + break; + case 14: + Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); + break; + case 16: + Talk(WHISPER_CUSTODIAN_11, player->GetGUID()); + break; + case 17: + Talk(WHISPER_CUSTODIAN_12, player->GetGUID()); + break; + case 18: + Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); + break; + case 22: + Talk(WHISPER_CUSTODIAN_13, player->GetGUID()); + break; + case 23: + Talk(WHISPER_CUSTODIAN_4, player->GetGUID()); + break; + case 24: + Talk(WHISPER_CUSTODIAN_14, player->GetGUID()); + DoCast(player, 34883); + // below here is temporary workaround, to be removed when spell works properly + player->AreaExploredOrEventHappens(10277); + break; + } + } + } + + void MoveInLineOfSight(Unit* who) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + return; + + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (who->HasAura(34877) && CAST_PLR(who)->GetQuestStatus(10277) == QUEST_STATUS_INCOMPLETE) + { + float Radius = 10.0f; + if (me->IsWithinDistInMap(who, Radius)) + { + Start(false, false, who->GetGUID()); + } + } + } + } + + void EnterCombat(Unit* /*who*/) {} + void Reset() {} + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } + }; + +}; + +/*###### +## npc_marin_noggenfogger +######*/ + +class npc_marin_noggenfogger : public CreatureScript +{ +public: + npc_marin_noggenfogger() : CreatureScript("npc_marin_noggenfogger") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor() && player->GetQuestRewardStatus(2662)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_steward_of_time +######*/ + +#define GOSSIP_ITEM_FLIGHT "Please take me to the master's lair." + +class npc_steward_of_time : public CreatureScript +{ +public: + npc_steward_of_time() : CreatureScript("npc_steward_of_time") { } + + bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) + { + if (quest->GetQuestId() == 10279) //Quest: To The Master's Lair + player->CastSpell(player, 34891, true); //(Flight through Caverns) + + return false; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF + 1) + player->CastSpell(player, 34891, true); //(Flight through Caverns) + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(10279) == QUEST_STATUS_INCOMPLETE || player->GetQuestRewardStatus(10279)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_FLIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(9978, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(9977, creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_stone_watcher_of_norgannon +######*/ + +#define GOSSIP_ITEM_NORGANNON_1 "What function do you serve?" +#define GOSSIP_ITEM_NORGANNON_2 "What are the Plates of Uldum?" +#define GOSSIP_ITEM_NORGANNON_3 "Where are the Plates of Uldum?" +#define GOSSIP_ITEM_NORGANNON_4 "Excuse me? We've been \"reschedueled for visitations\"? What does that mean?!" +#define GOSSIP_ITEM_NORGANNON_5 "So, what's inside Uldum?" +#define GOSSIP_ITEM_NORGANNON_6 "I will return when i have the Plates of Uldum." + +class npc_stone_watcher_of_norgannon : public CreatureScript +{ +public: + npc_stone_watcher_of_norgannon() : CreatureScript("npc_stone_watcher_of_norgannon") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(1675, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(1676, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(1677, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(1678, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(1679, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(2954); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(2954) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(1674, creature->GetGUID()); + + return true; + } + +}; + +/*###### +## npc_OOX17 +######*/ + +enum Npc00X17 +{ + SAY_OOX_START = 0, + SAY_OOX_AGGRO = 1, + SAY_OOX_AMBUSH = 2, + SAY_OOX17_AMBUSH_REPLY = 0, + SAY_OOX_END = 3, + + Q_OOX17 = 648, + SPAWN_FIRST = 7803, + SPAWN_SECOND_1 = 5617, + SPAWN_SECOND_2 = 7805 +}; + +class npc_OOX17 : public CreatureScript +{ +public: + npc_OOX17() : CreatureScript("npc_OOX17") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == Q_OOX17) + { + creature->setFaction(113); + creature->SetFullHealth(); + creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + creature->AI()->Talk(SAY_OOX_START); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_OOX17::npc_OOX17AI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_OOX17AI(creature); + } + + struct npc_OOX17AI : public npc_escortAI + { + npc_OOX17AI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 23: + me->SummonCreature(SPAWN_FIRST, -8350.96f, -4445.79f, 10.10f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_FIRST, -8355.96f, -4447.79f, 10.10f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_FIRST, -8353.96f, -4442.79f, 10.10f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + Talk(SAY_OOX_AMBUSH); + break; + case 56: + me->SummonCreature(SPAWN_SECOND_1, -7510.07f, -4795.50f, 9.35f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_SECOND_2, -7515.07f, -4797.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_SECOND_2, -7518.07f, -4792.50f, 9.35f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + Talk(SAY_OOX_AMBUSH); + if (Creature* scoff = me->FindNearestCreature(SPAWN_SECOND_2, 30)) + scoff->AI()->Talk(SAY_OOX17_AMBUSH_REPLY); + break; + case 86: + Talk(SAY_OOX_END); + player->GroupEventHappens(Q_OOX17, me); + break; + } + } + } + + void Reset(){} + + void EnterCombat(Unit* /*who*/) + { + Talk(SAY_OOX_AGGRO); + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + }; +}; + +/*#### +# npc_tooga +####*/ + +enum Tooga +{ + SAY_TOOG_WORRIED = 0, + SAY_TOOG_POST_1 = 1, + SAY_TORT_POST_2 = 0, + SAY_TOOG_POST_3 = 2, + SAY_TORT_POST_4 = 1, + SAY_TOOG_POST_5 = 3, + SAY_TORT_POST_6 = 2, + + QUEST_TOOGA = 1560, + NPC_TORTA = 6015, + + POINT_ID_TO_WATER = 1, + FACTION_TOOG_ESCORTEE = 113 +}; + +Position const ToWaterLoc = {-7032.664551f, -4906.199219f, -1.606446f, 0.0f}; + +class npc_tooga : public CreatureScript +{ +public: + npc_tooga() : CreatureScript("npc_tooga") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_TOOGA) + { + if (npc_toogaAI* pToogaAI = CAST_AI(npc_tooga::npc_toogaAI, creature->AI())) + pToogaAI->StartFollow(player, FACTION_TOOG_ESCORTEE, quest); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_toogaAI(creature); + } + + struct npc_toogaAI : public FollowerAI + { + npc_toogaAI(Creature* creature) : FollowerAI(creature) { } + + uint32 CheckSpeechTimer; + uint32 PostEventTimer; + uint32 PhasePostEvent; + + uint64 TortaGUID; + + void Reset() + { + CheckSpeechTimer = 2500; + PostEventTimer = 1000; + PhasePostEvent = 0; + + TortaGUID = 0; + } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE | STATE_FOLLOW_POSTEVENT) && who->GetEntry() == NPC_TORTA) + { + if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) + { + Player* player = GetLeaderForFollower(); + if (player && player->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE) + player->GroupEventHappens(QUEST_TOOGA, me); + + TortaGUID = who->GetGUID(); + SetFollowComplete(true); + } + } + } + + void MovementInform(uint32 MotionType, uint32 PointId) + { + FollowerAI::MovementInform(MotionType, PointId); + + if (MotionType != POINT_MOTION_TYPE) + return; + + if (PointId == POINT_ID_TO_WATER) + SetFollowComplete(); + } + + void UpdateFollowerAI(const uint32 Diff) + { + if (!UpdateVictim()) + { + //we are doing the post-event, or... + if (HasFollowState(STATE_FOLLOW_POSTEVENT)) + { + if (PostEventTimer <= Diff) + { + PostEventTimer = 5000; + + Creature* torta = Creature::GetCreature(*me, TortaGUID); + if (!torta || !torta->isAlive()) + { + //something happened, so just complete + SetFollowComplete(); + return; + } + + switch (PhasePostEvent) + { + case 1: + Talk(SAY_TOOG_POST_1); + break; + case 2: + torta->AI()->Talk(SAY_TORT_POST_2); + break; + case 3: + Talk(SAY_TOOG_POST_3); + break; + case 4: + torta->AI()->Talk(SAY_TORT_POST_4); + break; + case 5: + Talk(SAY_TOOG_POST_5); + break; + case 6: + torta->AI()->Talk(SAY_TORT_POST_6); + me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, ToWaterLoc); + break; + } + + ++PhasePostEvent; + } + else + PostEventTimer -= Diff; + } + //...we are doing regular speech check + else if (HasFollowState(STATE_FOLLOW_INPROGRESS)) + { + if (CheckSpeechTimer <= Diff) + { + CheckSpeechTimer = 5000; + + if (urand(0, 9) > 8) + Talk(SAY_TOOG_WORRIED); + } + else + CheckSpeechTimer -= Diff; + } + + return; + } + + DoMeleeAttackIfReady(); + } + }; + +}; + +void AddSC_tanaris() +{ + new mob_aquementas(); + new npc_custodian_of_time(); + new npc_marin_noggenfogger(); + new npc_steward_of_time(); + new npc_stone_watcher_of_norgannon(); + new npc_OOX17(); + new npc_tooga(); +} diff --git a/src/server/scripts/Kalimdor/zone_teldrassil.cpp b/src/server/scripts/Kalimdor/zone_teldrassil.cpp new file mode 100644 index 00000000000..d7983c2cbe6 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_teldrassil.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Teldrassil +SD%Complete: 100 +SDComment: Quest support: 938 +SDCategory: Teldrassil +EndScriptData */ + +/* ContentData +npc_mist +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedFollowerAI.h" +#include "Player.h" + +/*#### +# npc_mist +####*/ + +enum Mist +{ + SAY_AT_HOME = 0, + EMOTE_AT_HOME = 1, + QUEST_MIST = 938, + NPC_ARYNIA = 3519, + FACTION_DARNASSUS = 79 +}; + +class npc_mist : public CreatureScript +{ +public: + npc_mist() : CreatureScript("npc_mist") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_MIST) + if (npc_mistAI* pMistAI = CAST_AI(npc_mist::npc_mistAI, creature->AI())) + pMistAI->StartFollow(player, FACTION_DARNASSUS, quest); + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_mistAI(creature); + } + + struct npc_mistAI : public FollowerAI + { + npc_mistAI(Creature* creature) : FollowerAI(creature) { } + + void Reset() { } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_ARYNIA) + { + if (me->IsWithinDistInMap(who, 10.0f)) + { + Talk(SAY_AT_HOME, who->GetGUID()); + DoComplete(); + } + } + } + + void DoComplete() + { + Talk(EMOTE_AT_HOME); + + Player* player = GetLeaderForFollower(); + if (player && player->GetQuestStatus(QUEST_MIST) == QUEST_STATUS_INCOMPLETE) + player->GroupEventHappens(QUEST_MIST, me); + + //The follow is over (and for later development, run off to the woods before really end) + SetFollowComplete(); + } + + //call not needed here, no known abilities + /*void UpdateFollowerAI(const uint32 Diff) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + }*/ + }; + +}; + +void AddSC_teldrassil() +{ + new npc_mist(); +} diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp new file mode 100644 index 00000000000..8f7ab09260b --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp @@ -0,0 +1,695 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: The_Barrens +SD%Complete: 90 +SDComment: Quest support: 863, 898, 1719, 2458, 4921, 6981, +SDCategory: Barrens +EndScriptData */ + +/* ContentData +npc_beaten_corpse +npc_gilthares +npc_sputtervalve +npc_taskmaster_fizzule +npc_twiggy_flathead +npc_wizzlecrank_shredder +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "SpellInfo.h" + +/*###### +## npc_beaten_corpse +######*/ + +#define GOSSIP_CORPSE "Examine corpse in detail..." + +enum BeatenCorpse +{ + QUEST_LOST_IN_BATTLE = 4921 +}; + +class npc_beaten_corpse : public CreatureScript +{ +public: + npc_beaten_corpse() : CreatureScript("npc_beaten_corpse") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF +1) + { + player->SEND_GOSSIP_MENU(3558, creature->GetGUID()); + player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_LOST_IN_BATTLE) == QUEST_STATUS_COMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CORPSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(3557, creature->GetGUID()); + return true; + } + +}; + +/*###### +# npc_gilthares +######*/ + +enum Gilthares +{ + SAY_GIL_START = 0, + SAY_GIL_AT_LAST = 1, + SAY_GIL_PROCEED = 2, + SAY_GIL_FREEBOOTERS = 3, + SAY_GIL_AGGRO = 4, + SAY_GIL_ALMOST = 5, + SAY_GIL_SWEET = 6, + SAY_GIL_FREED = 7, + + QUEST_FREE_FROM_HOLD = 898, + AREA_MERCHANT_COAST = 391, + FACTION_ESCORTEE = 232 //guessed, possible not needed for this quest +}; + +class npc_gilthares : public CreatureScript +{ +public: + npc_gilthares() : CreatureScript("npc_gilthares") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_FREE_FROM_HOLD) + { + creature->setFaction(FACTION_ESCORTEE); + creature->SetStandState(UNIT_STAND_STATE_STAND); + + creature->AI()->Talk(SAY_GIL_START, player->GetGUID()); + + if (npc_giltharesAI* pEscortAI = CAST_AI(npc_gilthares::npc_giltharesAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_giltharesAI(creature); + } + + struct npc_giltharesAI : public npc_escortAI + { + npc_giltharesAI(Creature* creature) : npc_escortAI(creature) { } + + void Reset() { } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 16: + Talk(SAY_GIL_AT_LAST, player->GetGUID()); + break; + case 17: + Talk(SAY_GIL_PROCEED, player->GetGUID()); + break; + case 18: + Talk(SAY_GIL_FREEBOOTERS, player->GetGUID()); + break; + case 37: + Talk(SAY_GIL_ALMOST,player->GetGUID()); + break; + case 47: + Talk(SAY_GIL_SWEET, player->GetGUID()); + break; + case 53: + Talk(SAY_GIL_FREED, player->GetGUID()); + player->GroupEventHappens(QUEST_FREE_FROM_HOLD, me); + break; + } + } + + void EnterCombat(Unit* who) + { + //not always use + if (rand()%4) + return; + + //only aggro text if not player and only in this area + if (who->GetTypeId() != TYPEID_PLAYER && me->GetAreaId() == AREA_MERCHANT_COAST) + { + //appears to be pretty much random (possible only if escorter not in combat with who yet?) + Talk(SAY_GIL_AGGRO, who->GetGUID()); + } + } + }; + +}; + +/*###### +## npc_sputtervalve +######*/ + +#define GOSSIP_SPUTTERVALVE "Can you tell me about this shard?" + +class npc_sputtervalve : public CreatureScript +{ +public: + npc_sputtervalve() : CreatureScript("npc_sputtervalve") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->SEND_GOSSIP_MENU(2013, creature->GetGUID()); + player->AreaExploredOrEventHappens(6981); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(6981) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SPUTTERVALVE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + +}; + +/*###### +## npc_taskmaster_fizzule +######*/ + +enum TaskmasterFizzule +{ + FACTION_FRIENDLY_F = 35, + SPELL_FLARE = 10113, + SPELL_FOLLY = 10137, +}; + +class npc_taskmaster_fizzule : public CreatureScript +{ +public: + npc_taskmaster_fizzule() : CreatureScript("npc_taskmaster_fizzule") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_taskmaster_fizzuleAI(creature); + } + + struct npc_taskmaster_fizzuleAI : public ScriptedAI + { + npc_taskmaster_fizzuleAI(Creature* creature) : ScriptedAI(creature) + { + factionNorm = creature->getFaction(); + } + + uint32 factionNorm; + bool IsFriend; + uint32 ResetTimer; + uint8 FlareCount; + + void Reset() + { + IsFriend = false; + ResetTimer = 120000; + FlareCount = 0; + me->setFaction(factionNorm); + } + + void DoFriend() + { + me->RemoveAllAuras(); + me->DeleteThreatList(); + me->CombatStop(true); + + me->StopMoving(); + me->GetMotionMaster()->MoveIdle(); + + me->setFaction(FACTION_FRIENDLY_F); + me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + } + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + { + if (spell->Id == SPELL_FLARE || spell->Id == SPELL_FOLLY) + { + ++FlareCount; + + if (FlareCount >= 2) + IsFriend = true; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (IsFriend) + { + if (ResetTimer <= diff) + { + EnterEvadeMode(); + return; + } else ResetTimer -= diff; + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + + void ReceiveEmote(Player* /*player*/, uint32 emote) + { + if (emote == TEXT_EMOTE_SALUTE) + { + if (FlareCount >= 2) + { + if (me->getFaction() == FACTION_FRIENDLY_F) + return; + + DoFriend(); + } + } + } + }; + +}; + +/*##### +## npc_twiggy_flathead +#####*/ + +enum TwiggyFlathead +{ + NPC_BIG_WILL = 6238, + NPC_AFFRAY_CHALLENGER = 6240, + + SAY_BIG_WILL_READY = 0, + SAY_TWIGGY_FLATHEAD_BEGIN = 0, + SAY_TWIGGY_FLATHEAD_FRAY = 1, + SAY_TWIGGY_FLATHEAD_DOWN = 2, + SAY_TWIGGY_FLATHEAD_OVER = 3 +}; + +Position const AffrayChallengerLoc[6] = +{ + {-1683.0f, -4326.0f, 2.79f, 0.0f}, + {-1682.0f, -4329.0f, 2.79f, 0.0f}, + {-1683.0f, -4330.0f, 2.79f, 0.0f}, + {-1680.0f, -4334.0f, 2.79f, 1.49f}, + {-1674.0f, -4326.0f, 2.79f, 3.49f}, + {-1677.0f, -4334.0f, 2.79f, 1.66f} +}; + +class npc_twiggy_flathead : public CreatureScript +{ +public: + npc_twiggy_flathead() : CreatureScript("npc_twiggy_flathead") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_twiggy_flatheadAI (creature); + } + + struct npc_twiggy_flatheadAI : public ScriptedAI + { + npc_twiggy_flatheadAI(Creature* creature) : ScriptedAI(creature) {} + + bool EventInProgress; + bool EventGrate; + bool EventBigWill; + bool ChallengerDown[6]; + uint8 Wave; + uint32 WaveTimer; + uint32 ChallengerChecker; + uint64 PlayerGUID; + uint64 AffrayChallenger[6]; + uint64 BigWill; + + void Reset() + { + EventInProgress = false; + EventGrate = false; + EventBigWill = false; + WaveTimer = 600000; + ChallengerChecker = 0; + Wave = 0; + PlayerGUID = 0; + + for (uint8 i = 0; i < 6; ++i) + { + AffrayChallenger[i] = 0; + ChallengerDown[i] = false; + } + BigWill = 0; + } + + void EnterCombat(Unit* /*who*/) { } + + void MoveInLineOfSight(Unit* who) + { + if (!who || (!who->isAlive())) + return; + + if (me->IsWithinDistInMap(who, 10.0f) && (who->GetTypeId() == TYPEID_PLAYER) && CAST_PLR(who)->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE && !EventInProgress) + { + PlayerGUID = who->GetGUID(); + EventInProgress = true; + } + } + + void KilledUnit(Unit* /*victim*/) { } + + void UpdateAI(const uint32 diff) + { + if (EventInProgress) { + Player* pWarrior = NULL; + + if (PlayerGUID) + pWarrior = Unit::GetPlayer(*me, PlayerGUID); + + if (!pWarrior) + return; + + if (!pWarrior->isAlive() && pWarrior->GetQuestStatus(1719) == QUEST_STATUS_INCOMPLETE) { + Talk(SAY_TWIGGY_FLATHEAD_DOWN); + pWarrior->FailQuest(1719); + + for (uint8 i = 0; i < 6; ++i) // unsummon challengers + { + if (AffrayChallenger[i]) + { + Creature* creature = Unit::GetCreature((*me), AffrayChallenger[i]); + if (creature && creature->isAlive()) + creature->DisappearAndDie(); + } + } + + if (BigWill) // unsummon bigWill + { + Creature* creature = Unit::GetCreature((*me), BigWill); + if (creature && creature->isAlive()) + creature->DisappearAndDie(); + } + Reset(); + } + + if (!EventGrate && EventInProgress) + { + float x, y, z; + pWarrior->GetPosition(x, y, z); + + if (x >= -1684 && x <= -1674 && y >= -4334 && y <= -4324) { + pWarrior->AreaExploredOrEventHappens(1719); + Talk(SAY_TWIGGY_FLATHEAD_BEGIN, pWarrior->GetGUID()); + + for (uint8 i = 0; i < 6; ++i) + { + Creature* creature = me->SummonCreature(NPC_AFFRAY_CHALLENGER, AffrayChallengerLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000); + if (!creature) + continue; + creature->setFaction(35); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + AffrayChallenger[i] = creature->GetGUID(); + } + WaveTimer = 5000; + ChallengerChecker = 1000; + EventGrate = true; + } + } + else if (EventInProgress) + { + if (ChallengerChecker <= diff) + { + for (uint8 i = 0; i < 6; ++i) + { + if (AffrayChallenger[i]) + { + Creature* creature = Unit::GetCreature((*me), AffrayChallenger[i]); + if ((!creature || (!creature->isAlive())) && !ChallengerDown[i]) + { + Talk(SAY_TWIGGY_FLATHEAD_DOWN); + ChallengerDown[i] = true; + } + } + } + ChallengerChecker = 1000; + } else ChallengerChecker -= diff; + + if (WaveTimer <= diff) + { + if (Wave < 6 && AffrayChallenger[Wave] && !EventBigWill) + { + Talk(SAY_TWIGGY_FLATHEAD_FRAY); + Creature* creature = Unit::GetCreature((*me), AffrayChallenger[Wave]); + if (creature && (creature->isAlive())) + { + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + creature->setFaction(14); + creature->AI()->AttackStart(pWarrior); + ++Wave; + WaveTimer = 20000; + } + } + else if (Wave >= 6 && !EventBigWill) { + if (Creature* creature = me->SummonCreature(NPC_BIG_WILL, -1722, -4341, 6.12f, 6.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 480000)) + { + BigWill = creature->GetGUID(); + //creature->GetMotionMaster()->MovePoint(0, -1693, -4343, 4.32f); + //creature->GetMotionMaster()->MovePoint(1, -1684, -4333, 2.78f); + creature->GetMotionMaster()->MovePoint(2, -1682, -4329, 2.79f); + creature->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED); + EventBigWill = true; + WaveTimer = 1000; + } + } + else if (Wave >= 6 && EventBigWill && BigWill) + { + Creature* creature = Unit::GetCreature((*me), BigWill); + if (!creature || !creature->isAlive()) + { + Talk(SAY_TWIGGY_FLATHEAD_OVER); + Reset(); + } + } + } else WaveTimer -= diff; + } + } + } + }; + +}; + +/*##### +## npc_wizzlecrank_shredder +#####*/ + +enum Wizzlecrank +{ + SAY_MERCENARY = 0, + SAY_START = 0, + SAY_STARTUP1 = 1, + SAY_STARTUP2 = 2, + SAY_PROGRESS_1 = 3, + SAY_PROGRESS_2 = 4, + SAY_PROGRESS_3 = 5, + SAY_END = 6, + + QUEST_ESCAPE = 863, + FACTION_RATCHET = 637, + NPC_PILOT_WIZZ = 3451, + NPC_MERCENARY = 3282, +}; + +class npc_wizzlecrank_shredder : public CreatureScript +{ +public: + npc_wizzlecrank_shredder() : CreatureScript("npc_wizzlecrank_shredder") { } + + struct npc_wizzlecrank_shredderAI : public npc_escortAI + { + npc_wizzlecrank_shredderAI(Creature* creature) : npc_escortAI(creature) + { + IsPostEvent = false; + PostEventTimer = 1000; + PostEventCount = 0; + } + + bool IsPostEvent; + uint32 PostEventTimer; + uint32 PostEventCount; + + void Reset() + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (me->getStandState() == UNIT_STAND_STATE_DEAD) + me->SetStandState(UNIT_STAND_STATE_STAND); + + IsPostEvent = false; + PostEventTimer = 1000; + PostEventCount = 0; + } + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 0: + Talk(SAY_STARTUP1); + break; + case 9: + SetRun(false); + break; + case 17: + if (Creature* temp = me->SummonCreature(NPC_MERCENARY, 1128.489f, -3037.611f, 92.701f, 1.472f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000)) + { + temp->AI()->Talk(SAY_MERCENARY); + me->SummonCreature(NPC_MERCENARY, 1160.172f, -2980.168f, 97.313f, 3.690f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + } + break; + case 24: + IsPostEvent = true; + break; + } + } + + void WaypointStart(uint32 PointId) + { + Player* player = GetPlayerForEscort(); + + if (!player) + return; + + switch (PointId) + { + case 9: + Talk(SAY_STARTUP2, player->GetGUID()); + break; + case 18: + Talk(SAY_PROGRESS_1, player->GetGUID()); + SetRun(); + break; + } + } + + void JustSummoned(Creature* summoned) + { + if (summoned->GetEntry() == NPC_PILOT_WIZZ) + me->SetStandState(UNIT_STAND_STATE_DEAD); + + if (summoned->GetEntry() == NPC_MERCENARY) + summoned->AI()->AttackStart(me); + } + + void UpdateEscortAI(const uint32 Diff) + { + if (!UpdateVictim()) + { + if (IsPostEvent) + { + if (PostEventTimer <= Diff) + { + switch (PostEventCount) + { + case 0: + Talk(SAY_PROGRESS_2); + break; + case 1: + Talk(SAY_PROGRESS_3); + break; + case 2: + Talk(SAY_END); + break; + case 3: + if (Player* player = GetPlayerForEscort()) + { + player->GroupEventHappens(QUEST_ESCAPE, me); + me->SummonCreature(NPC_PILOT_WIZZ, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 180000); + } + break; + } + + ++PostEventCount; + PostEventTimer = 5000; + } + else + PostEventTimer -= Diff; + } + + return; + } + + DoMeleeAttackIfReady(); + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPE) + { + creature->setFaction(FACTION_RATCHET); + if (npc_escortAI* pEscortAI = CAST_AI(npc_wizzlecrank_shredder::npc_wizzlecrank_shredderAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_wizzlecrank_shredderAI(creature); + } + +}; + +void AddSC_the_barrens() +{ + new npc_beaten_corpse(); + new npc_gilthares(); + new npc_sputtervalve(); + new npc_taskmaster_fizzule(); + new npc_twiggy_flathead(); + new npc_wizzlecrank_shredder(); +} diff --git a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp new file mode 100644 index 00000000000..9c47991a5d5 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp @@ -0,0 +1,463 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Thousand Needles +SD%Complete: 100 +SDComment: Support for Quest: 1950, 4770, 4904, 4966, 5151. +SDCategory: Thousand Needles +EndScriptData */ + +/* ContentData +npc_kanati +npc_lakota_windsong +npc_swiftmountain +npc_plucky +npc_enraged_panther +go_panther_cage +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*##### +# npc_kanati +######*/ + +enum Kanati +{ + SAY_KAN_START = 0, + + QUEST_PROTECT_KANATI = 4966, + NPC_GALAK_ASS = 10720 +}; + +Position const GalakLoc = {-4867.387695f, -1357.353760f, -48.226f, 0.0f}; + +class npc_kanati : public CreatureScript +{ +public: + npc_kanati() : CreatureScript("npc_kanati") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_PROTECT_KANATI) + if (npc_kanatiAI* pEscortAI = CAST_AI(npc_kanati::npc_kanatiAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest, true); + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kanatiAI(creature); + } + + struct npc_kanatiAI : public npc_escortAI + { + npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { } + + void Reset() {} + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 0: + Talk(SAY_KAN_START); + DoSpawnGalak(); + break; + case 1: + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_PROTECT_KANATI, me); + break; + } + } + + void DoSpawnGalak() + { + for (int i = 0; i < 3; ++i) + me->SummonCreature(NPC_GALAK_ASS, GalakLoc, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + }; + +}; + +/*###### +# npc_lakota_windsong +######*/ + +enum Lakota +{ + SAY_LAKO_START = 0, + SAY_LAKO_LOOK_OUT = 1, + SAY_LAKO_HERE_COME = 2, + SAY_LAKO_MORE = 3, + SAY_LAKO_END = 4, + + QUEST_FREE_AT_LAST = 4904, + NPC_GRIM_BANDIT = 10758, + FACTION_ESCORTEE_LAKO = 232, //guessed + + ID_AMBUSH_1 = 0, + ID_AMBUSH_2 = 2, + ID_AMBUSH_3 = 4 +}; + +Position const BanditLoc[6] = +{ + {-4905.479492f, -2062.732666f, 84.352f, 0.0f}, + {-4915.201172f, -2073.528320f, 84.733f, 0.0f}, + {-4878.883301f, -1986.947876f, 91.966f, 0.0f}, + {-4877.503906f, -1966.113403f, 91.859f, 0.0f}, + {-4767.985352f, -1873.169189f, 90.192f, 0.0f}, + {-4788.861328f, -1888.007813f, 89.888f, 0.0f} +}; + +class npc_lakota_windsong : public CreatureScript +{ +public: + npc_lakota_windsong() : CreatureScript("npc_lakota_windsong") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_FREE_AT_LAST) + { + creature->AI()->Talk(SAY_LAKO_START, player->GetGUID()); + creature->setFaction(FACTION_ESCORTEE_LAKO); + + if (npc_lakota_windsongAI* pEscortAI = CAST_AI(npc_lakota_windsong::npc_lakota_windsongAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lakota_windsongAI(creature); + } + + struct npc_lakota_windsongAI : public npc_escortAI + { + npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { } + + void Reset() {} + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 8: + Talk(SAY_LAKO_LOOK_OUT); + DoSpawnBandits(ID_AMBUSH_1); + break; + case 14: + Talk(SAY_LAKO_HERE_COME); + DoSpawnBandits(ID_AMBUSH_2); + break; + case 21: + Talk(SAY_LAKO_MORE); + DoSpawnBandits(ID_AMBUSH_3); + break; + case 45: + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_FREE_AT_LAST, me); + break; + } + } + + void DoSpawnBandits(int AmbushId) + { + for (int i = 0; i < 2; ++i) + me->SummonCreature(NPC_GRIM_BANDIT, BanditLoc[i+AmbushId], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + } + }; + +}; + +/*###### +# npc_paoka_swiftmountain +######*/ + +enum Packa +{ + SAY_START = 0, + SAY_WYVERN = 1, + SAY_COMPLETE = 2, + + QUEST_HOMEWARD = 4770, + NPC_WYVERN = 4107, + FACTION_ESCORTEE = 232 //guessed +}; + +Position const WyvernLoc[3] = +{ + {-4990.606f, -906.057f, -5.343f, 0.0f}, + {-4970.241f, -927.378f, -4.951f, 0.0f}, + {-4985.364f, -952.528f, -5.199f, 0.0f} +}; + +class npc_paoka_swiftmountain : public CreatureScript +{ +public: + npc_paoka_swiftmountain() : CreatureScript("npc_paoka_swiftmountain") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_HOMEWARD) + { + creature->AI()->Talk(SAY_START, player->GetGUID()); + creature->setFaction(FACTION_ESCORTEE); + + if (npc_paoka_swiftmountainAI* pEscortAI = CAST_AI(npc_paoka_swiftmountain::npc_paoka_swiftmountainAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_paoka_swiftmountainAI(creature); + } + + struct npc_paoka_swiftmountainAI : public npc_escortAI + { + npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { } + + void Reset() {} + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 15: + Talk(SAY_WYVERN); + DoSpawnWyvern(); + break; + case 26: + Talk(SAY_COMPLETE); + break; + case 27: + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_HOMEWARD, me); + break; + } + } + + void DoSpawnWyvern() + { + for (int i = 0; i < 3; ++i) + me->SummonCreature(NPC_WYVERN, WyvernLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + } + }; +}; + +/*##### +# npc_plucky +######*/ + +#define GOSSIP_P "Please tell me the Phrase.." + +enum Plucky +{ + FACTION_FRIENDLY = 35, + QUEST_SCOOP = 1950, + SPELL_PLUCKY_HUMAN = 9192, + SPELL_PLUCKY_CHICKEN = 9220 +}; + +class npc_plucky : public CreatureScript +{ +public: + npc_plucky() : CreatureScript("npc_plucky") { } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->CLOSE_GOSSIP_MENU(); + player->CompleteQuest(QUEST_SCOOP); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_P, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(738, creature->GetGUID()); + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_pluckyAI(creature); + } + + struct npc_pluckyAI : public ScriptedAI + { + npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { NormFaction = creature->getFaction(); } + + uint32 NormFaction; + uint32 ResetTimer; + + void Reset() + { + ResetTimer = 120000; + + if (me->getFaction() != NormFaction) + me->setFaction(NormFaction); + + if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + DoCast(me, SPELL_PLUCKY_CHICKEN, false); + } + + void ReceiveEmote(Player* player, uint32 TextEmote) + { + if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE) + { + if (TextEmote == TEXT_EMOTE_BECKON) + { + me->setFaction(FACTION_FRIENDLY); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + DoCast(me, SPELL_PLUCKY_HUMAN, false); + } + } + + if (TextEmote == TEXT_EMOTE_CHICKEN) + { + if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) + return; + else + { + me->setFaction(FACTION_FRIENDLY); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + DoCast(me, SPELL_PLUCKY_HUMAN, false); + me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); + } + } + } + + void UpdateAI(const uint32 Diff) + { + if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) + { + if (ResetTimer <= Diff) + { + if (!me->getVictim()) + EnterEvadeMode(); + else + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + + return; + } + else + ResetTimer -= Diff; + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + +}; + +enum PantherCage +{ + ENRAGED_PANTHER = 10992 +}; + +class go_panther_cage : public GameObjectScript +{ +public: + go_panther_cage() : GameObjectScript("go_panther_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + if (player->GetQuestStatus(5151) == QUEST_STATUS_INCOMPLETE) + { + if (Creature* panther = go->FindNearestCreature(ENRAGED_PANTHER, 5, true)) + { + panther->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + panther->SetReactState(REACT_AGGRESSIVE); + panther->AI()->AttackStart(player); + } + } + + return true; + } +}; + +class npc_enraged_panther : public CreatureScript +{ +public: + npc_enraged_panther() : CreatureScript("npc_enraged_panther") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_enraged_pantherAI(creature); + } + + struct npc_enraged_pantherAI : public ScriptedAI + { + npc_enraged_pantherAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetReactState(REACT_PASSIVE); + } + + void UpdateAI(const uint32 /*diff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + +}; + +void AddSC_thousand_needles() +{ + new npc_kanati(); + new npc_lakota_windsong(); + new npc_paoka_swiftmountain(); + new npc_plucky(); + new npc_enraged_panther(); + new go_panther_cage(); +} diff --git a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp new file mode 100644 index 00000000000..0d915dc7c44 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Thunder_Bluff +SD%Complete: 100 +SDComment: Quest support: 925 +SDCategory: Thunder Bluff +EndScriptData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" + +/*##### +# npc_cairne_bloodhoof +######*/ + +enum CairneBloodhoof +{ + SPELL_BERSERKER_CHARGE = 16636, + SPELL_CLEAVE = 16044, + SPELL_MORTAL_STRIKE = 16856, + SPELL_THUNDERCLAP = 23931, + SPELL_UPPERCUT = 22916 +}; + +#define GOSSIP_HCB "I know this is rather silly but a young ward who is a bit shy would like your hoofprint." +//TODO: verify abilities/timers +class npc_cairne_bloodhoof : public CreatureScript +{ +public: + npc_cairne_bloodhoof() : CreatureScript("npc_cairne_bloodhoof") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_SENDER_INFO) + { + player->CastSpell(player, 23123, false); + player->SEND_GOSSIP_MENU(7014, creature->GetGUID()); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(925) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HCB, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO); + + player->SEND_GOSSIP_MENU(7013, creature->GetGUID()); + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_cairne_bloodhoofAI (creature); + } + + struct npc_cairne_bloodhoofAI : public ScriptedAI + { + npc_cairne_bloodhoofAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 BerserkerChargeTimer; + uint32 CleaveTimer; + uint32 MortalStrikeTimer; + uint32 ThunderclapTimer; + uint32 UppercutTimer; + + void Reset() + { + BerserkerChargeTimer = 30000; + CleaveTimer = 5000; + MortalStrikeTimer = 10000; + ThunderclapTimer = 15000; + UppercutTimer = 10000; + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (BerserkerChargeTimer <= diff) + { + Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0); + if (target) + DoCast(target, SPELL_BERSERKER_CHARGE); + BerserkerChargeTimer = 25000; + } else BerserkerChargeTimer -= diff; + + if (UppercutTimer <= diff) + { + DoCast(me->getVictim(), SPELL_UPPERCUT); + UppercutTimer = 20000; + } else UppercutTimer -= diff; + + if (ThunderclapTimer <= diff) + { + DoCast(me->getVictim(), SPELL_THUNDERCLAP); + ThunderclapTimer = 15000; + } else ThunderclapTimer -= diff; + + if (MortalStrikeTimer <= diff) + { + DoCast(me->getVictim(), SPELL_MORTAL_STRIKE); + MortalStrikeTimer = 15000; + } else MortalStrikeTimer -= diff; + + if (CleaveTimer <= diff) + { + DoCast(me->getVictim(), SPELL_CLEAVE); + CleaveTimer = 7000; + } else CleaveTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; + +}; + +void AddSC_thunder_bluff() +{ + new npc_cairne_bloodhoof(); +} diff --git a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp new file mode 100644 index 00000000000..e72c82bee97 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Ungoro Crater +SD%Complete: 100 +SDComment: Support for Quest: 4245, 4491 +SDCategory: Ungoro Crater +EndScriptData */ + +/* ContentData +npc_a-me +npc_ringo +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "ScriptedFollowerAI.h" +#include "Player.h" +#include "SpellInfo.h" + +enum AmeData +{ + SAY_READY = 0, + SAY_AGGRO1 = 1, + SAY_SEARCH = 2, + SAY_AGGRO2 = 3, + SAY_AGGRO3 = 4, + SAY_FINISH = 5, + + SPELL_DEMORALIZINGSHOUT = 13730, + + QUEST_CHASING_AME = 4245, + ENTRY_TARLORD = 6519, + ENTRY_TARLORD1 = 6519, + ENTRY_STOMPER = 6513, +}; + +class npc_ame : public CreatureScript +{ +public: + npc_ame() : CreatureScript("npc_ame") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_CHASING_AME) + { + CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID()); + creature->AI()->Talk(SAY_READY, player->GetGUID()); + creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + // Change faction so mobs attack + creature->setFaction(113); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ameAI(creature); + } + + struct npc_ameAI : public npc_escortAI + { + npc_ameAI(Creature* creature) : npc_escortAI(creature) {} + + uint32 DemoralizingShoutTimer; + + void WaypointReached(uint32 waypointId) + { + if (Player* player = GetPlayerForEscort()) + { + switch (waypointId) + { + case 19: + me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + Talk(SAY_AGGRO1, player->GetGUID()); + break; + case 28: + Talk(SAY_SEARCH, player->GetGUID()); + break; + case 38: + me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + Talk(SAY_AGGRO2, player->GetGUID()); + break; + case 49: + me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + Talk(SAY_AGGRO3, player->GetGUID()); + break; + case 55: + Talk(SAY_FINISH, player->GetGUID()); + player->GroupEventHappens(QUEST_CHASING_AME, me); + break; + } + } + } + + void Reset() + { + DemoralizingShoutTimer = 5000; + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_CHASING_AME); + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + if (!UpdateVictim()) + return; + + if (DemoralizingShoutTimer <= diff) + { + DoCast(me->getVictim(), SPELL_DEMORALIZINGSHOUT); + DemoralizingShoutTimer = 70000; + } else DemoralizingShoutTimer -= diff; + } + }; +}; + +/*#### +# npc_ringo +####*/ + +enum Ringo +{ + SAY_RIN_START = 0, + + SAY_FAINT = 1, + + SAY_WAKE = 2, + + SAY_RIN_END_1 = 3, + SAY_SPR_END_2 = 0, + SAY_RIN_END_3 = 4, + EMOTE_RIN_END_4 = 5, + EMOTE_RIN_END_5 = 6, + SAY_RIN_END_6 = 7, + SAY_SPR_END_7 = 1, + EMOTE_RIN_END_8 = 8, + + SPELL_REVIVE_RINGO = 15591, + QUEST_A_LITTLE_HELP = 4491, + NPC_SPRAGGLE = 9997, + FACTION_ESCORTEE = 113 +}; + +class npc_ringo : public CreatureScript +{ +public: + npc_ringo() : CreatureScript("npc_ringo") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_A_LITTLE_HELP) + { + if (npc_ringoAI* ringoAI = CAST_AI(npc_ringo::npc_ringoAI, creature->AI())) + { + creature->SetStandState(UNIT_STAND_STATE_STAND); + ringoAI->StartFollow(player, FACTION_ESCORTEE, quest); + } + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ringoAI(creature); + } + + struct npc_ringoAI : public FollowerAI + { + npc_ringoAI(Creature* creature) : FollowerAI(creature) { } + + uint32 FaintTimer; + uint32 EndEventProgress; + uint32 EndEventTimer; + + uint64 SpraggleGUID; + + void Reset() + { + FaintTimer = urand(30000, 60000); + EndEventProgress = 0; + EndEventTimer = 1000; + SpraggleGUID = 0; + } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (!me->getVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_SPRAGGLE) + { + if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) + { + if (Player* player = GetLeaderForFollower()) + { + if (player->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE) + player->GroupEventHappens(QUEST_A_LITTLE_HELP, me); + } + + SpraggleGUID = who->GetGUID(); + SetFollowComplete(true); + } + } + } + + void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) + { + if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_REVIVE_RINGO) + ClearFaint(); + } + + void SetFaint() + { + if (!HasFollowState(STATE_FOLLOW_POSTEVENT)) + { + SetFollowPaused(true); + + Talk(SAY_FAINT); + } + + //what does actually happen here? Emote? Aura? + me->SetStandState(UNIT_STAND_STATE_SLEEP); + } + + void ClearFaint() + { + me->SetStandState(UNIT_STAND_STATE_STAND); + + if (HasFollowState(STATE_FOLLOW_POSTEVENT)) + return; + + Talk(SAY_WAKE); + + SetFollowPaused(false); + } + + void UpdateFollowerAI(const uint32 Diff) + { + if (!UpdateVictim()) + { + if (HasFollowState(STATE_FOLLOW_POSTEVENT)) + { + if (EndEventTimer <= Diff) + { + Creature* spraggle = Creature::GetCreature(*me, SpraggleGUID); + if (!spraggle || !spraggle->isAlive()) + { + SetFollowComplete(); + return; + } + + switch (EndEventProgress) + { + case 1: + Talk(SAY_RIN_END_1); + EndEventTimer = 3000; + break; + case 2: + spraggle->AI()->Talk(SAY_SPR_END_2); + EndEventTimer = 5000; + break; + case 3: + Talk(SAY_RIN_END_3); + EndEventTimer = 1000; + break; + case 4: + Talk(EMOTE_RIN_END_4); + SetFaint(); + EndEventTimer = 9000; + break; + case 5: + Talk(EMOTE_RIN_END_5); + ClearFaint(); + EndEventTimer = 1000; + break; + case 6: + Talk(SAY_RIN_END_6); + EndEventTimer = 3000; + break; + case 7: + spraggle->AI()->Talk(SAY_SPR_END_7); + EndEventTimer = 10000; + break; + case 8: + Talk(EMOTE_RIN_END_8); + EndEventTimer = 5000; + break; + case 9: + SetFollowComplete(); + break; + } + + ++EndEventProgress; + } + else + EndEventTimer -= Diff; + } + else if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !HasFollowState(STATE_FOLLOW_PAUSED)) + { + if (FaintTimer <= Diff) + { + SetFaint(); + FaintTimer = urand(60000, 120000); + } + else + FaintTimer -= Diff; + } + + return; + } + + DoMeleeAttackIfReady(); + } + }; +}; + +void AddSC_ungoro_crater() +{ + new npc_ame(); + new npc_ringo(); +} diff --git a/src/server/scripts/Kalimdor/zone_winterspring.cpp b/src/server/scripts/Kalimdor/zone_winterspring.cpp new file mode 100644 index 00000000000..06f01033a25 --- /dev/null +++ b/src/server/scripts/Kalimdor/zone_winterspring.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Winterspring +SD%Complete: Almost Completely Emptied +SDComment: Vendor Rivern Frostwind. +SDCategory: Winterspring +EndScriptData */ + +/* ContentData +npc_rivern_frostwind +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npc_rivern_frostwind +######*/ + +class npc_rivern_frostwind : public CreatureScript +{ +public: + npc_rivern_frostwind() : CreatureScript("npc_rivern_frostwind") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor() && player->GetReputationRank(589) == REP_EXALTED) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + +}; + +void AddSC_winterspring() +{ + new npc_rivern_frostwind(); +} diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 233d49192e6..18549a1bf70 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -10,9 +10,9 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} - Northrend/wintergrasp.cpp + Northrend/zone_wintergrasp.cpp Northrend/isle_of_conquest.cpp - Northrend/storm_peaks.cpp + Northrend/zone_storm_peaks.cpp Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h @@ -117,14 +117,14 @@ set(scripts_STAT_SRCS Northrend/Naxxramas/instance_naxxramas.cpp Northrend/Naxxramas/boss_grobbulus.cpp Northrend/Naxxramas/boss_noth.cpp - Northrend/crystalsong_forest.cpp + Northrend/zone_crystalsong_forest.cpp Northrend/VaultOfArchavon/boss_archavon.cpp Northrend/VaultOfArchavon/boss_koralon.cpp Northrend/VaultOfArchavon/vault_of_archavon.h Northrend/VaultOfArchavon/instance_vault_of_archavon.cpp Northrend/VaultOfArchavon/boss_emalon.cpp Northrend/VaultOfArchavon/boss_toravon.cpp - Northrend/sholazar_basin.cpp + Northrend/zone_sholazar_basin.cpp Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp @@ -137,8 +137,8 @@ set(scripts_STAT_SRCS Northrend/UtgardeKeep/UtgardeKeep/instance_utgarde_keep.cpp Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp - Northrend/dragonblight.cpp - Northrend/grizzly_hills.cpp + Northrend/zone_dragonblight.cpp + Northrend/zone_grizzly_hills.cpp Northrend/AzjolNerub/AzjolNerub/azjol_nerub.h Northrend/AzjolNerub/AzjolNerub/instance_azjol_nerub.cpp Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp @@ -176,8 +176,8 @@ set(scripts_STAT_SRCS Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp Northrend/IcecrownCitadel/boss_sindragosa.cpp Northrend/IcecrownCitadel/boss_the_lich_king.cpp - Northrend/zuldrak.cpp - Northrend/icecrown.cpp + Northrend/zone_zuldrak.cpp + Northrend/zone_icecrown.cpp Northrend/Gundrak/boss_slad_ran.cpp Northrend/Gundrak/instance_gundrak.cpp Northrend/Gundrak/boss_drakkari_colossus.cpp @@ -185,9 +185,9 @@ set(scripts_STAT_SRCS Northrend/Gundrak/boss_gal_darah.cpp Northrend/Gundrak/boss_moorabi.cpp Northrend/Gundrak/boss_eck.cpp - Northrend/borean_tundra.cpp - Northrend/howling_fjord.cpp - Northrend/dalaran.cpp + Northrend/zone_borean_tundra.cpp + Northrend/zone_howling_fjord.cpp + Northrend/zone_dalaran.cpp Northrend/DraktharonKeep/boss_trollgore.cpp Northrend/DraktharonKeep/instance_drak_tharon_keep.cpp Northrend/DraktharonKeep/boss_novos.cpp diff --git a/src/server/scripts/Northrend/borean_tundra.cpp b/src/server/scripts/Northrend/borean_tundra.cpp deleted file mode 100644 index 8e7507bce61..00000000000 --- a/src/server/scripts/Northrend/borean_tundra.cpp +++ /dev/null @@ -1,2537 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Borean_Tundra -SD%Complete: 100 -SDComment: Quest support: 11708. Taxi vendors. -SDCategory: Borean Tundra -EndScriptData */ - -/* ContentData -npc_iruk -npc_corastrasza -npc_jenny -npc_sinkhole_kill_credit -npc_khunok_the_behemoth -mob_nerubar_victim -npc_keristrasza -npc_nesingwary_trapper -npc_lurgglbr -npc_nexus_drake_hatchling -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "ScriptedFollowerAI.h" -#include "Player.h" -#include "SpellInfo.h" -#include "WorldSession.h" - -/*###### -## npc_sinkhole_kill_credit -######*/ - -enum eSinkhole -{ - SPELL_SET_CART = 46797, - SPELL_EXPLODE_CART = 46799, - SPELL_SUMMON_CART = 46798, - SPELL_SUMMON_WORM = 46800, -}; - -class npc_sinkhole_kill_credit : public CreatureScript -{ -public: - npc_sinkhole_kill_credit() : CreatureScript("npc_sinkhole_kill_credit") { } - - struct npc_sinkhole_kill_creditAI : public ScriptedAI - { - npc_sinkhole_kill_creditAI(Creature* creature) : ScriptedAI(creature){} - - uint32 phaseTimer; - uint8 phase; - uint64 casterGuid; - - void Reset() - { - phaseTimer = 500; - phase = 0; - casterGuid = 0; - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (phase) - return; - - if (spell->Id == SPELL_SET_CART && caster->GetTypeId() == TYPEID_PLAYER - && CAST_PLR(caster)->GetQuestStatus(11897) == QUEST_STATUS_INCOMPLETE) - { - phase = 1; - casterGuid = caster->GetGUID(); - } - } - - void EnterCombat(Unit* /*who*/){} - - void UpdateAI(const uint32 diff) - { - if (!phase) - return; - - if (phaseTimer <= diff) - { - switch (phase) - { - case 1: - DoCast(me, SPELL_EXPLODE_CART, true); - DoCast(me, SPELL_SUMMON_CART, true); - if (GameObject* cart = me->FindNearestGameObject(188160, 3)) - cart->SetUInt32Value(GAMEOBJECT_FACTION, 14); - phaseTimer = 3000; - phase = 2; - break; - case 2: - if (GameObject* cart = me->FindNearestGameObject(188160, 3)) - cart->UseDoorOrButton(); - DoCast(me, SPELL_EXPLODE_CART, true); - phaseTimer = 3000; - phase = 3; - break; - case 3: - DoCast(me, SPELL_EXPLODE_CART, true); - phaseTimer = 2000; - phase = 4; - case 5: - DoCast(me, SPELL_SUMMON_WORM, true); - if (Unit* worm = me->FindNearestCreature(26250, 3)) - { - worm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - worm->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - } - phaseTimer = 1000; - phase = 6; - break; - case 6: - DoCast(me, SPELL_EXPLODE_CART, true); - if (Unit* worm = me->FindNearestCreature(26250, 3)) - { - me->Kill(worm); - worm->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - } - phaseTimer = 2000; - phase = 7; - break; - case 7: - DoCast(me, SPELL_EXPLODE_CART, true); - if (Player* caster = Unit::GetPlayer(*me, casterGuid)) - caster->KilledMonster(me->GetCreatureTemplate(), me->GetGUID()); - phaseTimer = 5000; - phase = 8; - break; - case 8: - EnterEvadeMode(); - break; - } - } else phaseTimer -= diff; - - } - - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_sinkhole_kill_creditAI(creature); - } -}; - -/*###### -## npc_khunok_the_behemoth -######*/ - -class npc_khunok_the_behemoth : public CreatureScript -{ -public: - npc_khunok_the_behemoth() : CreatureScript("npc_khunok_the_behemoth") { } - - struct npc_khunok_the_behemothAI : public ScriptedAI - { - npc_khunok_the_behemothAI(Creature* creature) : ScriptedAI(creature) {} - - void MoveInLineOfSight(Unit* who) - { - ScriptedAI::MoveInLineOfSight(who); - - if (who->GetTypeId() != TYPEID_UNIT) - return; - - if (who->GetEntry() == 25861 && me->IsWithinDistInMap(who, 10.0f)) - { - if (Unit* owner = who->GetOwner()) - { - if (owner->GetTypeId() == TYPEID_PLAYER) - { - owner->CastSpell(owner, 46231, true); - CAST_CRE(who)->DespawnOrUnsummon(); - } - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_khunok_the_behemothAI(creature); - } -}; - -/*###### -## npc_keristrasza -######*/ - -enum eKeristrasza -{ - SPELL_TELEPORT_TO_SARAGOSA = 46772 -}; - -#define GOSSIP_HELLO_KERI "I am prepared to face Saragosa!" - -class npc_keristrasza : public CreatureScript -{ -public: - npc_keristrasza() : CreatureScript("npc_keristrasza") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(11957) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_KERI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF + 1) - { - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_TELEPORT_TO_SARAGOSA, true); - } - - return true; - } -}; - -/*###### -## npc_corastrasza -######*/ - -#define GOSSIP_ITEM_C_1 "I... I think so..." - -enum eCorastrasza -{ - SPELL_SUMMON_WYRMREST_SKYTALON = 61240, - SPELL_WYRMREST_SKYTALON_RIDE_PERIODIC = 61244, - - QUEST_ACES_HIGH_DAILY = 13414, - QUEST_ACES_HIGH = 13413 -}; - -class npc_corastrasza : public CreatureScript -{ -public: - npc_corastrasza() : CreatureScript("npc_corastrasza") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_ACES_HIGH) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_ACES_HIGH_DAILY) == QUEST_STATUS_INCOMPLETE) //It's the same dragon for both quests. - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_C_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - - player->CastSpell(player, SPELL_SUMMON_WYRMREST_SKYTALON, true); - player->CastSpell(player, SPELL_WYRMREST_SKYTALON_RIDE_PERIODIC, true); - - } - - return true; - } -}; - -/*###### -## npc_iruk -######*/ - -#define GOSSIP_ITEM_I "" - -enum eIruk -{ - QUEST_SPIRITS_WATCH_OVER_US = 11961, - SPELL_CREATURE_TOTEM_OF_ISSLIRUK = 46816, - GOSSIP_TEXT_I = 12585 -}; - -class npc_iruk : public CreatureScript -{ -public: - npc_iruk() : CreatureScript("npc_iruk") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_SPIRITS_WATCH_OVER_US) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXT_I, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->CastSpell(player, SPELL_CREATURE_TOTEM_OF_ISSLIRUK, true); - player->CLOSE_GOSSIP_MENU(); - break; - - } - return true; - } -}; - -/*###### -## mob_nerubar_victim -######*/ - -#define WARSONG_PEON 25270 - -const uint32 nerubarVictims[3] = -{ - 45526, 45527, 45514 -}; - -class mob_nerubar_victim : public CreatureScript -{ -public: - mob_nerubar_victim() : CreatureScript("mob_nerubar_victim") { } - - struct mob_nerubar_victimAI : public ScriptedAI - { - mob_nerubar_victimAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - void EnterCombat(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - - void JustDied(Unit* killer) - { - Player* player = killer->ToPlayer(); - if (!player) - return; - - if (player->GetQuestStatus(11611) == QUEST_STATUS_INCOMPLETE) - { - uint8 uiRand = urand(0, 99); - if (uiRand < 25) - { - player->CastSpell(me, 45532, true); - player->KilledMonsterCredit(WARSONG_PEON, 0); - } - else if (uiRand < 75) - player->CastSpell(me, nerubarVictims[urand(0, 2)], true); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_nerubar_victimAI(creature); - } -}; - -/*###### -## npc_jenny -######*/ - -enum eJenny -{ - QUEST_LOADER_UP = 11881, - - NPC_FEZZIX_GEARTWIST = 25849, - NPC_JENNY = 25969, - - SPELL_GIVE_JENNY_CREDIT = 46358, - SPELL_CRATES_CARRIED = 46340, - SPELL_DROP_CRATE = 46342 -}; - -class npc_jenny : public CreatureScript -{ -public: - npc_jenny() : CreatureScript("npc_jenny") { } - - struct npc_jennyAI : public ScriptedAI - { - npc_jennyAI(Creature* creature) : ScriptedAI(creature) {} - - bool setCrateNumber; - - void Reset() - { - if (!setCrateNumber) - setCrateNumber = true; - - me->SetReactState(REACT_PASSIVE); - - switch (CAST_PLR(me->GetOwner())->GetTeamId()) - { - case TEAM_ALLIANCE: - me->setFaction(FACTION_ESCORT_A_NEUTRAL_ACTIVE); - break; - default: - case TEAM_HORDE: - me->setFaction(FACTION_ESCORT_H_NEUTRAL_ACTIVE); - break; - } - } - - void DamageTaken(Unit* /*pDone_by*/, uint32& /*uiDamage*/) - { - DoCast(me, SPELL_DROP_CRATE, true); - } - - void UpdateAI(const uint32 /*diff*/) - { - if (setCrateNumber) - { - me->AddAura(SPELL_CRATES_CARRIED, me); - setCrateNumber = false; - } - - if (!setCrateNumber && !me->HasAura(SPELL_CRATES_CARRIED)) - me->DisappearAndDie(); - - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_jennyAI (creature); - } -}; - -/*###### -## npc_fezzix_geartwist -######*/ - -class npc_fezzix_geartwist : public CreatureScript -{ -public: - npc_fezzix_geartwist() : CreatureScript("npc_fezzix_geartwist") { } - - struct npc_fezzix_geartwistAI : public ScriptedAI - { - npc_fezzix_geartwistAI(Creature* creature) : ScriptedAI(creature) {} - - void MoveInLineOfSight(Unit* who) - { - ScriptedAI::MoveInLineOfSight(who); - - if (who->GetTypeId() != TYPEID_UNIT) - return; - - if (who->GetEntry() == NPC_JENNY && me->IsWithinDistInMap(who, 10.0f)) - { - if (Unit* owner = who->GetOwner()) - { - if (owner->GetTypeId() == TYPEID_PLAYER) - { - if (who->HasAura(SPELL_CRATES_CARRIED)) - { - owner->CastSpell(owner, SPELL_GIVE_JENNY_CREDIT, true); // Maybe is not working. - CAST_PLR(owner)->CompleteQuest(QUEST_LOADER_UP); - CAST_CRE(who)->DisappearAndDie(); - } - } - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_fezzix_geartwistAI(creature); - } -}; - -/*###### -## npc_nesingwary_trapper -######*/ - -enum eNesingwaryTrapper -{ - GO_HIGH_QUALITY_FUR = 187983, - - GO_CARIBOU_TRAP_1 = 187982, - GO_CARIBOU_TRAP_2 = 187995, - GO_CARIBOU_TRAP_3 = 187996, - GO_CARIBOU_TRAP_4 = 187997, - GO_CARIBOU_TRAP_5 = 187998, - GO_CARIBOU_TRAP_6 = 187999, - GO_CARIBOU_TRAP_7 = 188000, - GO_CARIBOU_TRAP_8 = 188001, - GO_CARIBOU_TRAP_9 = 188002, - GO_CARIBOU_TRAP_10 = 188003, - GO_CARIBOU_TRAP_11 = 188004, - GO_CARIBOU_TRAP_12 = 188005, - GO_CARIBOU_TRAP_13 = 188006, - GO_CARIBOU_TRAP_14 = 188007, - GO_CARIBOU_TRAP_15 = 188008, - - SPELL_TRAPPED = 46104, -}; - -#define CaribouTrapsNum 15 -const uint32 CaribouTraps[CaribouTrapsNum] = -{ - GO_CARIBOU_TRAP_1, GO_CARIBOU_TRAP_2, GO_CARIBOU_TRAP_3, GO_CARIBOU_TRAP_4, GO_CARIBOU_TRAP_5, - GO_CARIBOU_TRAP_6, GO_CARIBOU_TRAP_7, GO_CARIBOU_TRAP_8, GO_CARIBOU_TRAP_9, GO_CARIBOU_TRAP_10, - GO_CARIBOU_TRAP_11, GO_CARIBOU_TRAP_12, GO_CARIBOU_TRAP_13, GO_CARIBOU_TRAP_14, GO_CARIBOU_TRAP_15, -}; - -class npc_nesingwary_trapper : public CreatureScript -{ -public: - npc_nesingwary_trapper() : CreatureScript("npc_nesingwary_trapper") { } - - struct npc_nesingwary_trapperAI : public ScriptedAI - { - npc_nesingwary_trapperAI(Creature* creature) : ScriptedAI(creature) { creature->SetVisible(false); } - - uint64 go_caribouGUID; - uint8 phase; - uint32 phaseTimer; - - void Reset() - { - me->SetVisible(false); - phaseTimer = 2500; - phase = 1; - go_caribouGUID = 0; - } - - void EnterCombat(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - - void JustDied(Unit* /*killer*/) - { - if (GameObject* go_caribou = me->GetMap()->GetGameObject(go_caribouGUID)) - go_caribou->SetLootState(GO_JUST_DEACTIVATED); - - if (TempSummon* summon = me->ToTempSummon()) - if (summon->isSummon()) - if (Unit* temp = summon->GetSummoner()) - if (temp->GetTypeId() == TYPEID_PLAYER) - CAST_PLR(temp)->KilledMonsterCredit(me->GetEntry(), 0); - - if (GameObject* go_caribou = me->GetMap()->GetGameObject(go_caribouGUID)) - go_caribou->SetGoState(GO_STATE_READY); - } - - void UpdateAI(const uint32 diff) - { - if (phaseTimer <= diff) - { - switch (phase) - { - case 1: - me->SetVisible(true); - phaseTimer = 2000; - phase = 2; - break; - case 2: - if (GameObject* go_fur = me->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 11.0f)) - me->GetMotionMaster()->MovePoint(0, go_fur->GetPositionX(), go_fur->GetPositionY(), go_fur->GetPositionZ()); - phaseTimer = 1500; - phase = 3; - break; - case 3: - //Talk(SAY_NESINGWARY_1); - phaseTimer = 2000; - phase = 4; - break; - case 4: - me->HandleEmoteCommand(EMOTE_ONESHOT_LOOT); - phaseTimer = 1000; - phase = 5; - break; - case 5: - me->HandleEmoteCommand(EMOTE_ONESHOT_NONE); - phaseTimer = 500; - phase = 6; - break; - case 6: - if (GameObject* go_fur = me->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 11.0f)) - go_fur->Delete(); - phaseTimer = 500; - phase = 7; - break; - case 7: - { - GameObject* go_caribou = NULL; - for (uint8 i = 0; i < CaribouTrapsNum; ++i) - { - go_caribou = me->FindNearestGameObject(CaribouTraps[i], 5.0f); - if (go_caribou) - { - go_caribou->SetGoState(GO_STATE_ACTIVE); - go_caribouGUID = go_caribou->GetGUID(); - break; - } - } - phase = 8; - phaseTimer = 1000; - } - break; - case 8: - DoCast(me, SPELL_TRAPPED, true); - phase = 0; - break; - } - } else phaseTimer -= diff; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_nesingwary_trapperAI(creature); - } -}; - -/*###### -## npc_lurgglbr -######*/ - -enum eLurgglbr -{ - QUEST_ESCAPE_WINTERFIN_CAVERNS = 11570, - - GO_CAGE = 187369, - - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775, - - SAY_START_1 = 0, - SAY_START_2 = 1, - SAY_END_1 = 2, - SAY_END_2 = 3 -}; - -class npc_lurgglbr : public CreatureScript -{ -public: - npc_lurgglbr() : CreatureScript("npc_lurgglbr") { } - - struct npc_lurgglbrAI : public npc_escortAI - { - npc_lurgglbrAI(Creature* creature) : npc_escortAI(creature){} - - uint32 IntroTimer; - uint32 IntroPhase; - - void Reset() - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - { - IntroTimer = 0; - IntroPhase = 0; - } - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 0: - IntroPhase = 1; - IntroTimer = 2000; - break; - case 41: - IntroPhase = 4; - IntroTimer = 2000; - break; - } - } - - void UpdateAI(const uint32 diff) - { - if (IntroPhase) - { - if (IntroTimer <= diff) - { - switch (IntroPhase) - { - case 1: - Talk(SAY_START_1); - IntroPhase = 2; - IntroTimer = 7500; - break; - case 2: - Talk(SAY_END_1); - IntroPhase = 3; - IntroTimer = 7500; - break; - case 3: - me->SetReactState(REACT_AGGRESSIVE); - IntroPhase = 0; - IntroTimer = 0; - break; - case 4: - Talk(SAY_START_2); - IntroPhase = 5; - IntroTimer = 8000; - break; - case 5: - Talk(SAY_END_2); - IntroPhase = 6; - IntroTimer = 2500; - break; - - case 6: - if (Player* player = GetPlayerForEscort()) - player->AreaExploredOrEventHappens(QUEST_ESCAPE_WINTERFIN_CAVERNS); - IntroPhase = 7; - IntroTimer = 2500; - break; - - case 7: - me->DespawnOrUnsummon(); - IntroPhase = 0; - IntroTimer = 0; - break; - } - } else IntroTimer -= diff; - } - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lurgglbrAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPE_WINTERFIN_CAVERNS) - { - if (GameObject* go = creature->FindNearestGameObject(GO_CAGE, 5.0f)) - { - go->SetRespawnTime(0); - go->SetGoType(GAMEOBJECT_TYPE_BUTTON); - go->UseDoorOrButton(20); - } - - if (npc_escortAI* pEscortAI = CAST_AI(npc_lurgglbr::npc_lurgglbrAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - - switch (player->GetTeam()) - { - case ALLIANCE: - creature->setFaction(FACTION_ESCORTEE_A); - break; - default: - case HORDE: - creature->setFaction(FACTION_ESCORTEE_H); - break; - } - - return true; - } - return false; - } -}; - -/*###### -## npc_nexus_drake_hatchling -######*/ - -enum eNexusDrakeHatchling -{ - SPELL_DRAKE_HARPOON = 46607, - SPELL_RED_DRAGONBLOOD = 46620, - SPELL_DRAKE_HATCHLING_SUBDUED = 46691, - SPELL_SUBDUED = 46675, - - NPC_RAELORASZ = 26117, - - QUEST_DRAKE_HUNT = 11919, - QUEST_DRAKE_HUNT_D = 11940 -}; - -class npc_nexus_drake_hatchling : public CreatureScript -{ -public: - npc_nexus_drake_hatchling() : CreatureScript("npc_nexus_drake_hatchling") { } - - struct npc_nexus_drake_hatchlingAI : public FollowerAI //The spell who makes the npc follow the player is missing, also we can use FollowerAI! - { - npc_nexus_drake_hatchlingAI(Creature* creature) : FollowerAI(creature) {} - - uint64 HarpoonerGUID; - bool WithRedDragonBlood; - - void Reset() - { - WithRedDragonBlood = false; - HarpoonerGUID = 0; - } - - void EnterCombat(Unit* who) - { - if (me->IsValidAttackTarget(who)) - AttackStart(who); - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id == SPELL_DRAKE_HARPOON && caster->GetTypeId() == TYPEID_PLAYER) - { - HarpoonerGUID = caster->GetGUID(); - DoCast(me, SPELL_RED_DRAGONBLOOD, true); - } - WithRedDragonBlood = true; - } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (!HarpoonerGUID) - return; - - if (me->HasAura(SPELL_SUBDUED) && who->GetEntry() == NPC_RAELORASZ) - { - if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) - { - if (Player* pHarpooner = Unit::GetPlayer(*me, HarpoonerGUID)) - { - pHarpooner->KilledMonsterCredit(26175, 0); - pHarpooner->RemoveAura(SPELL_DRAKE_HATCHLING_SUBDUED); - SetFollowComplete(); - HarpoonerGUID = 0; - me->DisappearAndDie(); - } - } - } - } - - void UpdateAI(const uint32 /*diff*/) - { - if (WithRedDragonBlood && HarpoonerGUID && !me->HasAura(SPELL_RED_DRAGONBLOOD)) - { - if (Player* pHarpooner = Unit::GetPlayer(*me, HarpoonerGUID)) - { - EnterEvadeMode(); - StartFollow(pHarpooner, 35, NULL); - - DoCast(me, SPELL_SUBDUED, true); - pHarpooner->CastSpell(pHarpooner, SPELL_DRAKE_HATCHLING_SUBDUED, true); - - me->AttackStop(); - WithRedDragonBlood = false; - } - } - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_nexus_drake_hatchlingAI(creature); - } -}; - -/*###### -## npc_thassarian -######*/ - -enum eThassarian -{ - QUEST_LAST_RITES = 12019, - - SPELL_TRANSFORM_VALANAR = 46753, - SPELL_STUN = 46957, - SPELL_SHADOW_BOLT = 15537, - - NPC_IMAGE_LICH_KING = 26203, - NPC_COUNSELOR_TALBOT = 25301, - NPC_PRINCE_VALANAR = 28189, - NPC_GENERAL_ARLOS = 25250, - NPC_LERYSSA = 25251, - - SAY_THASSARIAN_1 = 0, - SAY_THASSARIAN_2 = 1, - SAY_THASSARIAN_3 = 2, - SAY_THASSARIAN_4 = 3, - SAY_THASSARIAN_5 = 4, - SAY_THASSARIAN_6 = 5, - SAY_THASSARIAN_7 = 6, - - SAY_TALBOT_1 = 0, - SAY_TALBOT_2 = 1, - SAY_TALBOT_3 = 2, - SAY_TALBOT_4 = 3, - - SAY_LICH_1 = 0, - SAY_LICH_2 = 1, - SAY_LICH_3 = 2, - - SAY_ARLOS_1 = 0, - SAY_ARLOS_2 = 1, - - SAY_LERYSSA_1 = 0, - SAY_LERYSSA_2 = 1, - SAY_LERYSSA_3 = 2, - SAY_LERYSSA_4 = 3 -}; - -#define GOSSIP_ITEM_T "Let's do this, Thassarian. It's now or never." - -class npc_thassarian : public CreatureScript -{ -public: - npc_thassarian() : CreatureScript("npc_thassarian") { } - - struct npc_thassarianAI : public npc_escortAI - { - npc_thassarianAI(Creature* creature) : npc_escortAI(creature) {} - - uint64 arthasGUID; - uint64 talbotGUID; - uint64 leryssaGUID; - uint64 arlosGUID; - - bool arthasInPosition; - bool arlosInPosition; - bool leryssaInPosition; - bool talbotInPosition; - - uint32 phase; - uint32 phaseTimer; - - void Reset() - { - me->RestoreFaction(); - me->RemoveStandFlags(UNIT_STAND_STATE_SIT); - - arthasGUID = 0; - talbotGUID = 0; - leryssaGUID = 0; - arlosGUID = 0; - - arthasInPosition = false; - arlosInPosition = false; - leryssaInPosition = false; - talbotInPosition = false; - - phase = 0; - phaseTimer = 0; - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 3: - SetEscortPaused(true); - if (Creature* arthas = me->SummonCreature(NPC_IMAGE_LICH_KING, 3730.313f, 3518.689f, 473.324f, 1.562f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) - { - arthasGUID = arthas->GetGUID(); - arthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - arthas->SetReactState(REACT_PASSIVE); - arthas->SetWalk(true); - arthas->GetMotionMaster()->MovePoint(0, 3737.374756f, 3564.841309f, 477.433014f); - } - if (Creature* talbot = me->SummonCreature(NPC_COUNSELOR_TALBOT, 3747.23f, 3614.936f, 473.321f, 4.462012f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) - { - talbotGUID = talbot->GetGUID(); - talbot->SetWalk(true); - talbot->GetMotionMaster()->MovePoint(0, 3738.000977f, 3568.882080f, 477.433014f); - } - me->SetWalk(false); - break; - case 4: - SetEscortPaused(true); - phase = 7; - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (arthasInPosition && talbotInPosition) - { - phase = 1; - arthasInPosition = false; - talbotInPosition = false; - } - - if (arlosInPosition && leryssaInPosition) - { - arlosInPosition = false; - leryssaInPosition = false; - Talk(SAY_THASSARIAN_1); - SetEscortPaused(false); - } - - if (phaseTimer <= uiDiff) - { - Creature* talbot = me->GetCreature(*me, talbotGUID); - Creature* arthas = me->GetCreature(*me, arthasGUID); - switch (phase) - { - case 1: - if (talbot) - talbot->SetStandState(UNIT_STAND_STATE_KNEEL); - phaseTimer = 3000; - ++phase; - break; - - case 2: - if (talbot) - { - talbot->UpdateEntry(NPC_PRINCE_VALANAR, ALLIANCE); - talbot->setFaction(14); - talbot->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - talbot->SetReactState(REACT_PASSIVE); - } - phaseTimer = 5000; - ++phase; - break; - - case 3: - if (talbot) - talbot->AI()->Talk(SAY_TALBOT_1); - phaseTimer = 5000; - ++phase; - break; - - case 4: - if (arthas) - arthas->AI()->Talk(SAY_LICH_1); - phaseTimer = 5000; - ++phase; - break; - - case 5: - if (talbot) - talbot->AI()->Talk(SAY_TALBOT_2); - phaseTimer = 5000; - ++phase; - break; - - case 6: - if (Creature* arlos = me->SummonCreature(NPC_GENERAL_ARLOS, 3745.527100f, 3615.655029f, 473.321533f, 4.447805f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) - { - arlosGUID = arlos->GetGUID(); - arlos->SetWalk(true); - arlos->GetMotionMaster()->MovePoint(0, 3735.570068f, 3572.419922f, 477.441010f); - } - if (Creature* leryssa = me->SummonCreature(NPC_LERYSSA, 3749.654541f, 3614.959717f, 473.323486f, 4.524959f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) - { - leryssaGUID = leryssa->GetGUID(); - leryssa->SetWalk(false); - leryssa->SetReactState(REACT_PASSIVE); - leryssa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - leryssa->GetMotionMaster()->MovePoint(0, 3741.969971f, 3571.439941f, 477.441010f); - } - phaseTimer = 2000; - phase = 0; - break; - - case 7: - Talk(SAY_THASSARIAN_2); - phaseTimer = 5000; - ++phase; - break; - - case 8: - if (arthas && talbot) - { - arthas->SetInFront(me); //The client doesen't update with the new orientation :l - talbot->SetStandState(UNIT_STAND_STATE_STAND); - arthas->AI()->Talk(SAY_LICH_2); - } - phaseTimer = 5000; - phase = 9; - break; - - case 9: - Talk(SAY_THASSARIAN_3); - phaseTimer = 5000; - phase = 10; - break; - - case 10: - if (talbot) - talbot->AI()->Talk(SAY_TALBOT_3); - phaseTimer = 5000; - phase = 11; - break; - - case 11: - if (arthas) - arthas->AI()->Talk(SAY_LICH_3); - phaseTimer = 5000; - phase = 12; - break; - - case 12: - if (talbot) - talbot->AI()->Talk(SAY_TALBOT_4); - phaseTimer = 2000; - phase = 13; - break; - - case 13: - if (arthas) - arthas->RemoveFromWorld(); - ++phase; - break; - - case 14: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (talbot) - { - talbot->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - talbot->SetReactState(REACT_AGGRESSIVE); - talbot->CastSpell(me, SPELL_SHADOW_BOLT, false); - } - phaseTimer = 1500; - ++phase; - break; - - case 15: - me->SetReactState(REACT_AGGRESSIVE); - AttackStart(talbot); - phase = 0; - break; - - case 16: - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - phaseTimer = 20000; - ++phase; - break; - - case 17: - if (Creature* leryssa = me->GetCreature(*me, leryssaGUID)) - leryssa->RemoveFromWorld(); - if (Creature* arlos= me->GetCreature(*me, arlosGUID)) - arlos->RemoveFromWorld(); - if (talbot) - talbot->RemoveFromWorld(); - me->RemoveStandFlags(UNIT_STAND_STATE_SIT); - SetEscortPaused(false); - phaseTimer = 0; - phase = 0; - } - } else phaseTimer -= uiDiff; - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) - { - if (Creature* talbot = me->GetCreature(*me, talbotGUID)) - talbot->RemoveFromWorld(); - - if (Creature* leryssa = me->GetCreature(*me, leryssaGUID)) - leryssa->RemoveFromWorld(); - - if (Creature* arlos = me->GetCreature(*me, arlosGUID)) - arlos->RemoveFromWorld(); - - if (Creature* arthas = me->GetCreature(*me, arthasGUID)) - arthas->RemoveFromWorld(); - } - }; - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_LAST_RITES) == QUEST_STATUS_INCOMPLETE && creature->GetAreaId() == 4128) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_T, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(200.0f); - break; - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_thassarianAI(creature); - } -}; - -/*###### -## npc_image_lich_king -######*/ - -class npc_image_lich_king : public CreatureScript -{ -public: - npc_image_lich_king() : CreatureScript("npc_image_lich_king") { } - - struct npc_image_lich_kingAI : public ScriptedAI - { - npc_image_lich_kingAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - me->RestoreFaction(); - } - - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, CAST_CRE(summoner)->AI())->arthasInPosition = true; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_image_lich_kingAI(creature); - } -}; - -/*###### -## npc_general_arlos -######*/ - -class npc_general_arlos : public CreatureScript -{ -public: - npc_general_arlos() : CreatureScript("npc_general_arlos") { } - - struct npc_general_arlosAI : public ScriptedAI - { - npc_general_arlosAI(Creature* creature) : ScriptedAI(creature) {} - - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - - me->AddUnitState(UNIT_STATE_STUNNED); - me->CastSpell(me, SPELL_STUN, true); - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, CAST_CRE(summoner)->AI())->arlosInPosition = true; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_general_arlosAI(creature); - } -}; - -/*###### -## npc_counselor_talbot -######*/ - -enum eCounselorTalbot -{ - SPELL_DEFLECTION = 51009, - SPELL_SOUL_BLAST = 50992, -}; - -class npc_counselor_talbot : public CreatureScript -{ -public: - npc_counselor_talbot() : CreatureScript("npc_counselor_talbot") { } - - struct npc_counselor_talbotAI : public ScriptedAI - { - npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature) - { - creature->RestoreFaction(); - } - - uint64 leryssaGUID; - uint64 arlosGUID; - - bool bCheck; - - uint32 shadowBoltTimer; - uint32 deflectionTimer; - uint32 soulBlastTimer; - - void Reset() - { - leryssaGUID = 0; - arlosGUID = 0; - bCheck = false; - shadowBoltTimer = urand(5000, 12000); - deflectionTimer = urand(20000, 25000); - soulBlastTimer = urand (12000, 18000); - } - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, CAST_CRE(summoner)->AI())->talbotInPosition = true; - } - - void UpdateAI(const uint32 uiDiff) - { - if (bCheck) - { - if (Creature* leryssa = me->FindNearestCreature(NPC_LERYSSA, 50.0f, true)) - leryssaGUID = leryssa->GetGUID(); - if (Creature* arlos = me->FindNearestCreature(NPC_GENERAL_ARLOS, 50.0f, true)) - arlosGUID = arlos->GetGUID(); - bCheck = false; - } - - if (!UpdateVictim()) - return; - - if (me->GetAreaId() == 4125) - { - if (shadowBoltTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_SHADOW_BOLT); - shadowBoltTimer = urand(5000, 12000); - } else shadowBoltTimer -= uiDiff; - - if (deflectionTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_DEFLECTION); - deflectionTimer = urand(20000, 25000); - } else deflectionTimer -= uiDiff; - - if (soulBlastTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_SOUL_BLAST); - soulBlastTimer = urand (12000, 18000); - } else soulBlastTimer -= uiDiff; - } - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - if (!leryssaGUID || !arlosGUID) - return; - - Creature* leryssa = Unit::GetCreature(*me, leryssaGUID); - Creature* arlos = Unit::GetCreature(*me, arlosGUID); - if (!leryssa || !arlos) - return; - - arlos->AI()->Talk(SAY_ARLOS_1); - arlos->AI()->Talk(SAY_ARLOS_2); - leryssa->AI()->Talk(SAY_LERYSSA_1); - arlos->Kill(arlos, false); - leryssa->RemoveAura(SPELL_STUN); - leryssa->ClearUnitState(UNIT_STATE_STUNNED); - leryssa->SetWalk(false); - leryssa->GetMotionMaster()->MovePoint(0, 3722.114502f, 3564.201660f, 477.441437f); - - if (Player* player = killer->ToPlayer()) - player->RewardPlayerAndGroupAtEvent(NPC_PRINCE_VALANAR, 0); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_counselor_talbotAI(creature); - } -}; - -/*###### -## npc_leryssa -######*/ - -class npc_leryssa : public CreatureScript -{ -public: - npc_leryssa() : CreatureScript("npc_leryssa") { } - - struct npc_leryssaAI : public ScriptedAI - { - npc_leryssaAI(Creature* creature) : ScriptedAI(creature) - { - bDone = false; - phase = 0; - phaseTimer = 0; - - creature->RemoveStandFlags(UNIT_STAND_STATE_SIT); - } - - bool bDone; - - uint32 phase; - uint32 phaseTimer; - - void MovementInform(uint32 type, uint32 /*uiId*/) - { - if (type != POINT_MOTION_TYPE) - return; - - if (!bDone) - { - if (Creature* talbot = me->FindNearestCreature(NPC_PRINCE_VALANAR, 50.0f, true)) - CAST_AI(npc_counselor_talbot::npc_counselor_talbotAI, talbot->GetAI())->bCheck = true; - - me->AddUnitState(UNIT_STATE_STUNNED); - me->CastSpell(me, SPELL_STUN, true); - - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - CAST_AI(npc_thassarian::npc_thassarianAI, summoner->GetAI())->leryssaInPosition = true; - bDone = true; - } - else - { - me->SetStandState(UNIT_STAND_STATE_SIT); - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - summoner->SetStandState(UNIT_STAND_STATE_SIT); - phaseTimer = 1500; - phase = 1; - } - } - - void UpdateAI(const uint32 uiDiff) - { - ScriptedAI::UpdateAI(uiDiff); - - if (phaseTimer <= uiDiff) - { - switch (phase) - { - case 1: - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (Creature* thassarian = summoner->ToCreature()) - thassarian->AI()->Talk(SAY_THASSARIAN_4); - phaseTimer = 5000; - ++phase; - break; - case 2: - Talk(SAY_LERYSSA_2); - phaseTimer = 5000; - ++phase; - break; - case 3: - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (Creature* thassarian = summoner->ToCreature()) - thassarian->AI()->Talk(SAY_THASSARIAN_5); - phaseTimer = 5000; - ++phase; - break; - case 4: - Talk(SAY_LERYSSA_3); - phaseTimer = 5000; - ++phase; - break; - case 5: - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (Creature* thassarian = summoner->ToCreature()) - thassarian->AI()->Talk(SAY_THASSARIAN_6); - phaseTimer = 5000; - ++phase; - break; - - case 6: - Talk(SAY_LERYSSA_4); - phaseTimer = 5000; - ++phase; - break; - case 7: - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (Creature* thassarian = summoner->ToCreature()) - { - thassarian->AI()->Talk(SAY_THASSARIAN_7); - CAST_AI(npc_thassarian::npc_thassarianAI, thassarian->GetAI())->phase = 16; - } - phaseTimer = 5000; - phase = 0; - break; - } - } else phaseTimer -= uiDiff; - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_leryssaAI(creature); - } -}; - -/*###### -## 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 -}; - -class npc_beryl_sorcerer : public CreatureScript -{ -public: - npc_beryl_sorcerer() : CreatureScript("npc_beryl_sorcerer") { } - - struct npc_beryl_sorcererAI : public FollowerAI - { - npc_beryl_sorcererAI(Creature* creature) : FollowerAI(creature) {} - - bool bEnslaved; - - void Reset() - { - me->SetReactState(REACT_AGGRESSIVE); - bEnslaved = false; - } - - void EnterCombat(Unit* who) - { - if (me->IsValidAttackTarget(who)) - AttackStart(who); - } - - void SpellHit(Unit* pCaster, const SpellInfo* pSpell) - { - if (pSpell->Id == SPELL_ARCANE_CHAINS && pCaster->GetTypeId() == TYPEID_PLAYER && !HealthAbovePct(50) && !bEnslaved) - { - EnterEvadeMode(); //We make sure that the npc is not attacking the player! - me->SetReactState(REACT_PASSIVE); - StartFollow(pCaster->ToPlayer(), 0, NULL); - me->UpdateEntry(NPC_CAPTURED_BERLY_SORCERER, TEAM_NEUTRAL); - DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF, true); - - if (Player* player = pCaster->ToPlayer()) - player->KilledMonsterCredit(NPC_CAPTURED_BERLY_SORCERER, 0); - - bEnslaved = true; - } - } - - void MoveInLineOfSight(Unit* who) - { - FollowerAI::MoveInLineOfSight(who); - - if (who->GetEntry() == NPC_LIBRARIAN_DONATHAN && me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) - { - SetFollowComplete(); - me->DisappearAndDie(); - } - } - - void UpdateAI(const uint32 /*uiDiff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_beryl_sorcererAI(creature); - } -}; - -/*###### -## npc_imprisoned_beryl_sorcerer -######*/ -enum eImprisionedBerylSorcerer -{ - SPELL_NEURAL_NEEDLE = 45634, - - NPC_IMPRISONED_BERYL_SORCERER = 25478, - - SAY_IMPRISIONED_BERYL_1 = 0, - SAY_IMPRISIONED_BERYL_2 = 1, - SAY_IMPRISIONED_BERYL_3 = 2, - SAY_IMPRISIONED_BERYL_4 = 3, - SAY_IMPRISIONED_BERYL_5 = 4, - SAY_IMPRISIONED_BERYL_6 = 5, - SAY_IMPRISIONED_BERYL_7 = 6 -}; - -class npc_imprisoned_beryl_sorcerer : public CreatureScript -{ -public: - npc_imprisoned_beryl_sorcerer() : CreatureScript("npc_imprisoned_beryl_sorcerer") { } - - struct npc_imprisoned_beryl_sorcererAI : public ScriptedAI - { - npc_imprisoned_beryl_sorcererAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 rebuff; - - void Reset() - { - if (me->GetReactState() != REACT_PASSIVE) - me->SetReactState(REACT_PASSIVE); - - rebuff = 0; - } - - void UpdateAI(const uint32 diff) - { - UpdateVictim(); - - if (rebuff <= diff) - { - if (!me->HasAura(SPELL_COSMETIC_ENSLAVE_CHAINS_SELF)) - { - DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF); - } - rebuff = 180000; - } - else - rebuff -= diff; - - DoMeleeAttackIfReady(); - } - - void EnterCombat(Unit* /*who*/) - { - } - - void SpellHit(Unit* unit, const SpellInfo* spell) - { - if (spell->Id == SPELL_NEURAL_NEEDLE && unit->GetTypeId() == TYPEID_PLAYER) - { - if (Player* player = unit->ToPlayer()) - { - GotStinged(player->GetGUID()); - } - } - } - - void GotStinged(uint64 casterGUID) - { - if (Player* caster = Player::GetPlayer(*me, casterGUID)) - { - uint32 step = caster->GetAuraCount(SPELL_NEURAL_NEEDLE) + 1; - switch (step) - { - case 1: - Talk(SAY_IMPRISIONED_BERYL_1); - break; - case 2: - Talk(SAY_IMPRISIONED_BERYL_2, caster->GetGUID()); - break; - case 3: - Talk(SAY_IMPRISIONED_BERYL_3); - break; - case 4: - Talk(SAY_IMPRISIONED_BERYL_4); - break; - case 5: - Talk(SAY_IMPRISIONED_BERYL_5); - break; - case 6: - Talk(SAY_IMPRISIONED_BERYL_6, caster->GetGUID()); - break; - case 7: - Talk(SAY_IMPRISIONED_BERYL_7); - caster->KilledMonsterCredit(NPC_IMPRISONED_BERYL_SORCERER, 0); - break; - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_imprisoned_beryl_sorcererAI(creature); - } -}; - -/*###### -## npc_mootoo_the_younger -######*/ -enum MootooTheYounger -{ - SAY_1 = 0, - SAY_2 = 1, - SAY_3 = 2, - SAY_4 = 3, - SAY_5 = 4, - - NPC_MOOTOO_THE_YOUNGER = 25504, - QUEST_ESCAPING_THE_MIST = 11664 -}; - -class npc_mootoo_the_younger : public CreatureScript -{ -public: - npc_mootoo_the_younger() : CreatureScript("npc_mootoo_the_younger") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPING_THE_MIST) - { - switch (player->GetTeam()) - { - case ALLIANCE: - creature->setFaction(FACTION_ESCORTEE_A); - break; - case HORDE: - creature->setFaction(FACTION_ESCORTEE_H); - break; - } - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_1); - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - } - return true; - } - - struct npc_mootoo_the_youngerAI : public npc_escortAI - { - npc_mootoo_the_youngerAI(Creature* creature) : npc_escortAI(creature) {} - - void Reset() - { - SetDespawnAtFar(false); - } - - void JustDied(Unit* /*killer*/) - { - if (Player* player=GetPlayerForEscort()) - player->FailQuest(QUEST_ESCAPING_THE_MIST); - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 10: - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - Talk(SAY_2); - break; - case 12: - Talk(SAY_3); - me->HandleEmoteCommand(EMOTE_ONESHOT_LOOT); - break; - case 16: - Talk(SAY_4); - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - break; - case 20: - me->SetPhaseMask(1, true); - Talk(SAY_5); - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - player->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me); - SetRun(true); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_mootoo_the_youngerAI(creature); - } -}; - -/*###### -## npc_bonker_togglevolt -######*/ - -enum BonkerTogglevolt -{ - NPC_BONKER_TOGGLEVOLT = 25589, - QUEST_GET_ME_OUTA_HERE = 11673, - - SAY_BONKER_1 = 0, - SAY_BONKER_2 = 1 -}; - -class npc_bonker_togglevolt : public CreatureScript -{ -public: - npc_bonker_togglevolt() : CreatureScript("npc_bonker_togglevolt") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_GET_ME_OUTA_HERE) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_BONKER_2, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, true, player->GetGUID()); - } - return true; - } - - struct npc_bonker_togglevoltAI : public npc_escortAI - { - npc_bonker_togglevoltAI(Creature* creature) : npc_escortAI(creature) {} - uint32 Bonker_agro; - - void Reset() - { - Bonker_agro=0; - SetDespawnAtFar(false); - } - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_GET_ME_OUTA_HERE); - } - - void UpdateEscortAI(const uint32 /*diff*/) - { - if (GetAttack() && UpdateVictim()) - { - if (Bonker_agro == 0) - { - Talk(SAY_BONKER_1); - Bonker_agro++; - } - DoMeleeAttackIfReady(); - } - else Bonker_agro=0; - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 29: - player->GroupEventHappens(QUEST_GET_ME_OUTA_HERE, me); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_bonker_togglevoltAI(creature); - } -}; - -/*###### -## Help Those That Cannot Help Themselves, Quest 11876 -######*/ - -enum eHelpThemselves -{ - QUEST_CANNOT_HELP_THEMSELVES = 11876, - GO_MAMMOTH_TRAP_1 = 188022, - GO_MAMMOTH_TRAP_2 = 188024, - GO_MAMMOTH_TRAP_3 = 188025, - GO_MAMMOTH_TRAP_4 = 188026, - GO_MAMMOTH_TRAP_5 = 188027, - GO_MAMMOTH_TRAP_6 = 188028, - GO_MAMMOTH_TRAP_7 = 188029, - GO_MAMMOTH_TRAP_8 = 188030, - GO_MAMMOTH_TRAP_9 = 188031, - GO_MAMMOTH_TRAP_10 = 188032, - GO_MAMMOTH_TRAP_11 = 188033, - GO_MAMMOTH_TRAP_12 = 188034, - GO_MAMMOTH_TRAP_13 = 188035, - GO_MAMMOTH_TRAP_14 = 188036, - GO_MAMMOTH_TRAP_15 = 188037, - GO_MAMMOTH_TRAP_16 = 188038, - GO_MAMMOTH_TRAP_17 = 188039, - GO_MAMMOTH_TRAP_18 = 188040, - GO_MAMMOTH_TRAP_19 = 188041, - GO_MAMMOTH_TRAP_20 = 188042, - GO_MAMMOTH_TRAP_21 = 188043, - GO_MAMMOTH_TRAP_22 = 188044, -}; - -#define MammothTrapsNum 22 -const uint32 MammothTraps[MammothTrapsNum] = -{ - GO_MAMMOTH_TRAP_1, GO_MAMMOTH_TRAP_2, GO_MAMMOTH_TRAP_3, GO_MAMMOTH_TRAP_4, GO_MAMMOTH_TRAP_5, - GO_MAMMOTH_TRAP_6, GO_MAMMOTH_TRAP_7, GO_MAMMOTH_TRAP_8, GO_MAMMOTH_TRAP_9, GO_MAMMOTH_TRAP_10, - GO_MAMMOTH_TRAP_11, GO_MAMMOTH_TRAP_12, GO_MAMMOTH_TRAP_13, GO_MAMMOTH_TRAP_14, GO_MAMMOTH_TRAP_15, - GO_MAMMOTH_TRAP_16, GO_MAMMOTH_TRAP_17, GO_MAMMOTH_TRAP_18, GO_MAMMOTH_TRAP_19, GO_MAMMOTH_TRAP_20, - GO_MAMMOTH_TRAP_21, GO_MAMMOTH_TRAP_22 -}; - -class npc_trapped_mammoth_calf : public CreatureScript -{ -public: - npc_trapped_mammoth_calf() : CreatureScript("npc_trapped_mammoth_calf") { } - - struct npc_trapped_mammoth_calfAI : public ScriptedAI - { - npc_trapped_mammoth_calfAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 uiTimer; - bool bStarted; - - void Reset() - { - uiTimer = 1500; - bStarted = false; - - GameObject* pTrap = NULL; - for (uint8 i = 0; i < MammothTrapsNum; ++i) - { - pTrap = me->FindNearestGameObject(MammothTraps[i], 11.0f); - if (pTrap) - { - pTrap->SetGoState(GO_STATE_ACTIVE); - return; - } - } - } - - void UpdateAI(const uint32 diff) - { - if (bStarted) - { - if (uiTimer <= diff) - { - Position pos; - me->GetRandomNearPosition(pos, 10.0f); - me->GetMotionMaster()->MovePoint(0, pos); - bStarted = false; - } - else uiTimer -= diff; - } - } - - void DoAction(const int32 param) - { - if (param == 1) - bStarted = true; - } - - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - - me->DisappearAndDie(); - - GameObject* pTrap = NULL; - for (uint8 i = 0; i < MammothTrapsNum; ++i) - { - pTrap = me->FindNearestGameObject(MammothTraps[i], 11.0f); - if (pTrap) - { - pTrap->SetLootState(GO_JUST_DEACTIVATED); - return; - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_trapped_mammoth_calfAI(creature); - } -}; - -/*###### -## Quest 11653: Hah... You're Not So Big Now! -######*/ - -enum eNotSoBig -{ - QUEST_YOU_RE_NOT_SO_BIG_NOW = 11653, - SPELL_AURA_NOTSOBIG_1 = 45672, - SPELL_AURA_NOTSOBIG_2 = 45673, - SPELL_AURA_NOTSOBIG_3 = 45677, - SPELL_AURA_NOTSOBIG_4 = 45681 -}; - -class npc_magmoth_crusher : public CreatureScript -{ -public: - npc_magmoth_crusher() : CreatureScript("npc_magmoth_crusher") { } - - struct npc_magmoth_crusherAI : public ScriptedAI - { - npc_magmoth_crusherAI(Creature* creature) : ScriptedAI(creature) {} - - void JustDied(Unit* killer) - { - Player* player = killer->ToPlayer(); - if (!player) - return; - - if (player->GetQuestStatus(QUEST_YOU_RE_NOT_SO_BIG_NOW) == QUEST_STATUS_INCOMPLETE && - (me->HasAura(SPELL_AURA_NOTSOBIG_1) || me->HasAura(SPELL_AURA_NOTSOBIG_2) || - me->HasAura(SPELL_AURA_NOTSOBIG_3) || me->HasAura(SPELL_AURA_NOTSOBIG_4))) - { - Quest const* qInfo = sObjectMgr->GetQuestTemplate(QUEST_YOU_RE_NOT_SO_BIG_NOW); - if (qInfo) - player->KilledMonsterCredit(qInfo->RequiredNpcOrGo[0], 0); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_magmoth_crusherAI(creature); - } -}; - -/*###### -## Quest 11608: Bury Those Cockroaches! -######*/ - -#define QUEST_BURY_THOSE_COCKROACHES 11608 -#define SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION 45502 - -class npc_seaforium_depth_charge : public CreatureScript -{ -public: - npc_seaforium_depth_charge() : CreatureScript("npc_seaforium_depth_charge") { } - - struct npc_seaforium_depth_chargeAI : public ScriptedAI - { - npc_seaforium_depth_chargeAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 uiExplosionTimer; - - void Reset() - { - uiExplosionTimer = urand(5000, 10000); - } - - void UpdateAI(const uint32 diff) - { - if (uiExplosionTimer < diff) - { - DoCast(SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION); - for (uint8 i = 0; i < 4; ++i) - { - if (Creature* cCredit = me->FindNearestCreature(25402 + i, 10.0f))//25402-25405 credit markers - { - if (Unit* uOwner = me->GetOwner()) - { - Player* owner = uOwner->ToPlayer(); - if (owner && owner->GetQuestStatus(QUEST_BURY_THOSE_COCKROACHES) == QUEST_STATUS_INCOMPLETE) - owner->KilledMonsterCredit(cCredit->GetEntry(), cCredit->GetGUID()); - } - } - } - me->Kill(me); - return; - } else uiExplosionTimer -= diff; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_seaforium_depth_chargeAI(creature); - } -}; - -/*###### -## Help Those That Cannot Help Themselves, Quest 11876 -######*/ - -enum eValiancekeepcannons -{ - GO_VALIANCE_KEEP_CANNON_1 = 187560, - GO_VALIANCE_KEEP_CANNON_2 = 188692 -}; - -class npc_valiance_keep_cannoneer : public CreatureScript -{ -public: - npc_valiance_keep_cannoneer() : CreatureScript("npc_valiance_keep_cannoneer") { } - - struct npc_valiance_keep_cannoneerAI : public ScriptedAI - { - npc_valiance_keep_cannoneerAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 uiTimer; - - void Reset() - { - uiTimer = urand(13000, 18000); - } - - void UpdateAI(const uint32 diff) - { - if (uiTimer <= diff) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); - GameObject* pCannon = me->FindNearestGameObject(GO_VALIANCE_KEEP_CANNON_1, 10); - if (!pCannon) - pCannon = me->FindNearestGameObject(GO_VALIANCE_KEEP_CANNON_2, 10); - if (pCannon) - pCannon->Use(me); - uiTimer = urand(13000, 18000); - } - else uiTimer -= diff; - - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_valiance_keep_cannoneerAI(creature); - } -}; - -/******************************************************* - * npc_warmage_coldarra - *******************************************************/ - -enum Spells -{ - SPELL_TRANSITUS_SHIELD_BEAM = 48310 -}; - -enum NPCs -{ - NPC_TRANSITUS_SHIELD_DUMMY = 27306, - NPC_WARMAGE_HOLLISTER = 27906, - NPC_WARMAGE_CALANDRA = 27173, - NPC_WARMAGE_WATKINS = 27904 -}; - -class npc_warmage_coldarra : public CreatureScript -{ -public: - npc_warmage_coldarra() : CreatureScript("npc_warmage_coldarra") { } - - struct npc_warmage_coldarraAI : public Scripted_NoMovementAI - { - npc_warmage_coldarraAI(Creature* creature) : Scripted_NoMovementAI(creature){} - - uint32 m_uiTimer; //Timer until recast - - void Reset() - { - m_uiTimer = 0; - } - - void EnterCombat(Unit* /*who*/) {} - - void AttackStart(Unit* /*who*/) {} - - void UpdateAI(const uint32 uiDiff) - { - if (m_uiTimer <= uiDiff) - { - std::list orbList; - GetCreatureListWithEntryInGrid(orbList, me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f); - - switch (me->GetEntry()) - { - case NPC_WARMAGE_HOLLISTER: - { - if (!orbList.empty()) - { - for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) - { - if (Creature* pOrb = *itr) - if (pOrb->GetPositionY() > 6680) - DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); - } - } - m_uiTimer = urand(90000, 120000); - } - break; - case NPC_WARMAGE_CALANDRA: - { - if (!orbList.empty()) - { - for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) - { - if (Creature* pOrb = *itr) - if ((pOrb->GetPositionY() < 6680) && (pOrb->GetPositionY() > 6630)) - DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); - } - } - m_uiTimer = urand(90000, 120000); - } - break; - case NPC_WARMAGE_WATKINS: - { - if (!orbList.empty()) - { - for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) - { - if (Creature* pOrb = *itr) - if (pOrb->GetPositionY() < 6630) - DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); - } - } - m_uiTimer = urand(90000, 120000); - } - break; - } - } - else m_uiTimer -= uiDiff; - - ScriptedAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_warmage_coldarraAI(creature); - } -}; - -/*###### -## npc_hidden_cultist -######*/ - -enum eHiddenCultist -{ - SPELL_SHROUD_OF_THE_DEATH_CULTIST = 46077, //not working - SPELL_RIGHTEOUS_VISION = 46078, //player aura - - QUEST_THE_HUNT_IS_ON = 11794, - - GOSSIP_TEXT_SALTY_JOHN_THORPE = 12529, - GOSSIP_TEXT_GUARD_MITCHELSS = 12530, - GOSSIP_TEXT_TOM_HEGGER = 12528, - - NPC_TOM_HEGGER = 25827, - NPC_SALTY_JOHN_THORPE = 25248, - NPC_GUARD_MITCHELLS = 25828, - - SAY_HIDDEN_CULTIST_1 = 0, - SAY_HIDDEN_CULTIST_2 = 1, - SAY_HIDDEN_CULTIST_3 = 2, - SAY_HIDDEN_CULTIST_4 = 3 -}; - -const char* GOSSIP_ITEM_TOM_HEGGER = "What do you know about the Cult of the Damned?"; -const char* GOSSIP_ITEM_GUARD_MITCHELLS = "How long have you worked for the Cult of the Damned?"; -const char* GOSSIP_ITEM_SALTY_JOHN_THORPE = "I have a reason to believe you're involved in the cultist activity"; - -class npc_hidden_cultist : public CreatureScript -{ -public: - npc_hidden_cultist() : CreatureScript("npc_hidden_cultist") { } - - struct npc_hidden_cultistAI : public ScriptedAI - { - npc_hidden_cultistAI(Creature* creature) : ScriptedAI(creature) - { - uiEmoteState = creature->GetUInt32Value(UNIT_NPC_EMOTESTATE); - uiNpcFlags = creature->GetUInt32Value(UNIT_NPC_FLAGS); - } - - uint32 uiEmoteState; - uint32 uiNpcFlags; - - uint32 uiEventTimer; - uint8 uiEventPhase; - - uint64 uiPlayerGUID; - - void Reset() - { - if (uiEmoteState) - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, uiEmoteState); - - if (uiNpcFlags) - me->SetUInt32Value(UNIT_NPC_FLAGS, uiNpcFlags); - - uiEventTimer = 0; - uiEventPhase = 0; - - uiPlayerGUID = 0; - - DoCast(SPELL_SHROUD_OF_THE_DEATH_CULTIST); - - me->RestoreFaction(); - } - - void DoAction(const int32 /*iParam*/) - { - me->StopMoving(); - me->SetUInt32Value(UNIT_NPC_FLAGS, 0); - if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) - { - me->SetInFront(player); - me->SendMovementFlagUpdate(); - } - uiEventTimer = 3000; - uiEventPhase = 1; - } - - void SetGUID(uint64 uiGuid, int32 /*iId*/) - { - uiPlayerGUID = uiGuid; - } - - void AttackPlayer() - { - me->setFaction(14); - if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) - me->AI()->AttackStart(player); - } - - void UpdateAI(const uint32 uiDiff) - { - if (uiEventTimer && uiEventTimer <= uiDiff) - { - switch (uiEventPhase) - { - case 1: - switch (me->GetEntry()) - { - case NPC_SALTY_JOHN_THORPE: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); - Talk(SAY_HIDDEN_CULTIST_1); - uiEventTimer = 5000; - uiEventPhase = 2; - break; - case NPC_GUARD_MITCHELLS: - Talk(SAY_HIDDEN_CULTIST_2); - uiEventTimer = 5000; - uiEventPhase = 2; - break; - case NPC_TOM_HEGGER: - Talk(SAY_HIDDEN_CULTIST_3); - uiEventTimer = 5000; - uiEventPhase = 2; - break; - } - break; - case 2: - switch (me->GetEntry()) - { - case NPC_SALTY_JOHN_THORPE: - Talk(SAY_HIDDEN_CULTIST_4); - if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) - { - me->SetInFront(player); - me->SendMovementFlagUpdate(); - } - uiEventTimer = 3000; - uiEventPhase = 3; - break; - case NPC_GUARD_MITCHELLS: - case NPC_TOM_HEGGER: - AttackPlayer(); - uiEventPhase = 0; - break; - } - break; - case 3: - if (me->GetEntry() == NPC_SALTY_JOHN_THORPE) - { - AttackPlayer(); - uiEventPhase = 0; - } - break; - } - }else uiEventTimer -= uiDiff; - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_hidden_cultistAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - uint32 uiGossipText = 0; - const char* charGossipItem; - - switch (creature->GetEntry()) - { - case NPC_TOM_HEGGER: - uiGossipText = GOSSIP_TEXT_TOM_HEGGER; - charGossipItem = GOSSIP_ITEM_TOM_HEGGER; - break; - case NPC_SALTY_JOHN_THORPE: - uiGossipText = GOSSIP_TEXT_SALTY_JOHN_THORPE; - charGossipItem = GOSSIP_ITEM_SALTY_JOHN_THORPE; - break; - case NPC_GUARD_MITCHELLS: - uiGossipText = GOSSIP_TEXT_GUARD_MITCHELSS; - charGossipItem = GOSSIP_ITEM_GUARD_MITCHELLS; - break; - default: - charGossipItem = ""; - return false; - } - - if (player->HasAura(SPELL_RIGHTEOUS_VISION) && player->GetQuestStatus(QUEST_THE_HUNT_IS_ON) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, charGossipItem, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - if (creature->isVendor()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(uiGossipText, creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->AI()->SetGUID(player->GetGUID()); - creature->AI()->DoAction(1); - } - - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - -}; - -void AddSC_borean_tundra() -{ - new npc_sinkhole_kill_credit(); - new npc_khunok_the_behemoth(); - new npc_keristrasza(); - new npc_corastrasza(); - new npc_iruk(); - new mob_nerubar_victim(); - new npc_jenny(); - new npc_fezzix_geartwist(); - new npc_nesingwary_trapper(); - new npc_lurgglbr(); - new npc_nexus_drake_hatchling(); - new npc_thassarian(); - new npc_image_lich_king(); - new npc_counselor_talbot(); - new npc_leryssa(); - new npc_general_arlos(); - new npc_beryl_sorcerer(); - new npc_imprisoned_beryl_sorcerer(); - new npc_mootoo_the_younger(); - new npc_bonker_togglevolt(); - new npc_trapped_mammoth_calf(); - new npc_magmoth_crusher(); - new npc_seaforium_depth_charge(); - new npc_valiance_keep_cannoneer(); - new npc_warmage_coldarra(); - new npc_hidden_cultist(); -} diff --git a/src/server/scripts/Northrend/crystalsong_forest.cpp b/src/server/scripts/Northrend/crystalsong_forest.cpp deleted file mode 100644 index d12b5176b15..00000000000 --- a/src/server/scripts/Northrend/crystalsong_forest.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* Script Data Start -SDName: CrystalSongForest -SDAuthor: Malcrom -SD%Complete: 99% -SDComment: -SDCategory: CrystalsongForest -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "Player.h" - -/******************************************************* - * npc_warmage_violetstand - *******************************************************/ - -enum Spells -{ - SPELL_TRANSITUS_SHIELD_BEAM = 48310 -}; - -enum NPCs -{ - NPC_TRANSITUS_SHIELD_DUMMY = 27306, - NPC_WARMAGE_SARINA = 32369, - NPC_WARMAGE_HALISTER = 32371, - NPC_WARMAGE_ILSUDRIA = 32372 -}; - -class npc_warmage_violetstand : public CreatureScript -{ -public: - npc_warmage_violetstand() : CreatureScript("npc_warmage_violetstand") { } - - struct npc_warmage_violetstandAI : public Scripted_NoMovementAI - { - npc_warmage_violetstandAI(Creature* creature) : Scripted_NoMovementAI(creature){} - - uint64 uiTargetGUID; - - void Reset() - { - uiTargetGUID = 0; - } - - void UpdateAI(const uint32 /*uiDiff*/) - { - if (me->IsNonMeleeSpellCasted(false)) - return; - - if (me->GetEntry() == NPC_WARMAGE_SARINA) - { - if (!uiTargetGUID) - { - std::list orbList; - GetCreatureListWithEntryInGrid(orbList, me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f); - if (!orbList.empty()) - { - for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) - { - if (Creature* pOrb = *itr) - { - if (pOrb->GetPositionY() < 1000) - { - uiTargetGUID = pOrb->GetGUID(); - break; - } - } - } - } - } - }else - { - if (!uiTargetGUID) - if (Creature* pOrb = GetClosestCreatureWithEntry(me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f)) - uiTargetGUID = pOrb->GetGUID(); - - } - - if (Creature* pOrb = me->GetCreature(*me, uiTargetGUID)) - DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); - - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_warmage_violetstandAI(creature); - } -}; - -void AddSC_crystalsong_forest() -{ - new npc_warmage_violetstand; -} diff --git a/src/server/scripts/Northrend/dalaran.cpp b/src/server/scripts/Northrend/dalaran.cpp deleted file mode 100644 index d16b6fe4588..00000000000 --- a/src/server/scripts/Northrend/dalaran.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* Script Data Start -SDName: Dalaran -SDAuthor: WarHead, MaXiMiUS -SD%Complete: 99% -SDComment: For what is 63990+63991? Same function but don't work correct... -SDCategory: Dalaran -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "WorldSession.h" - -/******************************************************* - * npc_mageguard_dalaran - *******************************************************/ - -enum Spells -{ - SPELL_TRESPASSER_A = 54028, - SPELL_TRESPASSER_H = 54029, - - SPELL_SUNREAVER_DISGUISE_FEMALE = 70973, - SPELL_SUNREAVER_DISGUISE_MALE = 70974, - SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971, - SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972, -}; - -enum NPCs // All outdoor guards are within 35.0f of these NPCs -{ - NPC_APPLEBOUGH_A = 29547, - NPC_SWEETBERRY_H = 29715, -}; - -class npc_mageguard_dalaran : public CreatureScript -{ -public: - npc_mageguard_dalaran() : CreatureScript("npc_mageguard_dalaran") { } - - struct npc_mageguard_dalaranAI : public Scripted_NoMovementAI - { - npc_mageguard_dalaranAI(Creature* creature) : Scripted_NoMovementAI(creature) - { - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true); - creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); - } - - void Reset(){} - - void EnterCombat(Unit* /*who*/){} - - void AttackStart(Unit* /*who*/){} - - void MoveInLineOfSight(Unit* who) - { - if (!who || !who->IsInWorld() || who->GetZoneId() != 4395) - return; - - if (!me->IsWithinDist(who, 65.0f, false)) - return; - - Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself(); - - if (!player || player->isGameMaster() || player->IsBeingTeleported() || - // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass - player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) || - player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE)) - return; - - switch (me->GetEntry()) - { - case 29254: - if (player->GetTeam() == HORDE) // Horde unit found in Alliance area - { - if (GetClosestCreatureWithEntry(me, NPC_APPLEBOUGH_A, 32.0f)) - { - if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me - DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out - } - else // In my line of sight, and "indoors" - DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out - } - break; - case 29255: - if (player->GetTeam() == ALLIANCE) // Alliance unit found in Horde area - { - if (GetClosestCreatureWithEntry(me, NPC_SWEETBERRY_H, 32.0f)) - { - if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me - DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out - } - else // In my line of sight, and "indoors" - DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out - } - break; - } - me->SetOrientation(me->GetHomePosition().GetOrientation()); - return; - } - - void UpdateAI(const uint32 /*diff*/){} - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_mageguard_dalaranAI(creature); - } -}; - -/*###### -## npc_hira_snowdawn -######*/ - -enum eHiraSnowdawn -{ - SPELL_COLD_WEATHER_FLYING = 54197 -}; - -#define GOSSIP_TEXT_TRAIN_HIRA "I seek training to ride a steed." - -class npc_hira_snowdawn : public CreatureScript -{ -public: - npc_hira_snowdawn() : CreatureScript("npc_hira_snowdawn") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (!creature->isVendor() || !creature->isTrainer()) - return false; - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_TRAIN_HIRA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - if (player->getLevel() >= 80 && player->HasSpell(SPELL_COLD_WEATHER_FLYING)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRAIN) - player->GetSession()->SendTrainerList(creature->GetGUID()); - - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } -}; - -void AddSC_dalaran() -{ - new npc_mageguard_dalaran; - new npc_hira_snowdawn; -} diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp deleted file mode 100644 index a8fb0215902..00000000000 --- a/src/server/scripts/Northrend/dragonblight.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Dragonblight -SD%Complete: 100 -SDComment: -SDCategory: Dragonblight -EndScriptData */ - -/* ContentData -npc_alexstrasza_wr_gate -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SpellScript.h" -#include "SpellAuraEffects.h" -#include "ScriptedEscortAI.h" -#include "Vehicle.h" -#include "CombatAI.h" -#include "Player.h" - -enum eEnums -{ - QUEST_RETURN_TO_AG_A = 12499, - QUEST_RETURN_TO_AG_H = 12500, - MOVIE_ID_GATES = 14 -}; - -#define GOSSIP_ITEM_WHAT_HAPPENED "Alexstrasza, can you show me what happened here?" - -class npc_alexstrasza_wr_gate : public CreatureScript -{ -public: - npc_alexstrasza_wr_gate() : CreatureScript("npc_alexstrasza_wr_gate") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestRewardStatus(QUEST_RETURN_TO_AG_A) || player->GetQuestRewardStatus(QUEST_RETURN_TO_AG_H)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WHAT_HAPPENED, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - player->SendMovieStart(MOVIE_ID_GATES); - } - - return true; - } -}; - -/*###### -## Quest Strengthen the Ancients (12096|12092) -######*/ - -enum StrengthenAncientsMisc -{ - SAY_WALKER_FRIENDLY = 0, - SAY_WALKER_ENEMY = 1, - SAY_LOTHALOR = 0, - - SPELL_CREATE_ITEM_BARK = 47550, - SPELL_CONFUSED = 47044, - - NPC_LOTHALOR = 26321, - - FACTION_WALKER_ENEMY = 14, -}; - -class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker -{ -public: - spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { } - - class spell_q12096_q12092_dummy_SpellScript : public SpellScript - { - PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - uint32 roll = rand() % 2; - - Creature* tree = GetHitCreature(); - Player* player = GetCaster()->ToPlayer(); - - if (!tree || !player) - return; - - tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - - if (roll == 1) // friendly version - { - tree->CastSpell(player, SPELL_CREATE_ITEM_BARK); - tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID()); - tree->DespawnOrUnsummon(1000); - } - else if (roll == 0) // enemy version - { - tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID()); - tree->setFaction(FACTION_WALKER_ENEMY); - tree->Attack(player, true); - } - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_q12096_q12092_dummy_SpellScript(); - } -}; - -class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers -{ -public: - spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { } - - class spell_q12096_q12092_bark_SpellScript : public SpellScript - { - PrepareSpellScript(spell_q12096_q12092_bark_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Creature* lothalor = GetHitCreature(); - if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR) - return; - - lothalor->AI()->Talk(SAY_LOTHALOR); - lothalor->RemoveAura(SPELL_CONFUSED); - lothalor->DespawnOrUnsummon(4000); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_q12096_q12092_bark_SpellScript(); - } -}; - -/*###### -## Quest: Defending Wyrmrest Temple ID: 12372 -######*/ - -enum WyrmDefenderEnum -{ - // Quest data - QUEST_DEFENDING_WYRMREST_TEMPLE = 12372, - GOSSIP_TEXTID_DEF1 = 12899, - - // Gossip data - GOSSIP_TEXTID_DEF2 = 12900, - - // Spells data - SPELL_CHARACTER_SCRIPT = 49213, - SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE = 52421, // ID - 52421 Wyrmrest Defender: On Low Health Boss Emote to Controller - Random /self/ - SPELL_RENEW = 49263, // casted to heal drakes - SPELL_WYRMREST_DEFENDER_MOUNT = 49256, - - // Texts data - WHISPER_MOUNTED = 0, - BOSS_EMOTE_ON_LOW_HEALTH = 2 -}; - -#define GOSSIP_ITEM_1 "We need to get into the fight. Are you ready?" - -class npc_wyrmrest_defender : public CreatureScript -{ - public: - npc_wyrmrest_defender() : CreatureScript("npc_wyrmrest_defender") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_DEFENDING_WYRMREST_TEMPLE) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF1, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF2, creature->GetGUID()); - // Makes player cast trigger spell for 49207 on self - player->CastSpell(player, SPELL_CHARACTER_SCRIPT, true); - // The gossip should not auto close - } - - return true; - } - - struct npc_wyrmrest_defenderAI : public VehicleAI - { - npc_wyrmrest_defenderAI(Creature* creature) : VehicleAI(creature) { } - - bool hpWarningReady; - bool renewRecoveryCanCheck; - - uint32 RenewRecoveryChecker; - - void Reset() - { - hpWarningReady = true; - renewRecoveryCanCheck = false; - - RenewRecoveryChecker = 0; - } - - void UpdateAI(uint32 const diff) - { - // Check system for Health Warning should happen first time whenever get under 30%, - // after it should be able to happen only after recovery of last renew is fully done (20 sec), - // next one used won't interfere - if (hpWarningReady && me->GetHealthPct() <= 30.0f) - { - me->CastSpell(me, SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE); - hpWarningReady = false; - } - - if (renewRecoveryCanCheck) - { - if (RenewRecoveryChecker <= diff) - { - renewRecoveryCanCheck = false; - hpWarningReady = true; - } - else RenewRecoveryChecker -= diff; - } - } - - void SpellHit(Unit* /*caster*/, SpellInfo const* spell) - { - switch (spell->Id) - { - case SPELL_WYRMREST_DEFENDER_MOUNT: - Talk(WHISPER_MOUNTED, me->GetCharmerOrOwnerGUID()); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); - break; - // Both below are for checking low hp warning - case SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE: - Talk(BOSS_EMOTE_ON_LOW_HEALTH, me->GetCharmerOrOwnerGUID()); - break; - case SPELL_RENEW: - if (!hpWarningReady && RenewRecoveryChecker <= 100) - { - RenewRecoveryChecker = 20000; - } - renewRecoveryCanCheck = true; - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_wyrmrest_defenderAI(creature); - } -}; - -void AddSC_dragonblight() -{ - new npc_alexstrasza_wr_gate; - new spell_q12096_q12092_dummy; - new spell_q12096_q12092_bark; - new npc_wyrmrest_defender; -} diff --git a/src/server/scripts/Northrend/grizzly_hills.cpp b/src/server/scripts/Northrend/grizzly_hills.cpp deleted file mode 100644 index fe1f561071c..00000000000 --- a/src/server/scripts/Northrend/grizzly_hills.cpp +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "SpellInfo.h" -#include "CreatureTextMgr.h" - -/*###### -## Quest 12027: Mr. Floppy's Perilous Adventure -######*/ - -enum eFloppy -{ - NPC_MRFLOPPY = 26589, - NPC_HUNGRY_WORG = 26586, - NPC_RAVENOUS_WORG = 26590, //RWORG - NPC_EMILY = 26588, - - QUEST_PERILOUS_ADVENTURE = 12027, - - SPELL_MRFLOPPY = 47184, //vehicle aura - - SAY_WORGHAGGRO1 = 0, //Um... I think one of those wolves is back... - SAY_WORGHAGGRO2 = 1, //He's going for Mr. Floppy! - SAY_WORGRAGGRO3 = 2, //Oh, no! Look, it's another wolf, and it's a biiiiiig one! - SAY_WORGRAGGRO4 = 3, //He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta! - SAY_RANDOMAGGRO = 4, //There's a big meanie attacking Mr. Floppy! Help! - SAY_VICTORY1 = 5, //Let's get out of here before more wolves find us! - SAY_VICTORY2 = 6, //Don't go toward the light, Mr. Floppy! - SAY_VICTORY3 = 7, //Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy! - SAY_VICTORY4 = 8, //I think I see the camp! We're almost home, Mr. Floppy! Let's go! - TEXT_EMOTE_WP1 = 9, //Mr. Floppy revives - TEXT_EMOTE_AGGRO = 10, //The Ravenous Worg chomps down on Mr. Floppy - SAY_QUEST_ACCEPT = 11, //Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves! - SAY_QUEST_COMPLETE = 12 //Thank you for helping me get back to the camp. Go tell Walter that I'm safe now! -}; - -//emily -class npc_emily : public CreatureScript -{ -public: - npc_emily() : CreatureScript("npc_emily") { } - - struct npc_emilyAI : public npc_escortAI - { - npc_emilyAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 m_uiChatTimer; - - uint64 RWORGGUID; - uint64 MrfloppyGUID; - - bool Completed; - - void JustSummoned(Creature* summoned) - { - if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 50.0f)) - summoned->AI()->AttackStart(Mrfloppy); - else - summoned->AI()->AttackStart(me->getVictim()); - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 9: - if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f)) - MrfloppyGUID = Mrfloppy->GetGUID(); - break; - case 10: - if (Unit::GetCreature(*me, MrfloppyGUID)) - { - Talk(SAY_WORGHAGGRO1); - me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX()+5, me->GetPositionY()+2, me->GetPositionZ()+1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); - } - break; - case 11: - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - break; - case 17: - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - Talk(SAY_WORGRAGGRO3); - if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX()+10, me->GetPositionY()+8, me->GetPositionZ()+2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) - { - RWORG->setFaction(35); - RWORGGUID = RWORG->GetGUID(); - } - break; - case 18: - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - { - if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) - RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); - DoCast(Mrfloppy, SPELL_MRFLOPPY); - } - break; - case 19: - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - { - if (Mrfloppy->HasAura(SPELL_MRFLOPPY, 0)) - { - if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) - Mrfloppy->EnterVehicle(RWORG); - } - } - break; - case 20: - if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) - RWORG->HandleEmoteCommand(34); - break; - case 21: - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - { - if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) - { - RWORG->Kill(Mrfloppy); - Mrfloppy->ExitVehicle(); - RWORG->setFaction(14); - RWORG->GetMotionMaster()->MovePoint(0, RWORG->GetPositionX()+10, RWORG->GetPositionY()+80, RWORG->GetPositionZ()); - Talk(SAY_VICTORY2); - } - } - break; - case 22: - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - { - if (Mrfloppy->isDead()) - { - if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) - RWORG->DisappearAndDie(); - me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); - Mrfloppy->setDeathState(ALIVE); - Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - Talk(SAY_VICTORY3); - } - } - break; - case 24: - if (player) - { - Completed = true; - player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me); - Talk(SAY_QUEST_COMPLETE, player->GetGUID()); - } - me->SetWalk(false); - break; - case 25: - Talk(SAY_VICTORY4); - break; - case 27: - me->DisappearAndDie(); - if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) - Mrfloppy->DisappearAndDie(); - break; - } - } - - void EnterCombat(Unit* /*Who*/) - { - Talk(SAY_RANDOMAGGRO); - } - - void Reset() - { - m_uiChatTimer = 4000; - MrfloppyGUID = 0; - RWORGGUID = 0; - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (m_uiChatTimer <= uiDiff) - m_uiChatTimer = 12000; - else - m_uiChatTimer -= uiDiff; - } - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_PERILOUS_ADVENTURE) - { - creature->AI()->Talk(SAY_QUEST_ACCEPT); - if (Creature* Mrfloppy = GetClosestCreatureWithEntry(creature, NPC_MRFLOPPY, 180.0f)) - Mrfloppy->GetMotionMaster()->MoveFollow(creature, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_emily::npc_emilyAI, (creature->AI()))) - pEscortAI->Start(true, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_emilyAI(creature); - } -}; - -//mrfloppy -class npc_mrfloppy : public CreatureScript -{ -public: - npc_mrfloppy() : CreatureScript("npc_mrfloppy") { } - - struct npc_mrfloppyAI : public ScriptedAI - { - npc_mrfloppyAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 EmilyGUID; - uint64 RWORGGUID; - uint64 HWORGGUID; - - void Reset() {} - - void EnterCombat(Unit* Who) - { - if (Creature* Emily = GetClosestCreatureWithEntry(me, NPC_EMILY, 50.0f)) - { - switch (Who->GetEntry()) - { - case NPC_HUNGRY_WORG: - Emily->AI()->Talk(SAY_WORGHAGGRO2); - break; - case NPC_RAVENOUS_WORG: - Emily->AI()->Talk(SAY_WORGRAGGRO4); - break; - default: - Emily->AI()->Talk(SAY_RANDOMAGGRO); - } - } - } - - void EnterEvadeMode() {} - - void MoveInLineOfSight(Unit* /*who*/) {} - - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_mrfloppyAI(creature); - } -}; - -// Outhouse Bunny - -enum eOuthouseBunny -{ - SPELL_OUTHOUSE_GROANS = 48382, - SPELL_CAMERA_SHAKE = 47533, - SPELL_DUST_FIELD = 48329 -}; - -enum eSounds -{ - SOUND_FEMALE = 12671, - SOUND_MALE = 12670 -}; - -class npc_outhouse_bunny : public CreatureScript -{ -public: - npc_outhouse_bunny() : CreatureScript("npc_outhouse_bunny") { } - - struct npc_outhouse_bunnyAI : public ScriptedAI - { - npc_outhouse_bunnyAI(Creature* creature) : ScriptedAI(creature) {} - - uint8 m_counter; - uint8 m_gender; - - void Reset() - { - m_counter = 0; - m_gender = 0; - } - - void SetData(uint32 uiType, uint32 uiData) - { - if (uiType == 1) - m_gender = uiData; - } - - void SpellHit(Unit* pCaster, const SpellInfo* pSpell) - { - if (pSpell->Id == SPELL_OUTHOUSE_GROANS) - { - ++m_counter; - if (m_counter < 5) - DoCast(pCaster, SPELL_CAMERA_SHAKE, true); - else - m_counter = 0; - DoCast(me, SPELL_DUST_FIELD, true); - switch (m_gender) - { - case GENDER_FEMALE: - DoPlaySoundToSet(me, SOUND_FEMALE); - break; - - case GENDER_MALE: - DoPlaySoundToSet(me, SOUND_MALE); - break; - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_outhouse_bunnyAI(creature); - } -}; - -// Tallhorn Stage - -enum etallhornstage -{ - OBJECT_HAUNCH = 188665 -}; - -class npc_tallhorn_stag : public CreatureScript -{ -public: - npc_tallhorn_stag() : CreatureScript("npc_tallhorn_stag") { } - - struct npc_tallhorn_stagAI : public ScriptedAI - { - npc_tallhorn_stagAI(Creature* creature) : ScriptedAI(creature) {} - - uint8 m_uiPhase; - - void Reset() - { - m_uiPhase = 1; - } - - void UpdateAI(const uint32 /*uiDiff*/) - { - if (m_uiPhase == 1) - { - if (me->FindNearestGameObject(OBJECT_HAUNCH, 2.0f)) - { - me->SetStandState(UNIT_STAND_STATE_DEAD); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); - } - m_uiPhase = 0; - } - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_tallhorn_stagAI(creature); - } -}; - -// Amberpine Woodsman - -enum eamberpinewoodsman -{ - TALLHORN_STAG = 26363 -}; - -class npc_amberpine_woodsman : public CreatureScript -{ -public: - npc_amberpine_woodsman() : CreatureScript("npc_amberpine_woodsman") { } - - struct npc_amberpine_woodsmanAI : public ScriptedAI - { - npc_amberpine_woodsmanAI(Creature* creature) : ScriptedAI(creature) {} - - uint8 m_uiPhase; - uint32 m_uiTimer; - - void Reset() - { - m_uiTimer = 0; - m_uiPhase = 1; - } - - void UpdateAI(const uint32 uiDiff) - { - // call this each update tick? - if (me->FindNearestCreature(TALLHORN_STAG, 0.2f)) - { - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); - } - else - if (m_uiPhase) - { - if (m_uiTimer <= uiDiff) - { - switch (m_uiPhase) - { - case 1: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LOOT); - m_uiTimer = 3000; - m_uiPhase = 2; - break; - case 2: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H); - m_uiTimer = 4000; - m_uiPhase = 1; - break; - } - } - else - m_uiTimer -= uiDiff; - } - ScriptedAI::UpdateAI(uiDiff); - - UpdateVictim(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_amberpine_woodsmanAI(creature); - } -}; -/*###### -## Quest 12288: Overwhelmed! -######*/ - -enum eSkirmisher -{ - SPELL_RENEW_SKIRMISHER = 48812, - CREDIT_NPC = 27466, - - RANDOM_SAY = 0, -}; - -class npc_wounded_skirmisher : public CreatureScript -{ -public: - npc_wounded_skirmisher() : CreatureScript("npc_wounded_skirmisher") { } - - struct npc_wounded_skirmisherAI : public ScriptedAI - { - npc_wounded_skirmisherAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 uiPlayerGUID; - - uint32 DespawnTimer; - - void Reset() - { - DespawnTimer = 5000; - uiPlayerGUID = 0; - } - - void MovementInform(uint32, uint32 id) - { - if (id == 1) - me->DespawnOrUnsummon(DespawnTimer); - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id == SPELL_RENEW_SKIRMISHER && caster->GetTypeId() == TYPEID_PLAYER - && caster->ToPlayer()->GetQuestStatus(12288) == QUEST_STATUS_INCOMPLETE) - { - caster->ToPlayer()->KilledMonsterCredit(CREDIT_NPC, 0); - sCreatureTextMgr->SendChat(me, RANDOM_SAY, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, caster->ToPlayer()); - if (me->IsStandState()) - me->GetMotionMaster()->MovePoint(1, me->GetPositionX()+7, me->GetPositionY()+7, me->GetPositionZ()); - else - { - me->SetStandState(UNIT_STAND_STATE_STAND); - me->DespawnOrUnsummon(DespawnTimer); - } - } - } - - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_wounded_skirmisherAI(creature); - } -}; - -/*Lightning Sentry - if you kill it when you have your Minion with you, you will get a quest credit*/ -enum eSentry -{ - QUEST_OR_MAYBE_WE_DONT_A = 12138, - QUEST_OR_MAYBE_WE_DONT_H = 12198, - - NPC_LIGHTNING_SENTRY = 26407, - NPC_WAR_GOLEM = 27017, - - SPELL_CHARGED_SENTRY_TOTEM = 52703, -}; - -class npc_lightning_sentry : public CreatureScript -{ -public: - npc_lightning_sentry() : CreatureScript("npc_lightning_sentry") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_lightning_sentryAI(creature); - } - - struct npc_lightning_sentryAI : public ScriptedAI - { - npc_lightning_sentryAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 uiChargedSentryTotem; - - void Reset() - { - uiChargedSentryTotem = urand(10000, 12000); - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - - if (uiChargedSentryTotem <= uiDiff) - { - DoCast(SPELL_CHARGED_SENTRY_TOTEM); - uiChargedSentryTotem = urand(10000, 12000); - } - else - uiChargedSentryTotem -= uiDiff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - if (killer->ToPlayer() && killer->ToPlayer()->GetTypeId() == TYPEID_PLAYER) - { - if (me->FindNearestCreature(NPC_WAR_GOLEM, 10.0f, true)) - { - if (killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_A) == QUEST_STATUS_INCOMPLETE || - killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_H) == QUEST_STATUS_INCOMPLETE) - killer->ToPlayer()->KilledMonsterCredit(NPC_WAR_GOLEM, 0); - } - } - } - }; -}; - -/*Venture co. Straggler - when you cast Smoke Bomb, he will yell and run away*/ -enum eSmokeEmOut -{ - SAY_SEO = 0, - QUEST_SMOKE_EM_OUT_A = 12323, - QUEST_SMOKE_EM_OUT_H = 12324, - SPELL_SMOKE_BOMB = 49075, - SPELL_CHOP = 43410, - SPELL_VENTURE_STRAGGLER_CREDIT = 49093, -}; - -class npc_venture_co_straggler : public CreatureScript -{ - public: - npc_venture_co_straggler() : CreatureScript("npc_venture_co_straggler") { } - - struct npc_venture_co_stragglerAI : public ScriptedAI - { - npc_venture_co_stragglerAI(Creature* creature) : ScriptedAI(creature) { } - - uint64 uiPlayerGUID; - uint32 uiRunAwayTimer; - uint32 uiTimer; - uint32 uiChopTimer; - - void Reset() - { - uiPlayerGUID = 0; - uiTimer = 0; - uiRunAwayTimer = 0; - uiChopTimer = urand(10000, 12500); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_AGGRESSIVE); - } - - void UpdateAI(const uint32 uiDiff) - { - if (uiPlayerGUID && uiRunAwayTimer <= uiDiff) - { - if (Player* player = Unit::GetPlayer(*me, uiPlayerGUID)) - { - switch (uiTimer) - { - case 0: - DoCast(player, SPELL_VENTURE_STRAGGLER_CREDIT); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()+7, me->GetPositionZ()); - uiRunAwayTimer = 2500; - ++uiTimer; - break; - case 1: - Talk(SAY_SEO); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()-5, me->GetPositionZ()); - uiRunAwayTimer = 2500; - ++uiTimer; - break; - case 2: - me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-5, me->GetPositionY()-5, me->GetPositionZ()); - uiRunAwayTimer = 2500; - ++uiTimer; - break; - case 3: - me->DisappearAndDie(); - uiTimer = 0; - break; - } - } - } - else if (uiRunAwayTimer) - uiRunAwayTimer -= uiDiff; - - if (!UpdateVictim()) - return; - - if (uiChopTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_CHOP); - uiChopTimer = urand(10000, 12000); - } - else - uiChopTimer -= uiDiff; - - DoMeleeAttackIfReady(); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) - { - if (spell->Id == SPELL_SMOKE_BOMB && caster->GetTypeId() == TYPEID_PLAYER) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_PASSIVE); - me->CombatStop(false); - uiPlayerGUID = caster->GetGUID(); - uiRunAwayTimer = 3500; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_venture_co_stragglerAI(creature); - } -}; - -void AddSC_grizzly_hills() -{ - new npc_emily(); - new npc_mrfloppy(); - new npc_outhouse_bunny(); - new npc_tallhorn_stag(); - new npc_amberpine_woodsman(); - new npc_wounded_skirmisher(); - new npc_lightning_sentry(); - new npc_venture_co_straggler(); -} diff --git a/src/server/scripts/Northrend/howling_fjord.cpp b/src/server/scripts/Northrend/howling_fjord.cpp deleted file mode 100644 index ff4d8ec7a79..00000000000 --- a/src/server/scripts/Northrend/howling_fjord.cpp +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* ScriptData -SDName: Sholazar_Basin -SD%Complete: 100 -SDComment: Quest support: 11253, 11241. -SDCategory: howling_fjord -EndScriptData */ - -/* ContentData -npc_plaguehound_tracker -npc_apothecary_hanes -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_apothecary_hanes -######*/ -enum Entries -{ - NPC_APOTHECARY_HANES = 23784, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775, - NPC_HANES_FIRE_TRIGGER = 23968, - QUEST_TRAIL_OF_FIRE = 11241, - SPELL_COSMETIC_LOW_POLY_FIRE = 56274 -}; - -class npc_apothecary_hanes : public CreatureScript -{ -public: - npc_apothecary_hanes() : CreatureScript("npc_apothecary_hanes") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_TRAIL_OF_FIRE) - { - switch (player->GetTeam()) - { - case ALLIANCE: - creature->setFaction(FACTION_ESCORTEE_A); - break; - case HORDE: - creature->setFaction(FACTION_ESCORTEE_H); - break; - } - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - } - return true; - } - - struct npc_Apothecary_HanesAI : public npc_escortAI - { - npc_Apothecary_HanesAI(Creature* creature) : npc_escortAI(creature){} - uint32 PotTimer; - - void Reset() - { - SetDespawnAtFar(false); - PotTimer = 10000; //10 sec cooldown on potion - } - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_TRAIL_OF_FIRE); - } - - void UpdateEscortAI(const uint32 diff) - { - if (HealthBelowPct(75)) - { - if (PotTimer <= diff) - { - DoCast(me, 17534, true); - PotTimer = 10000; - } else PotTimer -= diff; - } - if (GetAttack() && UpdateVictim()) - DoMeleeAttackIfReady(); - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 1: - me->SetReactState(REACT_AGGRESSIVE); - SetRun(true); - break; - case 23: - player->GroupEventHappens(QUEST_TRAIL_OF_FIRE, me); - me->DespawnOrUnsummon(); - break; - case 5: - if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) - Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); - SetRun(false); - break; - case 6: - if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) - Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); - SetRun(true); - break; - case 8: - if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) - Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); - SetRun(false); - break; - case 9: - if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) - Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); - break; - case 10: - SetRun(true); - break; - case 13: - SetRun(false); - break; - case 14: - if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) - Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); - SetRun(true); - break; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_Apothecary_HanesAI(creature); - } -}; - -/*###### -## npc_plaguehound_tracker -######*/ - -enum ePlaguehound -{ - QUEST_SNIFF_OUT_ENEMY = 11253 -}; - -class npc_plaguehound_tracker : public CreatureScript -{ -public: - npc_plaguehound_tracker() : CreatureScript("npc_plaguehound_tracker") { } - - struct npc_plaguehound_trackerAI : public npc_escortAI - { - npc_plaguehound_trackerAI(Creature* creature) : npc_escortAI(creature) { } - - void Reset() - { - uint64 summonerGUID = 0; - - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (summoner->GetTypeId() == TYPEID_PLAYER) - summonerGUID = summoner->GetGUID(); - - if (!summonerGUID) - return; - - me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); - Start(false, false, summonerGUID); - } - - void WaypointReached(uint32 waypointId) - { - if (waypointId != 26) - return; - - me->DespawnOrUnsummon(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_plaguehound_trackerAI(creature); - } -}; - -/*###### -## npc_razael_and_lyana -######*/ - -#define GOSSIP_RAZAEL_REPORT "High Executor Anselm wants a report on the situation." -#define GOSSIP_LYANA_REPORT "High Executor Anselm requests your report." - -enum eRazael -{ - QUEST_REPORTS_FROM_THE_FIELD = 11221, - NPC_RAZAEL = 23998, - NPC_LYANA = 23778, - GOSSIP_TEXTID_RAZAEL1 = 11562, - GOSSIP_TEXTID_RAZAEL2 = 11564, - GOSSIP_TEXTID_LYANA1 = 11586, - GOSSIP_TEXTID_LYANA2 = 11588 -}; - -class npc_razael_and_lyana : public CreatureScript -{ -public: - npc_razael_and_lyana() : CreatureScript("npc_razael_and_lyana") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_REPORTS_FROM_THE_FIELD) == QUEST_STATUS_INCOMPLETE) - switch (creature->GetEntry()) - { - case NPC_RAZAEL: - if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_RAZAEL)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_RAZAEL_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL1, creature->GetGUID()); - return true; - } - break; - case NPC_LYANA: - if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_LYANA)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LYANA_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA1, creature->GetGUID()); - return true; - } - break; - } - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL2, creature->GetGUID()); - player->TalkedToCreature(NPC_RAZAEL, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA2, creature->GetGUID()); - player->TalkedToCreature(NPC_LYANA, creature->GetGUID()); - break; - } - return true; - } -}; - -/*###### -## npc_mcgoyver -######*/ - -#define GOSSIP_ITEM_MG_I "Walt sent me to pick up some dark iron ingots." -#define GOSSIP_ITEM_MG_II "Yarp." - -enum eMcGoyver -{ - QUEST_WE_CAN_REBUILD_IT = 11483, - - SPELL_CREATURE_DARK_IRON_INGOTS = 44512, - SPELL_TAXI_EXPLORERS_LEAGUE = 44280, - - GOSSIP_TEXTID_MCGOYVER = 12193 -}; - -class npc_mcgoyver : public CreatureScript -{ -public: - npc_mcgoyver() : CreatureScript("npc_mcgoyver") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_WE_CAN_REBUILD_IT) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_II, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, creature->GetGUID()); - player->CastSpell(player, SPELL_CREATURE_DARK_IRON_INGOTS, true); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->CastSpell(player, SPELL_TAXI_EXPLORERS_LEAGUE, true); - player->CLOSE_GOSSIP_MENU(); - break; - } - return true; - } -}; - -/*###### -## npc_daegarn -######*/ - -enum eDaegarnn -{ - QUEST_DEFEAT_AT_RING = 11300, - - NPC_FIRJUS = 24213, - NPC_JLARBORN = 24215, - NPC_YOROS = 24214, - NPC_OLUF = 23931, - - NPC_PRISONER_1 = 24253, // looks the same but has different abilities - NPC_PRISONER_2 = 24254, - NPC_PRISONER_3 = 24255, -}; - -static float afSummon[] = {838.81f, -4678.06f, -94.182f}; -static float afCenter[] = {801.88f, -4721.87f, -96.143f}; - -class npc_daegarn : public CreatureScript -{ -public: - npc_daegarn() : CreatureScript("npc_daegarn") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_DEFEAT_AT_RING) - { - if (npc_daegarnAI* pDaegarnAI = CAST_AI(npc_daegarn::npc_daegarnAI, creature->AI())) - pDaegarnAI->StartEvent(player->GetGUID()); - } - - return true; - } - - // TODO: make prisoners help (unclear if summoned or using npc's from surrounding cages (summon inside small cages?)) - struct npc_daegarnAI : public ScriptedAI - { - npc_daegarnAI(Creature* creature) : ScriptedAI(creature) { } - - bool bEventInProgress; - uint64 uiPlayerGUID; - - void Reset() - { - bEventInProgress = false; - uiPlayerGUID = 0; - } - - void StartEvent(uint64 uiGUID) - { - if (bEventInProgress) - return; - - uiPlayerGUID = uiGUID; - - SummonGladiator(NPC_FIRJUS); - } - - void JustSummoned(Creature* summon) - { - if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) - { - if (player->isAlive()) - { - summon->SetWalk(false); - summon->GetMotionMaster()->MovePoint(0, afCenter[0], afCenter[1], afCenter[2]); - summon->AI()->AttackStart(player); - return; - } - } - - Reset(); - } - - void SummonGladiator(uint32 uiEntry) - { - me->SummonCreature(uiEntry, afSummon[0], afSummon[1], afSummon[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30*IN_MILLISECONDS); - } - - void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) - { - uint32 uiEntry = 0; - - // will eventually reset the event if something goes wrong - switch (summoned->GetEntry()) - { - case NPC_FIRJUS: uiEntry = NPC_JLARBORN; break; - case NPC_JLARBORN: uiEntry = NPC_YOROS; break; - case NPC_YOROS: uiEntry = NPC_OLUF; break; - case NPC_OLUF: Reset(); return; - } - - SummonGladiator(uiEntry); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_daegarnAI(creature); - } -}; - -void AddSC_howling_fjord() -{ - new npc_apothecary_hanes; - new npc_plaguehound_tracker; - new npc_razael_and_lyana; - new npc_mcgoyver; - new npc_daegarn; - } diff --git a/src/server/scripts/Northrend/icecrown.cpp b/src/server/scripts/Northrend/icecrown.cpp deleted file mode 100644 index 2ec5a3e8164..00000000000 --- a/src/server/scripts/Northrend/icecrown.cpp +++ /dev/null @@ -1,878 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Icecrown -SD%Complete: 100 -SDComment: Quest support: 12807 -SDCategory: Icecrown -EndScriptData */ - -/* ContentData -npc_arete -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SpellAuras.h" -#include "Player.h" - -/*###### -## npc_arete -######*/ - -#define GOSSIP_ARETE_ITEM1 "Lord-Commander, I would hear your tale." -#define GOSSIP_ARETE_ITEM2 "" -#define GOSSIP_ARETE_ITEM3 "I thought that they now called themselves the Scarlet Onslaught?" -#define GOSSIP_ARETE_ITEM4 "Where did the grand admiral go?" -#define GOSSIP_ARETE_ITEM5 "That's fine. When do I start?" -#define GOSSIP_ARETE_ITEM6 "Let's finish this!" -#define GOSSIP_ARETE_ITEM7 "That's quite a tale, Lord-Commander." - -enum eArete -{ - GOSSIP_TEXTID_ARETE1 = 13525, - GOSSIP_TEXTID_ARETE2 = 13526, - GOSSIP_TEXTID_ARETE3 = 13527, - GOSSIP_TEXTID_ARETE4 = 13528, - GOSSIP_TEXTID_ARETE5 = 13529, - GOSSIP_TEXTID_ARETE6 = 13530, - GOSSIP_TEXTID_ARETE7 = 13531, - - QUEST_THE_STORY_THUS_FAR = 12807 -}; - -class npc_arete : public CreatureScript -{ -public: - npc_arete() : CreatureScript("npc_arete") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_THE_STORY_THUS_FAR) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE1, creature->GetGUID()); - return true; - } - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE3, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE4, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE5, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE6, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE7, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(QUEST_THE_STORY_THUS_FAR); - break; - } - - return true; - } -}; - -/*###### -## npc_squire_david -######*/ - -enum eSquireDavid -{ - QUEST_THE_ASPIRANT_S_CHALLENGE_H = 13680, - QUEST_THE_ASPIRANT_S_CHALLENGE_A = 13679, - - NPC_ARGENT_VALIANT = 33448, - - GOSSIP_TEXTID_SQUIRE = 14407 -}; - -#define GOSSIP_SQUIRE_ITEM_1 "I am ready to fight!" -#define GOSSIP_SQUIRE_ITEM_2 "How do the Argent Crusader raiders fight?" - -class npc_squire_david : public CreatureScript -{ -public: - npc_squire_david() : CreatureScript("npc_squire_david") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_THE_ASPIRANT_S_CHALLENGE_H) == QUEST_STATUS_INCOMPLETE || - player->GetQuestStatus(QUEST_THE_ASPIRANT_S_CHALLENGE_A) == QUEST_STATUS_INCOMPLETE)//We need more info about it. - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SQUIRE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SQUIRE_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - } - - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_SQUIRE, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->SummonCreature(NPC_ARGENT_VALIANT, 8575.451f, 952.472f, 547.554f, 0.38f); - } - return true; - } -}; - -/*###### -## npc_argent_valiant -######*/ - -enum eArgentValiant -{ - SPELL_CHARGE = 63010, - SPELL_SHIELD_BREAKER = 65147, - SPELL_KILL_CREDIT = 63049 -}; - -class npc_argent_valiant : public CreatureScript -{ -public: - npc_argent_valiant() : CreatureScript("npc_argent_valiant") { } - - struct npc_argent_valiantAI : public ScriptedAI - { - npc_argent_valiantAI(Creature* creature) : ScriptedAI(creature) - { - creature->GetMotionMaster()->MovePoint(0, 8599.258f, 963.951f, 547.553f); - creature->setFaction(35); //wrong faction in db? - } - - uint32 uiChargeTimer; - uint32 uiShieldBreakerTimer; - - void Reset() - { - uiChargeTimer = 7000; - uiShieldBreakerTimer = 10000; - } - - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - - me->setFaction(14); - } - - void DamageTaken(Unit* pDoneBy, uint32& uiDamage) - { - if (uiDamage > me->GetHealth() && pDoneBy->GetTypeId() == TYPEID_PLAYER) - { - uiDamage = 0; - pDoneBy->CastSpell(pDoneBy, SPELL_KILL_CREDIT, true); - me->setFaction(35); - me->DespawnOrUnsummon(5000); - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - EnterEvadeMode(); - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - - if (uiChargeTimer <= uiDiff) - { - DoCastVictim(SPELL_CHARGE); - uiChargeTimer = 7000; - } else uiChargeTimer -= uiDiff; - - if (uiShieldBreakerTimer <= uiDiff) - { - DoCastVictim(SPELL_SHIELD_BREAKER); - uiShieldBreakerTimer = 10000; - } else uiShieldBreakerTimer -= uiDiff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_argent_valiantAI(creature); - } -}; - -/*###### -## npc_guardian_pavilion -######*/ - -enum eGuardianPavilion -{ - SPELL_TRESPASSER_H = 63987, - AREA_SUNREAVER_PAVILION = 4676, - - AREA_SILVER_COVENANT_PAVILION = 4677, - SPELL_TRESPASSER_A = 63986, -}; - -class npc_guardian_pavilion : public CreatureScript -{ -public: - npc_guardian_pavilion() : CreatureScript("npc_guardian_pavilion") { } - - struct npc_guardian_pavilionAI : public Scripted_NoMovementAI - { - npc_guardian_pavilionAI(Creature* creature) : Scripted_NoMovementAI(creature) {} - - void MoveInLineOfSight(Unit* who) - { - if (me->GetAreaId() != AREA_SUNREAVER_PAVILION && me->GetAreaId() != AREA_SILVER_COVENANT_PAVILION) - return; - - if (!who || who->GetTypeId() != TYPEID_PLAYER || !me->IsHostileTo(who) || !me->isInBackInMap(who, 5.0f)) - return; - - if (who->HasAura(SPELL_TRESPASSER_H) || who->HasAura(SPELL_TRESPASSER_A)) - return; - - if (who->ToPlayer()->GetTeamId() == TEAM_ALLIANCE) - who->CastSpell(who, SPELL_TRESPASSER_H, true); - else - who->CastSpell(who, SPELL_TRESPASSER_A, true); - - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_guardian_pavilionAI(creature); - } -}; - -/*###### -## npc_vereth_the_cunning -######*/ - -enum eVerethTheCunning -{ - NPC_GEIST_RETURN_BUNNY_KC = 31049, - NPC_LITHE_STALKER = 30894, - SPELL_SUBDUED_LITHE_STALKER = 58151, -}; - -class npc_vereth_the_cunning : public CreatureScript -{ -public: - npc_vereth_the_cunning() : CreatureScript("npc_vereth_the_cunning") { } - - struct npc_vereth_the_cunningAI : public ScriptedAI - { - npc_vereth_the_cunningAI(Creature* creature) : ScriptedAI(creature) {} - - void MoveInLineOfSight(Unit* who) - { - ScriptedAI::MoveInLineOfSight(who); - - if (who->GetEntry() == NPC_LITHE_STALKER && me->IsWithinDistInMap(who, 10.0f)) - { - if (Unit* owner = who->GetCharmer()) - { - if (who->HasAura(SPELL_SUBDUED_LITHE_STALKER)) - { - owner->ToPlayer()->KilledMonsterCredit(NPC_GEIST_RETURN_BUNNY_KC, 0); - who->ToCreature()->DisappearAndDie(); - - } - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_vereth_the_cunningAI(creature); - } -}; - -/*###### -* npc_tournament_training_dummy -######*/ -enum TournamentDummy -{ - NPC_CHARGE_TARGET = 33272, - NPC_MELEE_TARGET = 33229, - NPC_RANGED_TARGET = 33243, - - SPELL_CHARGE_CREDIT = 62658, - SPELL_MELEE_CREDIT = 62672, - SPELL_RANGED_CREDIT = 62673, - - SPELL_PLAYER_THRUST = 62544, - SPELL_PLAYER_BREAK_SHIELD = 62626, - SPELL_PLAYER_CHARGE = 62874, - - SPELL_RANGED_DEFEND = 62719, - SPELL_CHARGE_DEFEND = 64100, - SPELL_VULNERABLE = 62665, - - SPELL_COUNTERATTACK = 62709, - - EVENT_DUMMY_RECAST_DEFEND = 1, - EVENT_DUMMY_RESET = 2, -}; - -class npc_tournament_training_dummy : public CreatureScript -{ - public: - npc_tournament_training_dummy(): CreatureScript("npc_tournament_training_dummy"){} - - struct npc_tournament_training_dummyAI : Scripted_NoMovementAI - { - npc_tournament_training_dummyAI(Creature* creature) : Scripted_NoMovementAI(creature) {} - - EventMap events; - bool isVulnerable; - - void Reset() - { - me->SetControlled(true, UNIT_STATE_STUNNED); - me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); - isVulnerable = false; - - // Cast Defend spells to max stack size - switch (me->GetEntry()) - { - case NPC_CHARGE_TARGET: - DoCast(SPELL_CHARGE_DEFEND); - break; - case NPC_RANGED_TARGET: - me->CastCustomSpell(SPELL_RANGED_DEFEND, SPELLVALUE_AURA_STACK, 3, me); - break; - } - - events.Reset(); - events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000); - } - - void EnterEvadeMode() - { - if (!_EnterEvadeMode()) - return; - - Reset(); - } - - void DamageTaken(Unit* /*attacker*/, uint32& damage) - { - damage = 0; - events.RescheduleEvent(EVENT_DUMMY_RESET, 10000); - } - - void SpellHit(Unit* caster, SpellInfo const* spell) - { - switch (me->GetEntry()) - { - case NPC_CHARGE_TARGET: - if (spell->Id == SPELL_PLAYER_CHARGE) - if (isVulnerable) - DoCast(caster, SPELL_CHARGE_CREDIT, true); - break; - case NPC_MELEE_TARGET: - if (spell->Id == SPELL_PLAYER_THRUST) - { - DoCast(caster, SPELL_MELEE_CREDIT, true); - - if (Unit* target = caster->GetVehicleBase()) - DoCast(target, SPELL_COUNTERATTACK, true); - } - break; - case NPC_RANGED_TARGET: - if (spell->Id == SPELL_PLAYER_BREAK_SHIELD) - if (isVulnerable) - DoCast(caster, SPELL_RANGED_CREDIT, true); - break; - } - - if (spell->Id == SPELL_PLAYER_BREAK_SHIELD) - if (!me->HasAura(SPELL_CHARGE_DEFEND) && !me->HasAura(SPELL_RANGED_DEFEND)) - isVulnerable = true; - } - - void UpdateAI(uint32 const diff) - { - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_DUMMY_RECAST_DEFEND: - switch (me->GetEntry()) - { - case NPC_CHARGE_TARGET: - { - if (!me->HasAura(SPELL_CHARGE_DEFEND)) - DoCast(SPELL_CHARGE_DEFEND); - break; - } - case NPC_RANGED_TARGET: - { - Aura* defend = me->GetAura(SPELL_RANGED_DEFEND); - if (!defend || defend->GetStackAmount() < 3 || defend->GetDuration() <= 8000) - DoCast(SPELL_RANGED_DEFEND); - break; - } - } - isVulnerable = false; - events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000); - break; - case EVENT_DUMMY_RESET: - if (UpdateVictim()) - { - EnterEvadeMode(); - events.ScheduleEvent(EVENT_DUMMY_RESET, 10000); - } - break; - } - - if (!UpdateVictim()) - return; - - if (!me->HasUnitState(UNIT_STATE_STUNNED)) - me->SetControlled(true, UNIT_STATE_STUNNED); - } - - void MoveInLineOfSight(Unit* /*who*/){} - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_tournament_training_dummyAI(creature); - } - -}; - -// Battle for Crusaders' Pinnacle -enum BlessedBanner -{ - SPELL_BLESSING_OF_THE_CRUSADE = 58026, - SPELL_THREAT_PULSE = 58113, - SPELL_CRUSADERS_SPIRE_VICTORY = 58084, - SPELL_TORCH = 58121, - - NPC_BLESSED_BANNER = 30891, - NPC_CRUSADER_LORD_DALFORS = 31003, - NPC_ARGENT_BATTLE_PRIEST = 30919, - NPC_ARGENT_MASON = 30900, - NPC_REANIMATED_CAPTAIN = 30986, - NPC_SCOURGE_DRUDGE = 30984, - NPC_HIDEOUS_PLAGEBRINGER = 30987, - NPC_HALOF_THE_DEATHBRINGER = 30989, - NPC_LK = 31013, - - BANNER_SAY = 0, // "The Blessed Banner of the Crusade has been planted.\n Defend the banner from all attackers!" - DALFORS_SAY_PRE_1 = 0, // "BY THE LIGHT! Those damned monsters! Look at what they've done to our people!" - DALFORS_SAY_PRE_2 = 1, // "Burn it down, boys. Burn it all down." - DALFORS_SAY_START = 2, // "Let 'em come. They'll pay for what they've done!" - DALFORS_YELL_FINISHED = 3, // "We've done it, lads! We've taken the pinnacle from the Scourge! Report to Father Gustav at once and tell him the good news! We're gonna get to buildin' and settin' up! Go!" - LK_TALK_1 = 0, // "Leave no survivors!" - LK_TALK_2 = 1, // "Cower before my terrible creations!" - LK_TALK_3 = 2, // "Feast my children! Feast upon the flesh of the living!" - LK_TALK_4 = 3, // "Lay down your arms and surrender your souls!" - - EVENT_SPAWN = 1, - EVENT_INTRO_1 = 2, - EVENT_INTRO_2 = 3, - EVENT_INTRO_3 = 4, - EVENT_MASON_ACTION = 5, - EVENT_START_FIGHT = 6, - EVENT_WAVE_SPAWN = 7, - EVENT_HALOF = 8, - EVENT_ENDED = 9, -}; - -Position const DalforsPos[3] = -{ - {6458.703f, 403.858f, 490.498f, 3.1205f}, // Dalfors spawn point - {6422.950f, 423.335f, 510.451f, 0.0f}, // Dalfors intro pos - {6426.343f, 420.515f, 508.650f, 0.0f}, // Dalfors fight pos -}; - -Position const Priest1Pos[2] = -{ - {6462.025f, 403.681f, 489.721f, 3.1007f}, // priest1 spawn point - {6421.480f, 423.576f, 510.781f, 5.7421f}, // priest1 intro pos -}; - -Position const Priest2Pos[2] = -{ - {6463.969f, 407.198f, 489.240f, 2.2689f}, // priest2 spawn point - {6419.778f, 421.404f, 510.972f, 5.7421f}, // priest2 intro pos -}; - -Position const Priest3Pos[2] = -{ - {6464.371f, 400.944f, 489.186f, 6.1610f}, // priest3 spawn point - {6423.516f, 425.782f, 510.774f, 5.7421f}, // priest3 intro pos -}; - -Position const Mason1Pos[3] = -{ - {6462.929f, 409.826f, 489.392f, 3.0968f}, // mason1 spawn point - {6428.163f, 421.960f, 508.297f, 0.0f}, // mason1 intro pos - {6414.335f, 454.904f, 511.395f, 2.8972f}, // mason1 action pos -}; - -Position const Mason2Pos[3] = -{ - {6462.650f, 405.670f, 489.576f, 2.9414f}, // mason2 spawn point - {6426.250f, 419.194f, 508.219f, 0.0f}, // mason2 intro pos - {6415.014f, 446.849f, 511.395f, 3.1241f}, // mason2 action pos -}; - -Position const Mason3Pos[3] = -{ - {6462.646f, 401.218f, 489.601f, 2.7864f}, // mason3 spawn point - {6423.855f, 416.598f, 508.305f, 0.0f}, // mason3 intro pos - {6417.070f, 438.824f, 511.395f, 3.6651f}, // mason3 action pos -}; - -class npc_blessed_banner : public CreatureScript -{ -public: - npc_blessed_banner() : CreatureScript("npc_blessed_banner") { } - - struct npc_blessed_bannerAI : public Scripted_NoMovementAI - { - npc_blessed_bannerAI(Creature* creature) : Scripted_NoMovementAI(creature) , Summons(me) - { - HalofSpawned = false; - PhaseCount = 0; - Summons.DespawnAll(); - } - - EventMap events; - - bool HalofSpawned; - - uint32 PhaseCount; - - SummonList Summons; - - uint64 guidDalfors; - uint64 guidPriest[3]; - uint64 guidMason[3]; - uint64 guidHalof; - - void Reset() - { - me->setRegeneratingHealth(false); - DoCast(SPELL_THREAT_PULSE); - me->AI()->Talk(BANNER_SAY); - events.ScheduleEvent(EVENT_SPAWN,3000); - } - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* /*who*/) {} - - void JustSummoned(Creature* Summoned) - { - Summons.Summon(Summoned); - } - - void JustDied(Unit* /*killer*/) - { - Summons.DespawnAll(); - me->DespawnOrUnsummon(); - } - - void UpdateAI(uint32 const diff) - { - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_SPAWN: - { - if (Creature* Dalfors = DoSummon(NPC_CRUSADER_LORD_DALFORS, DalforsPos[0])) - { - guidDalfors = Dalfors->GetGUID(); - Dalfors->GetMotionMaster()->MovePoint(0, DalforsPos[1]); - } - if (Creature* Priest1 = DoSummon(NPC_ARGENT_BATTLE_PRIEST, Priest1Pos[0])) - { - guidPriest[0] = Priest1->GetGUID(); - Priest1->GetMotionMaster()->MovePoint(0, Priest1Pos[1]); - } - if (Creature* Priest2 = DoSummon(NPC_ARGENT_BATTLE_PRIEST, Priest2Pos[0])) - { - guidPriest[1] = Priest2->GetGUID(); - Priest2->GetMotionMaster()->MovePoint(0, Priest2Pos[1]); - } - if (Creature* Priest3 = DoSummon(NPC_ARGENT_BATTLE_PRIEST, Priest3Pos[0])) - { - guidPriest[2] = Priest3->GetGUID(); - Priest3->GetMotionMaster()->MovePoint(0, Priest3Pos[1]); - } - if (Creature* Mason1 = DoSummon(NPC_ARGENT_MASON, Mason1Pos[0])) - { - guidMason[0] = Mason1->GetGUID(); - Mason1->GetMotionMaster()->MovePoint(0, Mason1Pos[1]); - } - if (Creature* Mason2 = DoSummon(NPC_ARGENT_MASON, Mason2Pos[0])) - { - guidMason[1] = Mason2->GetGUID(); - Mason2->GetMotionMaster()->MovePoint(0, Mason2Pos[1]); - } - if (Creature* Mason3 = DoSummon(NPC_ARGENT_MASON, Mason3Pos[0])) - { - guidMason[2] = Mason3->GetGUID(); - Mason3->GetMotionMaster()->MovePoint(0, Mason3Pos[1]); - } - events.ScheduleEvent(EVENT_INTRO_1,15000); - } - break; - case EVENT_INTRO_1: - { - if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) - Dalfors->AI()->Talk(DALFORS_SAY_PRE_1); - events.ScheduleEvent(EVENT_INTRO_2,5000); - } - break; - case EVENT_INTRO_2: - { - if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) - { - Dalfors->SetFacingTo(6.215f); - Dalfors->AI()->Talk(DALFORS_SAY_PRE_2); - } - events.ScheduleEvent(EVENT_INTRO_3,5000); - } - break; - case EVENT_INTRO_3: - { - if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) - { - Dalfors->GetMotionMaster()->MovePoint(0, DalforsPos[2]); - Dalfors->SetHomePosition(DalforsPos[2]); - } - if (Creature* Priest1 = me->GetCreature(*me,guidPriest[0])) - { - Priest1->SetFacingTo(5.7421f); - Priest1->SetHomePosition(Priest1Pos[1]); - } - if (Creature* Priest2 = me->GetCreature(*me,guidPriest[1])) - { - Priest2->SetFacingTo(5.7421f); - Priest2->SetHomePosition(Priest2Pos[1]); - } - if (Creature* Priest3 = me->GetCreature(*me,guidPriest[2])) - { - Priest3->SetFacingTo(5.7421f); - Priest3->SetHomePosition(Priest3Pos[1]); - } - if (Creature* Mason1 = me->GetCreature(*me,guidMason[0])) - { - Mason1->GetMotionMaster()->MovePoint(0, Mason1Pos[2]); - Mason1->SetHomePosition(Mason1Pos[2]); - } - if (Creature* Mason2 = me->GetCreature(*me,guidMason[1])) - { - Mason2->GetMotionMaster()->MovePoint(0, Mason2Pos[2]); - Mason2->SetHomePosition(Mason2Pos[2]); - } - if (Creature* Mason3 = me->GetCreature(*me,guidMason[2])) - { - Mason3->GetMotionMaster()->MovePoint(0, Mason3Pos[2]); - Mason3->SetHomePosition(Mason3Pos[2]); - } - events.ScheduleEvent(EVENT_START_FIGHT,5000); - events.ScheduleEvent(EVENT_MASON_ACTION,15000); - } - break; - case EVENT_MASON_ACTION: - { - if (Creature* Mason1 = me->GetCreature(*me,guidMason[0])) - { - Mason1->SetFacingTo(2.8972f); - Mason1->AI()->SetData(1,1); // triggers SAI actions on npc - } - if (Creature* Mason2 = me->GetCreature(*me,guidMason[1])) - { - Mason2->SetFacingTo(3.1241f); - Mason2->AI()->SetData(1,1); // triggers SAI actions on npc - } - if (Creature* Mason3 = me->GetCreature(*me,guidMason[2])) - { - Mason3->SetFacingTo(3.6651f); - Mason3->AI()->SetData(1,1); // triggers SAI actions on npc - } - } - break; - case EVENT_START_FIGHT: - { - if(Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) - LK->AI()->Talk(LK_TALK_1); - if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) - Dalfors->AI()->Talk(DALFORS_SAY_START); - events.ScheduleEvent(EVENT_WAVE_SPAWN,1000); - } - break; - case EVENT_WAVE_SPAWN: - { - if (PhaseCount == 3) - { - if (Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) - LK->AI()->Talk(LK_TALK_2); - } - else if (PhaseCount == 6) - { - if (Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) - LK->AI()->Talk(LK_TALK_3); - } - if (Creature* tempsum = DoSummon(NPC_SCOURGE_DRUDGE,Mason3Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - if (urand(0,1) == 0) - { - if (Creature* tempsum = DoSummon(NPC_HIDEOUS_PLAGEBRINGER,Mason1Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - if (Creature* tempsum = DoSummon(NPC_HIDEOUS_PLAGEBRINGER,Mason2Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - } - else - { - if (Creature* tempsum = DoSummon(NPC_REANIMATED_CAPTAIN,Mason1Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - if (Creature* tempsum = DoSummon(NPC_REANIMATED_CAPTAIN,Mason2Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - } - - PhaseCount++; - - if (PhaseCount < 8) - events.ScheduleEvent(EVENT_WAVE_SPAWN,urand(10000,20000)); - else - events.ScheduleEvent(EVENT_HALOF,urand(10000,20000)); - } - break; - case EVENT_HALOF: - { - if (Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) - LK->AI()->Talk(LK_TALK_4); - if (Creature* tempsum = DoSummon(NPC_SCOURGE_DRUDGE,Mason1Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - if (Creature* tempsum = DoSummon(NPC_SCOURGE_DRUDGE,Mason2Pos[0])) - { - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - if (Creature* tempsum = DoSummon(NPC_HALOF_THE_DEATHBRINGER,DalforsPos[0])) - { - HalofSpawned = true; - guidHalof = tempsum->GetGUID(); - tempsum->SetHomePosition(DalforsPos[2]); - tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); - } - } - break; - case EVENT_ENDED: - { - Summons.DespawnAll(); - me->DespawnOrUnsummon(); - } - break; - } - - if (PhaseCount == 8) - if (Creature* Halof = me->GetCreature(*me,guidHalof)) - if (Halof->isDead()) - { - DoCast(me,SPELL_CRUSADERS_SPIRE_VICTORY,true); - Summons.DespawnEntry(NPC_HIDEOUS_PLAGEBRINGER); - Summons.DespawnEntry(NPC_REANIMATED_CAPTAIN); - Summons.DespawnEntry(NPC_SCOURGE_DRUDGE); - Summons.DespawnEntry(NPC_HALOF_THE_DEATHBRINGER); - if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) - Dalfors->AI()->Talk(DALFORS_YELL_FINISHED); - events.ScheduleEvent(EVENT_ENDED,10000); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_blessed_bannerAI(creature); - } -}; - -void AddSC_icecrown() -{ - new npc_arete; - new npc_squire_david; - new npc_argent_valiant; - new npc_guardian_pavilion; - new npc_vereth_the_cunning; - new npc_tournament_training_dummy; - new npc_blessed_banner(); -} diff --git a/src/server/scripts/Northrend/sholazar_basin.cpp b/src/server/scripts/Northrend/sholazar_basin.cpp deleted file mode 100644 index 2aa355084a1..00000000000 --- a/src/server/scripts/Northrend/sholazar_basin.cpp +++ /dev/null @@ -1,1048 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* ScriptData -SDName: Sholazar_Basin -SD%Complete: 100 -SDComment: Quest support: 12570, 12573, 12621, 12726 -SDCategory: Sholazar_Basin -EndScriptData */ - -/* ContentData -npc_injured_rainspeaker_oracle -npc_vekjik -avatar_of_freya -npc_haiphoon (Quest: "Song of Wind and Water") -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "SpellScript.h" -#include "SpellAuras.h" -#include "Vehicle.h" -#include "CombatAI.h" -#include "Player.h" - -/*###### -## npc_injured_rainspeaker_oracle -######*/ - -#define GOSSIP_ITEM1 "I am ready to travel to your village now." - -enum eRainspeaker -{ - SAY_START_IRO = 0, - SAY_QUEST_ACCEPT_IRO = 1, - SAY_END_IRO = 2, - - QUEST_FORTUNATE_MISUNDERSTANDINGS = 12570, - FACTION_ESCORTEE_A = 774, - FACTION_ESCORTEE_H = 775 -}; - -class npc_injured_rainspeaker_oracle : public CreatureScript -{ -public: - npc_injured_rainspeaker_oracle() : CreatureScript("npc_injured_rainspeaker_oracle") { } - - struct npc_injured_rainspeaker_oracleAI : public npc_escortAI - { - npc_injured_rainspeaker_oracleAI(Creature* creature) : npc_escortAI(creature) { c_guid = creature->GetGUID(); } - - uint64 c_guid; - - void Reset() - { - me->RestoreFaction(); - // if we will have other way to assign this to only one npc remove this part - if (GUID_LOPART(me->GetGUID()) != 101030) - { - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 1: - SetRun(); - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); - me->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING); - me->SetSpeed(MOVE_SWIM, 0.85f, true); - me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_DISABLE_GRAVITY); - break; - case 19: - me->SetUnitMovementFlags(MOVEMENTFLAG_FALLING); - break; - case 28: - player->GroupEventHappens(QUEST_FORTUNATE_MISUNDERSTANDINGS, me); - // me->RestoreFaction(); - Talk(SAY_END_IRO); - SetRun(false); - break; - } - } - - void JustDied(Unit* /*killer*/) - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - return; - - if (Player* player = GetPlayerForEscort()) - { - if (player->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) != QUEST_STATUS_COMPLETE) - player->FailQuest(QUEST_FORTUNATE_MISUNDERSTANDINGS); - } - } - }; - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(35.0f); - creature->SetUnitMovementFlags(MOVEMENTFLAG_FALLING); - creature->AI()->Talk(SAY_START_IRO); - - switch (player->GetTeam()){ - case ALLIANCE: - creature->setFaction(FACTION_ESCORTEE_A); - break; - case HORDE: - creature->setFaction(FACTION_ESCORTEE_H); - break; - } - } - return true; - } - - bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* /*_Quest*/) - { - creature->AI()->Talk(SAY_QUEST_ACCEPT_IRO); - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_injured_rainspeaker_oracleAI(creature); - } -}; - -/*###### -## npc_vekjik -######*/ - -#define GOSSIP_VEKJIK_ITEM1 "Shaman Vekjik, I have spoken with the big-tongues and they desire peace. I have brought this offering on their behalf." -#define GOSSIP_VEKJIK_ITEM2 "No no... I had no intentions of betraying your people. I was only defending myself. it was all a misunderstanding." - -enum eVekjik -{ - GOSSIP_TEXTID_VEKJIK1 = 13137, - GOSSIP_TEXTID_VEKJIK2 = 13138, - - SAY_TEXTID_VEKJIK1 = 0, - - SPELL_FREANZYHEARTS_FURY = 51469, - - QUEST_MAKING_PEACE = 12573 -}; - -class npc_vekjik : public CreatureScript -{ -public: - npc_vekjik() : CreatureScript("npc_vekjik") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_MAKING_PEACE) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK1, creature->GetGUID()); - return true; - } - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->CLOSE_GOSSIP_MENU(); - creature->AI()->Talk(SAY_TEXTID_VEKJIK1, player->GetGUID()); - player->AreaExploredOrEventHappens(QUEST_MAKING_PEACE); - creature->CastSpell(player, SPELL_FREANZYHEARTS_FURY, false); - break; - } - - return true; - } -}; - -/*###### -## avatar_of_freya -######*/ - -#define GOSSIP_ITEM_AOF1 "I want to stop the Scourge as much as you do. How can I help?" -#define GOSSIP_ITEM_AOF2 "You can trust me. I am no friend of the Lich King." -#define GOSSIP_ITEM_AOF3 "I will not fail." - -enum eFreya -{ - QUEST_FREYA_PACT = 12621, - - SPELL_FREYA_CONVERSATION = 52045, - - GOSSIP_TEXTID_AVATAR1 = 13303, - GOSSIP_TEXTID_AVATAR2 = 13304, - GOSSIP_TEXTID_AVATAR3 = 13305 -}; - -class npc_avatar_of_freya : public CreatureScript -{ -public: - npc_avatar_of_freya() : CreatureScript("npc_avatar_of_freya") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_FREYA_PACT) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR1, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR3, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->CastSpell(player, SPELL_FREYA_CONVERSATION, true); - player->CLOSE_GOSSIP_MENU(); - break; - } - return true; - } -}; - -/*###### -## npc_bushwhacker -######*/ - -class npc_bushwhacker : public CreatureScript -{ -public: - npc_bushwhacker() : CreatureScript("npc_bushwhacker") { } - - struct npc_bushwhackerAI : public ScriptedAI - { - npc_bushwhackerAI(Creature* creature) : ScriptedAI(creature) - { - } - - void InitializeAI() - { - if (me->isDead()) - return; - - if (TempSummon* summ = me->ToTempSummon()) - if (Unit* summoner = summ->GetSummoner()) - me->GetMotionMaster()->MovePoint(0, summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ()); - - Reset(); - } - - void UpdateAI(const uint32 /*uiDiff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_bushwhackerAI(creature); - } -}; - -/*###### -## npc_engineer_helice -######*/ - -enum eEnums -{ - SPELL_EXPLODE_CRYSTAL = 62487, - SPELL_FLAMES = 64561, - - SAY_WP_1 = 0, - SAY_WP_2 = 1, - SAY_WP_3 = 2, - SAY_WP_4 = 3, - SAY_WP_5 = 4, - SAY_WP_6 = 5, - SAY_WP_7 = 6, - - QUEST_DISASTER = 12688 -}; - -class npc_engineer_helice : public CreatureScript -{ -public: - npc_engineer_helice() : CreatureScript("npc_engineer_helice") { } - - struct npc_engineer_heliceAI : public npc_escortAI - { - npc_engineer_heliceAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 m_uiChatTimer; - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - - switch (waypointId) - { - case 0: - Talk(SAY_WP_2); - break; - case 1: - Talk(SAY_WP_3); - me->CastSpell(5918.33f, 5372.91f, -98.770f, SPELL_EXPLODE_CRYSTAL, true); - me->SummonGameObject(184743, 5918.33f, 5372.91f, -98.770f, 0, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN); //approx 3 to 4 seconds - me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); - break; - case 2: - Talk(SAY_WP_4); - break; - case 7: - Talk(SAY_WP_5); - break; - case 8: - me->CastSpell(5887.37f, 5379.39f, -91.289f, SPELL_EXPLODE_CRYSTAL, true); - me->SummonGameObject(184743, 5887.37f, 5379.39f, -91.289f, 0, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN); //approx 3 to 4 seconds - me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); - break; - case 9: - Talk(SAY_WP_6); - break; - case 13: - if (player) - { - player->GroupEventHappens(QUEST_DISASTER, me); - Talk(SAY_WP_7); - } - break; - } - } - - void Reset() - { - m_uiChatTimer = 4000; - } - - void JustDied(Unit* /*killer*/) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_DISASTER); - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (m_uiChatTimer <= uiDiff) - { - m_uiChatTimer = 12000; - } - else - m_uiChatTimer -= uiDiff; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_engineer_heliceAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_DISASTER) - { - if (npc_engineer_heliceAI* pEscortAI = CAST_AI(npc_engineer_helice::npc_engineer_heliceAI, creature->AI())) - { - creature->GetMotionMaster()->MoveJumpTo(0, 0.4f, 0.4f); - creature->setFaction(113); - - pEscortAI->Start(false, false, player->GetGUID()); - creature->AI()->Talk(SAY_WP_1); - } - } - return true; - } -}; - -/*##### -## npc_jungle_punch_target -#####*/ - -#define SAY_OFFER "Care to try Grimbooze Thunderbrew's new jungle punch?" -#define SAY_HEMET_1 "Aye, I'll try it." -#define SAY_HEMET_2 "That's exactly what I needed!" -#define SAY_HEMET_3 "It's got my vote! That'll put hair on your chest like nothing else will." -#define SAY_HADRIUS_1 "I'm always up for something of Grimbooze's." -#define SAY_HADRIUS_2 "Well, so far, it tastes like something my wife would drink..." -#define SAY_HADRIUS_3 "Now, there's the kick I've come to expect from Grimbooze's drinks! I like it!" -#define SAY_TAMARA_1 "Sure!" -#define SAY_TAMARA_2 "Oh my..." -#define SAY_TAMARA_3 "Tastes like I'm drinking... engine degreaser!" - -enum utils -{ - NPC_HEMET = 27986, - NPC_HADRIUS = 28047, - NPC_TAMARA = 28568, - SPELL_OFFER = 51962, - QUEST_ENTRY = 12645, -}; - -enum NesingwaryChildrensWeek -{ - SPELL_ORPHAN_OUT = 58818, - - QUEST_THE_MIGHTY_HEMET_NESINGWARY = 13957, - - ORPHAN_WOLVAR = 33532, - - TEXT_WOLVAR_ORPHAN_6 = 6, - TEXT_WOLVAR_ORPHAN_7 = 7, - TEXT_WOLVAR_ORPHAN_8 = 8, - TEXT_WOLVAR_ORPHAN_9 = 9, - - TEXT_NESINGWARY_1 = 1, -}; - -class npc_jungle_punch_target : public CreatureScript -{ -public: - npc_jungle_punch_target() : CreatureScript("npc_jungle_punch_target") { } - - struct npc_jungle_punch_targetAI : public ScriptedAI - { - npc_jungle_punch_targetAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - sayTimer = 3500; - sayStep = 0; - timer = 0; - phase = 0; - playerGUID = 0; - orphanGUID = 0; - } - - void MoveInLineOfSight(Unit* who) - { - if (!phase && who && who->GetDistance2d(me) < 10.0f) - if (Player* player = who->ToPlayer()) - if (player->GetQuestStatus(QUEST_THE_MIGHTY_HEMET_NESINGWARY) == QUEST_STATUS_INCOMPLETE) - { - playerGUID = player->GetGUID(); - if (Aura* orphanOut = player->GetAura(SPELL_ORPHAN_OUT)) - if (orphanOut->GetCaster() && orphanOut->GetCaster()->GetEntry() == ORPHAN_WOLVAR) - { - orphanGUID = orphanOut->GetCaster()->GetGUID(); - phase = 1; - } - } - } - - void proceedCwEvent(const uint32 diff) - { - if (timer <= diff) - { - Player* player = Player::GetPlayer(*me, playerGUID); - Creature* orphan = Creature::GetCreature(*me, orphanGUID); - - if(!orphan || !player) - { - Reset(); - return; - } - - switch(phase) - { - case 1: - orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); - orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_6); - timer = 5000; - break; - case 2: - orphan->SetFacingToObject(me); - orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_7); - timer = 5000; - break; - case 3: - Talk(TEXT_NESINGWARY_1); - timer = 5000; - break; - case 4: - orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_8); - timer = 5000; - break; - case 5: - orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_9); - timer = 5000; - break; - case 6: - orphan->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - player->GroupEventHappens(QUEST_THE_MIGHTY_HEMET_NESINGWARY, me); - Reset(); - return; - } - ++phase; - } - else - timer -= diff; - } - - void UpdateAI(const uint32 uiDiff) - { - if (phase) - proceedCwEvent(uiDiff); - - if (!sayStep) - return; - - if (sayTimer < uiDiff) - { - switch (sayStep) - { - case 0: - { - switch (me->GetEntry()) - { - case NPC_HEMET: me->MonsterSay(SAY_HEMET_1, LANG_UNIVERSAL, 0); break; - case NPC_HADRIUS: me->MonsterSay(SAY_HADRIUS_1, LANG_UNIVERSAL, 0); break; - case NPC_TAMARA: me->MonsterSay(SAY_TAMARA_1, LANG_UNIVERSAL, 0); break; - } - sayTimer = 3000; - sayStep++; - break; - } - case 1: - { - switch (me->GetEntry()) - { - case NPC_HEMET: me->MonsterSay(SAY_HEMET_2, LANG_UNIVERSAL, 0); break; - case NPC_HADRIUS: me->MonsterSay(SAY_HADRIUS_2, LANG_UNIVERSAL, 0); break; - case NPC_TAMARA: me->MonsterSay(SAY_TAMARA_2, LANG_UNIVERSAL, 0); break; - } - sayTimer = 3000; - sayStep++; - break; - } - case 2: - { - switch (me->GetEntry()) - { - case NPC_HEMET: me->MonsterSay(SAY_HEMET_3, LANG_UNIVERSAL, 0); break; - case NPC_HADRIUS: me->MonsterSay(SAY_HADRIUS_3, LANG_UNIVERSAL, 0); break; - case NPC_TAMARA: me->MonsterSay(SAY_TAMARA_3, LANG_UNIVERSAL, 0); break; - } - sayTimer = 3000; - sayStep = 0; - break; - } - } - } - else - sayTimer -= uiDiff; - } - - void SpellHit(Unit* caster, const SpellInfo* proto) - { - if (!proto || proto->Id != SPELL_OFFER) - return; - - if (!caster->ToPlayer()) - return; - - QuestStatusMap::const_iterator itr = caster->ToPlayer()->getQuestStatusMap().find(QUEST_ENTRY); - if (itr->second.Status != QUEST_STATUS_INCOMPLETE) - return; - - for (uint8 i=0; i<3; i++) - { - switch (i) - { - case 0: - if (NPC_HEMET != me->GetEntry()) - continue; - else - break; - case 1: - if (NPC_HADRIUS != me->GetEntry()) - continue; - else - break; - case 2: - if (NPC_TAMARA != me->GetEntry()) - continue; - else - break; - } - - if (itr->second.CreatureOrGOCount[i] != 0) - continue; - - caster->ToPlayer()->KilledMonsterCredit(me->GetEntry(), 0); - caster->ToPlayer()->Say(SAY_OFFER, LANG_UNIVERSAL); - sayStep = 0; - break; - } - } - - private: - uint16 sayTimer; - uint8 sayStep; - uint32 timer; - int8 phase; - uint64 playerGUID; - uint64 orphanGUID; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_jungle_punch_targetAI(creature); - } -}; - -/*###### -## npc_adventurous_dwarf -######*/ - -#define GOSSIP_OPTION_ORANGE "Can you spare an orange?" -#define GOSSIP_OPTION_BANANAS "Have a spare bunch of bananas?" -#define GOSSIP_OPTION_PAPAYA "I could really use a papaya." - -enum eAdventurousDwarf -{ - QUEST_12634 = 12634, - - ITEM_BANANAS = 38653, - ITEM_PAPAYA = 38655, - ITEM_ORANGE = 38656, - - SPELL_ADD_ORANGE = 52073, - SPELL_ADD_BANANAS = 52074, - SPELL_ADD_PAPAYA = 52076, - - GOSSIP_MENU_DWARF = 13307, - - SAY_DWARF_OUCH = 0, - SAY_DWARF_HELP = 1 -}; - -class npc_adventurous_dwarf : public CreatureScript -{ -public: - npc_adventurous_dwarf() : CreatureScript("npc_adventurous_dwarf") { } - - struct npc_adventurous_dwarfAI : public ScriptedAI - { - npc_adventurous_dwarfAI(Creature* creature) : ScriptedAI(creature) - { - Talk(SAY_DWARF_OUCH); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_adventurous_dwarfAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_12634) != QUEST_STATUS_INCOMPLETE) - return false; - - if (player->GetItemCount(ITEM_ORANGE) < 1) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OPTION_ORANGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - if (player->GetItemCount(ITEM_BANANAS) < 2) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OPTION_BANANAS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - - if (player->GetItemCount(ITEM_PAPAYA) < 1) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OPTION_PAPAYA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - - player->PlayerTalkClass->SendGossipMenu(GOSSIP_MENU_DWARF, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - uint32 spellId = 0; - - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - spellId = SPELL_ADD_ORANGE; - break; - case GOSSIP_ACTION_INFO_DEF + 2: - spellId = SPELL_ADD_BANANAS; - break; - case GOSSIP_ACTION_INFO_DEF + 3: - spellId = SPELL_ADD_PAPAYA; - break; - } - - if (spellId) - player->CastSpell(player, spellId, true); - - creature->AI()->Talk(SAY_DWARF_HELP); - creature->DespawnOrUnsummon(); - return true; - } -}; - -/*###### -## Quest The Lifewarden's Wrath -######*/ - -enum MiscLifewarden -{ - NPC_PRESENCE = 28563, // Freya's Presence - NPC_SABOTEUR = 28538, // Cultist Saboteur - NPC_SERVANT = 28320, // Servant of Freya - - WHISPER_ACTIVATE = 0, - - SPELL_FREYA_DUMMY = 51318, - SPELL_LIFEFORCE = 51395, - SPELL_FREYA_DUMMY_TRIGGER = 51335, - SPELL_LASHER_EMERGE = 48195, - SPELL_WILD_GROWTH = 52948, -}; - -class spell_q12620_the_lifewarden_wrath : public SpellScriptLoader -{ -public: - spell_q12620_the_lifewarden_wrath() : SpellScriptLoader("spell_q12620_the_lifewarden_wrath") { } - - class spell_q12620_the_lifewarden_wrath_SpellScript : public SpellScript - { - PrepareSpellScript(spell_q12620_the_lifewarden_wrath_SpellScript); - - void HandleSendEvent(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - - if (Unit* caster = GetCaster()) - { - if (Creature* presence = caster->FindNearestCreature(NPC_PRESENCE, 50.0f)) - { - presence->AI()->Talk(WHISPER_ACTIVATE, caster->GetGUID()); - presence->CastSpell(presence, SPELL_FREYA_DUMMY, true); // will target plants - // Freya Dummy could be scripted with the following code - - // Revive plants - std::list servants; - GetCaster()->GetCreatureListWithEntryInGrid(servants, NPC_SERVANT, 200.0f); - for (std::list::iterator itr = servants.begin(); itr != servants.end(); ++itr) - { - // Couldn't find a spell that does this - if ((*itr)->isDead()) - (*itr)->Respawn(true); - - (*itr)->CastSpell(*itr, SPELL_FREYA_DUMMY_TRIGGER, true); - (*itr)->CastSpell(*itr, SPELL_LASHER_EMERGE, false); - (*itr)->CastSpell(*itr, SPELL_WILD_GROWTH, false); - - if (Unit* target = (*itr)->SelectNearestTarget(150.0f)) - (*itr)->AI()->AttackStart(target); - } - - // Kill nearby enemies - std::list saboteurs; - caster->GetCreatureListWithEntryInGrid(saboteurs, NPC_SABOTEUR, 200.0f); - for (std::list::iterator itr = saboteurs.begin(); itr != saboteurs.end(); ++itr) - if ((*itr)->isAlive()) - // Lifeforce has a cast duration, it should be cast at all saboteurs one by one - presence->CastSpell((*itr), SPELL_LIFEFORCE, false); - } - } - } - - void Register() - { - OnEffectHit += SpellEffectFn(spell_q12620_the_lifewarden_wrath_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_q12620_the_lifewarden_wrath_SpellScript(); - } -}; - -/*###### -## Quest Kick, What Kick? (12589) -######*/ - -enum KickWhatKick -{ - NPC_LUCKY_WILHELM = 28054, - NPC_APPLE = 28053, - NPC_DROSTAN = 28328, - NPC_CRUNCHY = 28346, - NPC_THICKBIRD = 28093, - - SPELL_HIT_APPLE = 51331, - SPELL_MISS_APPLE = 51332, - SPELL_MISS_BIRD_APPLE = 51366, - SPELL_APPLE_FALL = 51371, - SPELL_BIRD_FALL = 51369, - - EVENT_MISS = 0, - EVENT_HIT = 1, - EVENT_MISS_BIRD = 2, - - SAY_WILHELM_MISS = 0, - SAY_WILHELM_HIT = 1, - SAY_DROSTAN_REPLY_MISS = 0, -}; - -class spell_q12589_shoot_rjr : public SpellScriptLoader -{ -public: - spell_q12589_shoot_rjr() : SpellScriptLoader("spell_q12589_shoot_rjr") { } - - class spell_q12589_shoot_rjr_SpellScript : public SpellScript - { - PrepareSpellScript(spell_q12589_shoot_rjr_SpellScript); - - SpellCastResult CheckCast() - { - if (Unit* target = GetExplTargetUnit()) - if (target->GetEntry() == NPC_LUCKY_WILHELM) - return SPELL_CAST_OK; - - SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM); - return SPELL_FAILED_CUSTOM_ERROR; - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - uint32 roll = urand(1, 100); - - uint8 ev; - if (roll <= 50) - ev = EVENT_MISS; - else if (roll <= 83) - ev = EVENT_HIT; - else - ev = EVENT_MISS_BIRD; - - Unit* shooter = GetCaster(); - Creature* wilhelm = GetHitUnit()->ToCreature(); - Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30); - Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30); - - if (!wilhelm || !apple || !drostan) - return; - - switch (ev) - { - case EVENT_MISS_BIRD: - { - Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30); - Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30); - - if (!bird || !crunchy) - ; // fall to EVENT_MISS - else - { - shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE); - bird->CastSpell(bird, SPELL_BIRD_FALL); - wilhelm->AI()->Talk(SAY_WILHELM_MISS); - drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); - - bird->Kill(bird); - crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), - bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); - // TODO: Make crunchy perform emote eat when he reaches the bird - - break; - } - } - case EVENT_MISS: - { - shooter->CastSpell(wilhelm, SPELL_MISS_APPLE); - wilhelm->AI()->Talk(SAY_WILHELM_MISS); - drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); - break; - } - case EVENT_HIT: - { - shooter->CastSpell(apple, SPELL_HIT_APPLE); - apple->CastSpell(apple, SPELL_APPLE_FALL); - wilhelm->AI()->Talk(SAY_WILHELM_HIT); - if (Player* player = shooter->ToPlayer()) - player->KilledMonsterCredit(NPC_APPLE, 0); - apple->DespawnOrUnsummon(); - - break; - } - } - } - - void Register() - { - OnCheckCast += SpellCheckCastFn(spell_q12589_shoot_rjr_SpellScript::CheckCast); - OnEffectHitTarget += SpellEffectFn(spell_q12589_shoot_rjr_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_q12589_shoot_rjr_SpellScript(); - } -}; - -/*###### -## Quest: Song of Wind and Water ID: 12726 -######*/ -/*This quest precisly needs core script since battle vehicles are not well integrated with SAI, -may be easily converted to SAI when they get.*/ -enum SongOfWindAndWater -{ - // Spells - SPELL_DEVOUR_WIND = 52862, - SPELL_DEVOUR_WATER = 52864, - // NPCs - NPC_HAIPHOON_WATER = 28999, - NPC_HAIPHOON_AIR = 28985 -}; - -class npc_haiphoon : public CreatureScript -{ -public: - npc_haiphoon() : CreatureScript("npc_haiphoon") { } - - struct npc_haiphoonAI : public VehicleAI - { - npc_haiphoonAI(Creature* creature) : VehicleAI(creature) { } - - void SpellHitTarget(Unit* target, SpellInfo const* spell) - { - if (target == me) - return; - - if (spell->Id == SPELL_DEVOUR_WIND && me->GetCharmerOrOwnerPlayerOrPlayerItself()) - { - me->UpdateEntry(NPC_HAIPHOON_AIR); - } - else if (spell->Id == SPELL_DEVOUR_WATER && me->GetCharmerOrOwnerPlayerOrPlayerItself()) - { - me->UpdateEntry(NPC_HAIPHOON_WATER); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_haiphoonAI(creature); - } -}; - -void AddSC_sholazar_basin() -{ - new npc_injured_rainspeaker_oracle(); - new npc_vekjik(); - new npc_avatar_of_freya(); - new npc_bushwhacker(); - new npc_engineer_helice(); - new npc_adventurous_dwarf(); - new npc_jungle_punch_target(); - new spell_q12620_the_lifewarden_wrath(); - new spell_q12589_shoot_rjr(); - new npc_haiphoon(); -} diff --git a/src/server/scripts/Northrend/storm_peaks.cpp b/src/server/scripts/Northrend/storm_peaks.cpp deleted file mode 100644 index 85ab1dc1127..00000000000 --- a/src/server/scripts/Northrend/storm_peaks.cpp +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "SpellScript.h" -#include "SpellAuraEffects.h" -#include "Vehicle.h" -#include "CombatAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_agnetta_tyrsdottar -######*/ - -#define GOSSIP_AGNETTA "Skip the warmup, sister... or are you too scared to face soemeone your own size?" - -enum eAgnetta -{ - QUEST_ITS_THAT_YOUR_GOBLIN = 12969, - FACTION_HOSTILE_AT1 = 45, - SAY_AGGRO = 0 -}; - -class npc_agnetta_tyrsdottar : public CreatureScript -{ -public: - npc_agnetta_tyrsdottar() : CreatureScript("npc_agnetta_tyrsdottar") { } - - struct npc_agnetta_tyrsdottarAI : public ScriptedAI - { - npc_agnetta_tyrsdottarAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() - { - me->RestoreFaction(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_agnetta_tyrsdottarAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_ITS_THAT_YOUR_GOBLIN) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_AGNETTA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(13691, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - creature->AI()->Talk(SAY_AGGRO); - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_AT1); - creature->AI()->AttackStart(player); - } - - return true; - } -}; - -/*###### -## npc_frostborn_scout -######*/ - -#define GOSSIP_ITEM1 "Are you okay? I've come to take you back to Frosthold if you can stand." -#define GOSSIP_ITEM2 "I'm sorry that I didn't get here sooner. What happened?" -#define GOSSIP_ITEM3 "I'll go get some help. Hang in there." - -enum eFrostbornScout -{ - QUEST_MISSING_SCOUTS = 12864 -}; - -class npc_frostborn_scout : public CreatureScript -{ -public: - npc_frostborn_scout() : CreatureScript("npc_frostborn_scout") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - - if (player->GetQuestStatus(QUEST_MISSING_SCOUTS) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->PlayerTalkClass->SendGossipMenu(13611, creature->GetGUID()); - } - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->PlayerTalkClass->SendGossipMenu(13612, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->PlayerTalkClass->SendGossipMenu(13613, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->PlayerTalkClass->SendGossipMenu(13614, creature->GetGUID()); - player->AreaExploredOrEventHappens(QUEST_MISSING_SCOUTS); - break; - } - - return true; - } -}; - -///////////////////// -///npc_injured_goblin -///////////////////// - -enum eInjuredGoblin -{ - QUEST_BITTER_DEPARTURE = 12832, - SAY_QUEST_ACCEPT = 0, - SAY_END_WP_REACHED = 1 -}; - -#define GOSSIP_ITEM_1 "I am ready, lets get you out of here" - -class npc_injured_goblin : public CreatureScript -{ -public: - npc_injured_goblin() : CreatureScript("npc_injured_goblin") { } - - struct npc_injured_goblinAI : public npc_escortAI - { - npc_injured_goblinAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 26: - Talk(SAY_END_WP_REACHED, player->GetGUID()); - break; - case 27: - player->GroupEventHappens(QUEST_BITTER_DEPARTURE, me); - break; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void Reset() {} - - void JustDied(Unit* /*killer*/) - { - Player* player = GetPlayerForEscort(); - if (HasEscortState(STATE_ESCORT_ESCORTING) && player) - player->FailQuest(QUEST_BITTER_DEPARTURE); - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - if (!UpdateVictim()) - return; - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_injured_goblinAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_BITTER_DEPARTURE) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->PlayerTalkClass->SendGossipMenu(9999999, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(999999, creature->GetGUID()); - return true; - } - - bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_BITTER_DEPARTURE) - creature->AI()->Talk(SAY_QUEST_ACCEPT); - - return false; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - npc_escortAI* pEscortAI = CAST_AI(npc_injured_goblin::npc_injured_goblinAI, creature->AI()); - - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - pEscortAI->Start(true, true, player->GetGUID()); - creature->setFaction(113); - } - return true; - } -}; - -/*###### -## npc_roxi_ramrocket -######*/ - -#define SPELL_MECHANO_HOG 60866 -#define SPELL_MEKGINEERS_CHOPPER 60867 - -class npc_roxi_ramrocket : public CreatureScript -{ -public: - npc_roxi_ramrocket() : CreatureScript("npc_roxi_ramrocket") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - //Quest Menu - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - //Trainer Menu - if ( creature->isTrainer() ) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); - - //Vendor Menu - if ( creature->isVendor() ) - if (player->HasSpell(SPELL_MECHANO_HOG) || player->HasSpell(SPELL_MEKGINEERS_CHOPPER)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_TRAIN: - player->GetSession()->SendTrainerList(creature->GetGUID()); - break; - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(creature->GetGUID()); - break; - } - return true; - } -}; - -/*###### -## npc_brunnhildar_prisoner -######*/ - -enum BrunnhildarPrisoner { - SPELL_ICE_PRISON = 54894, - SPELL_ICE_LANCE = 55046, - SPELL_FREE_PRISONER = 55048, - SPELL_RIDE_DRAKE = 55074, - SPELL_SHARD_IMPACT = 55047 -}; - -class npc_brunnhildar_prisoner : public CreatureScript -{ -public: - npc_brunnhildar_prisoner() : CreatureScript("npc_brunnhildar_prisoner") { } - - struct npc_brunnhildar_prisonerAI : public ScriptedAI - { - npc_brunnhildar_prisonerAI(Creature* creature) : ScriptedAI(creature) {} - - bool freed; - - void Reset() - { - freed = false; - me->CastSpell(me, SPELL_ICE_PRISON, true); - } - - void JustRespawned() - { - Reset(); - } - - void UpdateAI(const uint32 /*diff*/) - { - if (!freed) - return; - - if (!me->HasUnitState(UNIT_STATE_ONVEHICLE)) - { - me->DespawnOrUnsummon(); - } - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id != SPELL_ICE_LANCE) - return; - - if (caster->GetVehicleKit()->GetAvailableSeatCount() != 0) - { - me->CastSpell(me, SPELL_FREE_PRISONER, true); - me->CastSpell(caster, SPELL_RIDE_DRAKE, true); - me->CastSpell(me, SPELL_SHARD_IMPACT, true); - freed = true; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_brunnhildar_prisonerAI(creature); - } -}; - -/*###### -## npc_freed_protodrake -######*/ - -enum FreedProtoDrake -{ - AREA_VALLEY_OF_ANCIENT_WINTERS = 4437, - TEXT_EMOTE = 0, - SPELL_KILL_CREDIT_PRISONER = 55144, - SPELL_SUMMON_LIBERATED = 55073, - SPELL_KILL_CREDIT_DRAKE = 55143 -}; - -const Position FreedDrakeWaypoints[16] = -{ - {7294.96f, -2418.733f, 823.869f, 0.0f}, - {7315.984f, -2331.46f, 826.3972f, 0.0f}, - {7271.826f, -2271.479f, 833.5917f, 0.0f}, - {7186.253f, -2218.475f, 847.5632f, 0.0f}, - {7113.195f, -2164.288f, 850.2301f, 0.0f}, - {7078.018f, -2063.106f, 854.7581f, 0.0f}, - {7073.221f, -1983.382f, 861.9246f, 0.0f}, - {7061.455f, -1885.899f, 865.119f, 0.0f}, - {7033.32f, -1826.775f, 876.2578f, 0.0f}, - {6999.902f, -1784.012f, 897.4521f, 0.0f}, - {6954.913f, -1747.043f, 897.4521f, 0.0f}, - {6933.856f, -1720.698f, 882.2022f, 0.0f}, - {6932.729f, -1687.306f, 866.1189f, 0.0f}, - {6952.458f, -1663.802f, 849.8133f, 0.0f}, - {7002.819f, -1651.681f, 831.397f, 0.0f}, - {7026.531f, -1649.239f, 828.8406f, 0.0f} -}; - - -class npc_freed_protodrake : public CreatureScript -{ -public: - npc_freed_protodrake() : CreatureScript("npc_freed_protodrake") { } - - struct npc_freed_protodrakeAI : public VehicleAI - { - npc_freed_protodrakeAI(Creature* creature) : VehicleAI(creature) {} - - bool autoMove; - bool wpReached; - uint16 CheckTimer; - uint16 countWP; - - void Reset() - { - autoMove = false; - wpReached = false; - CheckTimer = 5000; - countWP = 0; - } - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id < 15) - { - ++countWP; - wpReached = true; - } - else - // drake reached village - { - // get player that rides drake (from seat 0) - Unit* player = me->GetVehicleKit()->GetPassenger(0); - if (player && player->GetTypeId() == TYPEID_PLAYER) - { - // for each prisoner on drake,give credit - for (uint8 i = 1; i < 4; ++i) - if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i)) - { - if (prisoner->GetTypeId() != TYPEID_UNIT) - return; - prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true); - prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true); - prisoner->ExitVehicle(); - } - me->CastSpell(me, SPELL_KILL_CREDIT_DRAKE, true); - player->ExitVehicle(); - } - } - } - - void UpdateAI(const uint32 diff) - { - if (!autoMove) - { - if (CheckTimer < diff) - { - CheckTimer = 5000; - if (me->GetAreaId() == AREA_VALLEY_OF_ANCIENT_WINTERS) - { - Talk(TEXT_EMOTE, me->GetVehicleKit()->GetPassenger(0)->GetGUID()); - autoMove = true; - wpReached = true; - } - } - else - CheckTimer -= diff; - } - - if (wpReached && autoMove) - { - wpReached = false; - me->GetMotionMaster()->MovePoint(countWP, FreedDrakeWaypoints[countWP]); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_freed_protodrakeAI(creature); - } -}; - -class npc_icefang : public CreatureScript -{ -public: - npc_icefang() : CreatureScript("npc_icefang") { } - - struct npc_icefangAI : public npc_escortAI - { - npc_icefangAI(Creature* creature) : npc_escortAI(creature) {} - - void AttackStart(Unit* /*who*/) {} - void EnterCombat(Unit* /*who*/) {} - void EnterEvadeMode() {} - - void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) - { - if (who->GetTypeId() == TYPEID_PLAYER) - { - if (apply) - Start(false, true, who->GetGUID()); - } - } - - void WaypointReached(uint32 /*waypointId*/) - { - } - - void JustDied(Unit* /*killer*/) - { - } - - void OnCharmed(bool /*apply*/) - { - } - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_icefangAI (creature); - } -}; - -class npc_hyldsmeet_protodrake : public CreatureScript -{ - enum NPCs - { - NPC_HYLDSMEET_DRAKERIDER = 29694 - }; - - public: - npc_hyldsmeet_protodrake() : CreatureScript("npc_hyldsmeet_protodrake") { } - - class npc_hyldsmeet_protodrakeAI : public CreatureAI - { - public: - npc_hyldsmeet_protodrakeAI(Creature* creature) : CreatureAI(creature), _accessoryRespawnTimer(0), _vehicleKit(creature->GetVehicleKit()) {} - - void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) - { - if (apply) - return; - - if (who->GetEntry() == NPC_HYLDSMEET_DRAKERIDER) - _accessoryRespawnTimer = 5 * MINUTE * IN_MILLISECONDS; - } - - void UpdateAI(uint32 const diff) - { - //! We need to manually reinstall accessories because the vehicle itself is friendly to players, - //! so EnterEvadeMode is never triggered. The accessory on the other hand is hostile and killable. - if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && _vehicleKit) - { - _vehicleKit->InstallAllAccessories(true); - _accessoryRespawnTimer = 0; - } - else - _accessoryRespawnTimer -= diff; - } - - private: - uint32 _accessoryRespawnTimer; - Vehicle* _vehicleKit; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_hyldsmeet_protodrakeAI (creature); - } -}; - -enum CloseRift -{ - SPELL_DESPAWN_RIFT = 61665 -}; - -class spell_close_rift : public SpellScriptLoader -{ - public: - spell_close_rift() : SpellScriptLoader("spell_close_rift") { } - - class spell_close_rift_AuraScript : public AuraScript - { - PrepareAuraScript(spell_close_rift_AuraScript); - - bool Load() - { - _counter = 0; - return true; - } - - bool Validate(SpellInfo const* /*spell*/) - { - return sSpellMgr->GetSpellInfo(SPELL_DESPAWN_RIFT); - } - - void HandlePeriodic(AuraEffect const* /* aurEff */) - { - if (++_counter == 5) - GetTarget()->CastSpell((Unit*)NULL, SPELL_DESPAWN_RIFT, true); - } - - void Register() - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_close_rift_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - - private: - uint8 _counter; - - }; - - AuraScript* GetAuraScript() const - { - return new spell_close_rift_AuraScript(); - } -}; - -void AddSC_storm_peaks() -{ - new npc_agnetta_tyrsdottar(); - new npc_frostborn_scout(); - new npc_injured_goblin(); - new npc_roxi_ramrocket(); - new npc_brunnhildar_prisoner(); - new npc_freed_protodrake(); - new npc_icefang(); - new npc_hyldsmeet_protodrake(); - new spell_close_rift(); -} diff --git a/src/server/scripts/Northrend/wintergrasp.cpp b/src/server/scripts/Northrend/wintergrasp.cpp deleted file mode 100644 index 8935c77b30e..00000000000 --- a/src/server/scripts/Northrend/wintergrasp.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/* Copyright (C) 2008 - 2009 Trinity - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public 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 "BattlefieldMgr.h" -#include "BattlefieldWG.h" -#include "Battlefield.h" -#include "ScriptSystem.h" -#include "WorldSession.h" -#include "ObjectMgr.h" -#include "Vehicle.h" -#include "GameObjectAI.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "SpellScript.h" -#include "Player.h" - -#define GOSSIP_HELLO_DEMO1 "Build catapult." -#define GOSSIP_HELLO_DEMO2 "Build demolisher." -#define GOSSIP_HELLO_DEMO3 "Build siege engine." -#define GOSSIP_HELLO_DEMO4 "I cannot build more!" - -enum WGqueuenpctext -{ - WG_NPCQUEUE_TEXT_H_NOWAR = 14775, - WG_NPCQUEUE_TEXT_H_QUEUE = 14790, - WG_NPCQUEUE_TEXT_H_WAR = 14777, - WG_NPCQUEUE_TEXT_A_NOWAR = 14782, - WG_NPCQUEUE_TEXT_A_QUEUE = 14791, - WG_NPCQUEUE_TEXT_A_WAR = 14781, - WG_NPCQUEUE_TEXTOPTION_JOIN = -1850507, -}; - -enum Spells -{ - // Demolisher engineers spells - SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE = 61409, - SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE = 56662, - SPELL_BUILD_CATAPULT_FORCE = 56664, - SPELL_BUILD_DEMOLISHER_FORCE = 56659, - SPELL_ACTIVATE_CONTROL_ARMS = 49899, - SPELL_RIDE_WG_VEHICLE = 60968, - - SPELL_VEHICLE_TELEPORT = 49759, - - // Spirit guide - SPELL_CHANNEL_SPIRIT_HEAL = 22011, -}; - -enum CreatureIds -{ - NPC_GOBLIN_MECHANIC = 30400, - NPC_GNOMISH_ENGINEER = 30499, - - NPC_WINTERGRASP_CONTROL_ARMS = 27852, - - NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC = 23472, -}; - -enum QuestIds -{ - QUEST_BONES_AND_ARROWS_HORDE_ATT = 13193, - QUEST_JINXING_THE_WALLS_HORDE_ATT = 13202, - QUEST_SLAY_THEM_ALL_HORDE_ATT = 13180, - QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT = 13200, - QUEST_HEALING_WITH_ROSES_HORDE_ATT = 13201, - QUEST_DEFEND_THE_SIEGE_HORDE_ATT = 13223, - - QUEST_BONES_AND_ARROWS_HORDE_DEF = 13199, - QUEST_WARDING_THE_WALLS_HORDE_DEF = 13192, - QUEST_SLAY_THEM_ALL_HORDE_DEF = 13178, - QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF = 13191, - QUEST_HEALING_WITH_ROSES_HORDE_DEF = 13194, - QUEST_TOPPLING_THE_TOWERS_HORDE_DEF = 13539, - QUEST_STOP_THE_SIEGE_HORDE_DEF = 13185, - - QUEST_BONES_AND_ARROWS_ALLIANCE_ATT = 13196, - QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT = 13198, - QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT = 13179, - QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT = 13222, - QUEST_A_RARE_HERB_ALLIANCE_ATT = 13195, - - QUEST_BONES_AND_ARROWS_ALLIANCE_DEF = 13154, - QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF = 13153, - QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF = 13177, - QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF = 13538, - QUEST_STOP_THE_SIEGE_ALLIANCE_DEF = 13186, - QUEST_A_RARE_HERB_ALLIANCE_DEF = 13156, -}; - -uint8 const MAX_WINTERGRASP_VEHICLES = 4; - -uint32 const vehiclesList[MAX_WINTERGRASP_VEHICLES] = -{ - NPC_WINTERGRASP_CATAPULT, - NPC_WINTERGRASP_DEMOLISHER, - NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE, - NPC_WINTERGRASP_SIEGE_ENGINE_HORDE -}; - -class npc_wg_demolisher_engineer : public CreatureScript -{ - public: - npc_wg_demolisher_engineer() : CreatureScript("npc_wg_demolisher_engineer") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (canBuild(creature)) - { - if (player->HasAura(SPELL_CORPORAL)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - else if (player->HasAura(SPELL_LIEUTENANT)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - } - } - else - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->CLOSE_GOSSIP_MENU(); - - if (canBuild(creature)) - { - switch (action - GOSSIP_ACTION_INFO_DEF) - { - case 0: - creature->CastSpell(player, SPELL_BUILD_CATAPULT_FORCE, true); - break; - case 1: - creature->CastSpell(player, SPELL_BUILD_DEMOLISHER_FORCE, true); - break; - case 2: - creature->CastSpell(player, player->GetTeamId() == TEAM_ALLIANCE ? SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE : SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE, true); - break; - } - if (Creature* controlArms = creature->FindNearestCreature(NPC_WINTERGRASP_CONTROL_ARMS, 30.0f, true)) - creature->CastSpell(controlArms, SPELL_ACTIVATE_CONTROL_ARMS, true); - } - return true; - } - - private: - bool canBuild(Creature* creature) - { - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!wintergrasp) - return false; - - switch (creature->GetEntry()) - { - case NPC_GOBLIN_MECHANIC: - return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_H)); - case NPC_GNOMISH_ENGINEER: - return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_A)); - default: - return false; - } - } -}; - -class npc_wg_spirit_guide : public CreatureScript -{ - public: - npc_wg_spirit_guide() : CreatureScript("npc_wg_spirit_guide") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!wintergrasp) - return true; - - GraveyardVect graveyard = wintergrasp->GetGraveyardVector(); - for (uint8 i = 0; i < graveyard.size(); i++) - if (graveyard[i]->GetControlTeamId() == player->GetTeamId()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(((BfGraveyardWG*)graveyard[i])->GetTextId()), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + i); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->CLOSE_GOSSIP_MENU(); - - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (wintergrasp) - { - GraveyardVect gy = wintergrasp->GetGraveyardVector(); - for (uint8 i = 0; i < gy.size(); i++) - if (action - GOSSIP_ACTION_INFO_DEF == i && gy[i]->GetControlTeamId() == player->GetTeamId()) - if (WorldSafeLocsEntry const* safeLoc = sWorldSafeLocsStore.LookupEntry(gy[i]->GetGraveyardId())) - player->TeleportTo(safeLoc->map_id, safeLoc->x, safeLoc->y, safeLoc->z, 0); - } - return true; - } - - struct npc_wg_spirit_guideAI : public ScriptedAI - { - npc_wg_spirit_guideAI(Creature* creature) : ScriptedAI(creature) { } - - void UpdateAI(uint32 const /*diff*/) - { - if (!me->HasUnitState(UNIT_STATE_CASTING)) - DoCast(me, SPELL_CHANNEL_SPIRIT_HEAL); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_wg_spirit_guideAI(creature); - } -}; - -class npc_wg_queue : public CreatureScript -{ - public: - npc_wg_queue() : CreatureScript("npc_wg_queue") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!wintergrasp) - return true; - - if (wintergrasp->IsWarTime()) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(WG_NPCQUEUE_TEXTOPTION_JOIN), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_WAR : WG_NPCQUEUE_TEXT_A_WAR, creature->GetGUID()); - } - else - { - uint32 timer = wintergrasp->GetTimer() / 1000; - player->SendUpdateWorldState(4354, time(NULL) + timer); - if (timer < 15 * MINUTE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(WG_NPCQUEUE_TEXTOPTION_JOIN), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_QUEUE : WG_NPCQUEUE_TEXT_A_QUEUE, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_NOWAR : WG_NPCQUEUE_TEXT_A_NOWAR, creature->GetGUID()); - } - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/ , uint32 /*sender*/ , uint32 /*action*/) - { - player->CLOSE_GOSSIP_MENU(); - - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!wintergrasp) - return true; - - if (wintergrasp->IsWarTime()) - wintergrasp->InvitePlayerToWar(player); - else - { - uint32 timer = wintergrasp->GetTimer() / 1000; - if (timer < 15 * MINUTE) - wintergrasp->InvitePlayerToQueue(player); - } - return true; - } -}; - -class go_wg_vehicle_teleporter : public GameObjectScript -{ - public: - go_wg_vehicle_teleporter() : GameObjectScript("go_wg_vehicle_teleporter") { } - - struct go_wg_vehicle_teleporterAI : public GameObjectAI - { - go_wg_vehicle_teleporterAI(GameObject* gameObject) : GameObjectAI(gameObject), _checkTimer(1000) { } - - void UpdateAI(uint32 diff) - { - if (_checkTimer <= diff) - { - if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) - // Tabulation madness in the hole! - for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++) - if (Creature* vehicleCreature = go->FindNearestCreature(vehiclesList[i], 3.0f, true)) - if (!vehicleCreature->HasAura(SPELL_VEHICLE_TELEPORT) && vehicleCreature->getFaction() == WintergraspFaction[wg->GetDefenderTeam()]) - if (Creature* teleportTrigger = vehicleCreature->FindNearestCreature(NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC, 100.0f, true)) - teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true); - - _checkTimer = 1000; - } - else _checkTimer -= diff; - } - - private: - uint32 _checkTimer; - }; - - GameObjectAI* GetAI(GameObject* go) const - { - return new go_wg_vehicle_teleporterAI(go); - } -}; - -class npc_wg_quest_giver : public CreatureScript -{ - public: - npc_wg_quest_giver() : CreatureScript("npc_wg_quest_giver") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!wintergrasp) - return true; - - if (creature->isQuestGiver()) - { - QuestRelationBounds objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry()); - QuestRelationBounds objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(creature->GetEntry()); - - QuestMenu& qm = player->PlayerTalkClass->GetQuestMenu(); - qm.ClearMenu(); - - for (QuestRelations::const_iterator i = objectQIR.first; i != objectQIR.second; ++i) - { - uint32 questId = i->second; - QuestStatus status = player->GetQuestStatus(questId); - if (status == QUEST_STATUS_COMPLETE) - qm.AddMenuItem(questId, 4); - else if (status == QUEST_STATUS_INCOMPLETE) - qm.AddMenuItem(questId, 4); - //else if (status == QUEST_STATUS_AVAILABLE) - // qm.AddMenuItem(quest_id, 2); - } - - for (QuestRelations::const_iterator i = objectQR.first; i != objectQR.second; ++i) - { - uint32 questId = i->second; - Quest const* quest = sObjectMgr->GetQuestTemplate(questId); - if (!quest) - continue; - - switch (questId) - { - // Horde attacker - case QUEST_BONES_AND_ARROWS_HORDE_ATT: - case QUEST_JINXING_THE_WALLS_HORDE_ATT: - case QUEST_SLAY_THEM_ALL_HORDE_ATT: - case QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT: - case QUEST_HEALING_WITH_ROSES_HORDE_ATT: - case QUEST_DEFEND_THE_SIEGE_HORDE_ATT: - if (wintergrasp->GetAttackerTeam() == TEAM_HORDE) - { - QuestStatus status = player->GetQuestStatus(questId); - - if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 4); - else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 2); - } - break; - // Horde defender - case QUEST_BONES_AND_ARROWS_HORDE_DEF: - case QUEST_WARDING_THE_WALLS_HORDE_DEF: - case QUEST_SLAY_THEM_ALL_HORDE_DEF: - case QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF: - case QUEST_HEALING_WITH_ROSES_HORDE_DEF: - case QUEST_TOPPLING_THE_TOWERS_HORDE_DEF: - case QUEST_STOP_THE_SIEGE_HORDE_DEF: - if (wintergrasp->GetDefenderTeam() == TEAM_HORDE) - { - QuestStatus status = player->GetQuestStatus(questId); - - if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 4); - else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 2); - } - break; - // Alliance attacker - case QUEST_BONES_AND_ARROWS_ALLIANCE_ATT: - case QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT: - case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT: - case QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT: - case QUEST_A_RARE_HERB_ALLIANCE_ATT: - if (wintergrasp->GetAttackerTeam() == TEAM_ALLIANCE) - { - QuestStatus status = player->GetQuestStatus(questId); - - if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 4); - else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 2); - } - break; - // Alliance defender - case QUEST_BONES_AND_ARROWS_ALLIANCE_DEF: - case QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF: - case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF: - case QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF: - case QUEST_STOP_THE_SIEGE_ALLIANCE_DEF: - case QUEST_A_RARE_HERB_ALLIANCE_DEF: - if (wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE) - { - QuestStatus status = player->GetQuestStatus(questId); - - if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 4); - else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 2); - } - break; - default: - QuestStatus status = player->GetQuestStatus(questId); - - if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 4); - else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(questId, 2); - break; - } - } - } - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } -}; - -class spell_wintergrasp_force_building : public SpellScriptLoader -{ - public: - spell_wintergrasp_force_building() : SpellScriptLoader("spell_wintergrasp_force_building") { } - - class spell_wintergrasp_force_building_SpellScript : public SpellScript - { - PrepareSpellScript(spell_wintergrasp_force_building_SpellScript); - - bool Validate(SpellInfo const* /*spell*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_BUILD_CATAPULT_FORCE) - || !sSpellMgr->GetSpellInfo(SPELL_BUILD_DEMOLISHER_FORCE) - || !sSpellMgr->GetSpellInfo(SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE) - || !sSpellMgr->GetSpellInfo(SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE)) - return false; - return true; - } - - void HandleScript(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetHitUnit(), GetEffectValue(), false); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_force_building_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_wintergrasp_force_building_SpellScript(); - } -}; - -class spell_wintergrasp_grab_passenger : public SpellScriptLoader -{ - public: - spell_wintergrasp_grab_passenger() : SpellScriptLoader("spell_wintergrasp_grab_passenger") { } - - class spell_wintergrasp_grab_passenger_SpellScript : public SpellScript - { - PrepareSpellScript(spell_wintergrasp_grab_passenger_SpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Player* target = GetHitPlayer()) - target->CastSpell(GetCaster(), SPELL_RIDE_WG_VEHICLE, false); - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_grab_passenger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_wintergrasp_grab_passenger_SpellScript(); - } -}; - -class achievement_wg_didnt_stand_a_chance : public AchievementCriteriaScript -{ -public: - achievement_wg_didnt_stand_a_chance() : AchievementCriteriaScript("achievement_wg_didnt_stand_a_chance") { } - - bool OnCheck(Player* source, Unit* target) - { - if (!target) - return false; - - if (Player* victim = target->ToPlayer()) - { - if (!victim->IsMounted()) - return false; - - if (Vehicle* vehicle = source->GetVehicle()) - if (vehicle->GetVehicleInfo()->m_ID == 244) // Wintergrasp Tower Cannon - return true; - } - - return false; - } -}; - -enum WgTeleport -{ - SPELL_WINTERGRASP_TELEPORT_TRIGGER = 54643, -}; - -class spell_wintergrasp_defender_teleport : public SpellScriptLoader -{ -public: - spell_wintergrasp_defender_teleport() : SpellScriptLoader("spell_wintergrasp_defender_teleport") { } - - class spell_wintergrasp_defender_teleport_SpellScript : public SpellScript - { - PrepareSpellScript(spell_wintergrasp_defender_teleport_SpellScript); - - SpellCastResult CheckCast() - { - if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) - if (Player* target = GetExplTargetUnit()->ToPlayer()) - // check if we are in Wintergrasp at all, SotA uses same teleport spells - if ((target->GetZoneId() == 4197 && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER)) - return SPELL_FAILED_BAD_TARGETS; - return SPELL_CAST_OK; - } - - void Register() - { - OnCheckCast += SpellCheckCastFn(spell_wintergrasp_defender_teleport_SpellScript::CheckCast); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_wintergrasp_defender_teleport_SpellScript(); - } -}; - -class spell_wintergrasp_defender_teleport_trigger : public SpellScriptLoader -{ -public: - spell_wintergrasp_defender_teleport_trigger() : SpellScriptLoader("spell_wintergrasp_defender_teleport_trigger") { } - - class spell_wintergrasp_defender_teleport_trigger_SpellScript : public SpellScript - { - PrepareSpellScript(spell_wintergrasp_defender_teleport_trigger_SpellScript); - - void HandleDummy(SpellEffIndex /*effindex*/) - { - if (Unit* target = GetHitUnit()) - { - WorldLocation loc; - target->GetPosition(&loc); - SetExplTargetDest(loc); - } - } - - void Register() - { - OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_defender_teleport_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_wintergrasp_defender_teleport_trigger_SpellScript(); - } -}; - -void AddSC_wintergrasp() -{ - new npc_wg_queue(); - new npc_wg_spirit_guide(); - new npc_wg_demolisher_engineer(); - new go_wg_vehicle_teleporter(); - new npc_wg_quest_giver(); - new spell_wintergrasp_force_building(); - new spell_wintergrasp_grab_passenger(); - new achievement_wg_didnt_stand_a_chance(); - new spell_wintergrasp_defender_teleport(); - new spell_wintergrasp_defender_teleport_trigger(); -} diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp new file mode 100644 index 00000000000..8e7507bce61 --- /dev/null +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -0,0 +1,2537 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Borean_Tundra +SD%Complete: 100 +SDComment: Quest support: 11708. Taxi vendors. +SDCategory: Borean Tundra +EndScriptData */ + +/* ContentData +npc_iruk +npc_corastrasza +npc_jenny +npc_sinkhole_kill_credit +npc_khunok_the_behemoth +mob_nerubar_victim +npc_keristrasza +npc_nesingwary_trapper +npc_lurgglbr +npc_nexus_drake_hatchling +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "ScriptedFollowerAI.h" +#include "Player.h" +#include "SpellInfo.h" +#include "WorldSession.h" + +/*###### +## npc_sinkhole_kill_credit +######*/ + +enum eSinkhole +{ + SPELL_SET_CART = 46797, + SPELL_EXPLODE_CART = 46799, + SPELL_SUMMON_CART = 46798, + SPELL_SUMMON_WORM = 46800, +}; + +class npc_sinkhole_kill_credit : public CreatureScript +{ +public: + npc_sinkhole_kill_credit() : CreatureScript("npc_sinkhole_kill_credit") { } + + struct npc_sinkhole_kill_creditAI : public ScriptedAI + { + npc_sinkhole_kill_creditAI(Creature* creature) : ScriptedAI(creature){} + + uint32 phaseTimer; + uint8 phase; + uint64 casterGuid; + + void Reset() + { + phaseTimer = 500; + phase = 0; + casterGuid = 0; + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (phase) + return; + + if (spell->Id == SPELL_SET_CART && caster->GetTypeId() == TYPEID_PLAYER + && CAST_PLR(caster)->GetQuestStatus(11897) == QUEST_STATUS_INCOMPLETE) + { + phase = 1; + casterGuid = caster->GetGUID(); + } + } + + void EnterCombat(Unit* /*who*/){} + + void UpdateAI(const uint32 diff) + { + if (!phase) + return; + + if (phaseTimer <= diff) + { + switch (phase) + { + case 1: + DoCast(me, SPELL_EXPLODE_CART, true); + DoCast(me, SPELL_SUMMON_CART, true); + if (GameObject* cart = me->FindNearestGameObject(188160, 3)) + cart->SetUInt32Value(GAMEOBJECT_FACTION, 14); + phaseTimer = 3000; + phase = 2; + break; + case 2: + if (GameObject* cart = me->FindNearestGameObject(188160, 3)) + cart->UseDoorOrButton(); + DoCast(me, SPELL_EXPLODE_CART, true); + phaseTimer = 3000; + phase = 3; + break; + case 3: + DoCast(me, SPELL_EXPLODE_CART, true); + phaseTimer = 2000; + phase = 4; + case 5: + DoCast(me, SPELL_SUMMON_WORM, true); + if (Unit* worm = me->FindNearestCreature(26250, 3)) + { + worm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + worm->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + } + phaseTimer = 1000; + phase = 6; + break; + case 6: + DoCast(me, SPELL_EXPLODE_CART, true); + if (Unit* worm = me->FindNearestCreature(26250, 3)) + { + me->Kill(worm); + worm->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } + phaseTimer = 2000; + phase = 7; + break; + case 7: + DoCast(me, SPELL_EXPLODE_CART, true); + if (Player* caster = Unit::GetPlayer(*me, casterGuid)) + caster->KilledMonster(me->GetCreatureTemplate(), me->GetGUID()); + phaseTimer = 5000; + phase = 8; + break; + case 8: + EnterEvadeMode(); + break; + } + } else phaseTimer -= diff; + + } + + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_sinkhole_kill_creditAI(creature); + } +}; + +/*###### +## npc_khunok_the_behemoth +######*/ + +class npc_khunok_the_behemoth : public CreatureScript +{ +public: + npc_khunok_the_behemoth() : CreatureScript("npc_khunok_the_behemoth") { } + + struct npc_khunok_the_behemothAI : public ScriptedAI + { + npc_khunok_the_behemothAI(Creature* creature) : ScriptedAI(creature) {} + + void MoveInLineOfSight(Unit* who) + { + ScriptedAI::MoveInLineOfSight(who); + + if (who->GetTypeId() != TYPEID_UNIT) + return; + + if (who->GetEntry() == 25861 && me->IsWithinDistInMap(who, 10.0f)) + { + if (Unit* owner = who->GetOwner()) + { + if (owner->GetTypeId() == TYPEID_PLAYER) + { + owner->CastSpell(owner, 46231, true); + CAST_CRE(who)->DespawnOrUnsummon(); + } + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_khunok_the_behemothAI(creature); + } +}; + +/*###### +## npc_keristrasza +######*/ + +enum eKeristrasza +{ + SPELL_TELEPORT_TO_SARAGOSA = 46772 +}; + +#define GOSSIP_HELLO_KERI "I am prepared to face Saragosa!" + +class npc_keristrasza : public CreatureScript +{ +public: + npc_keristrasza() : CreatureScript("npc_keristrasza") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(11957) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_KERI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF + 1) + { + player->CLOSE_GOSSIP_MENU(); + player->CastSpell(player, SPELL_TELEPORT_TO_SARAGOSA, true); + } + + return true; + } +}; + +/*###### +## npc_corastrasza +######*/ + +#define GOSSIP_ITEM_C_1 "I... I think so..." + +enum eCorastrasza +{ + SPELL_SUMMON_WYRMREST_SKYTALON = 61240, + SPELL_WYRMREST_SKYTALON_RIDE_PERIODIC = 61244, + + QUEST_ACES_HIGH_DAILY = 13414, + QUEST_ACES_HIGH = 13413 +}; + +class npc_corastrasza : public CreatureScript +{ +public: + npc_corastrasza() : CreatureScript("npc_corastrasza") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_ACES_HIGH) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_ACES_HIGH_DAILY) == QUEST_STATUS_INCOMPLETE) //It's the same dragon for both quests. + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_C_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + + player->CastSpell(player, SPELL_SUMMON_WYRMREST_SKYTALON, true); + player->CastSpell(player, SPELL_WYRMREST_SKYTALON_RIDE_PERIODIC, true); + + } + + return true; + } +}; + +/*###### +## npc_iruk +######*/ + +#define GOSSIP_ITEM_I "" + +enum eIruk +{ + QUEST_SPIRITS_WATCH_OVER_US = 11961, + SPELL_CREATURE_TOTEM_OF_ISSLIRUK = 46816, + GOSSIP_TEXT_I = 12585 +}; + +class npc_iruk : public CreatureScript +{ +public: + npc_iruk() : CreatureScript("npc_iruk") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_SPIRITS_WATCH_OVER_US) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXT_I, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->CastSpell(player, SPELL_CREATURE_TOTEM_OF_ISSLIRUK, true); + player->CLOSE_GOSSIP_MENU(); + break; + + } + return true; + } +}; + +/*###### +## mob_nerubar_victim +######*/ + +#define WARSONG_PEON 25270 + +const uint32 nerubarVictims[3] = +{ + 45526, 45527, 45514 +}; + +class mob_nerubar_victim : public CreatureScript +{ +public: + mob_nerubar_victim() : CreatureScript("mob_nerubar_victim") { } + + struct mob_nerubar_victimAI : public ScriptedAI + { + mob_nerubar_victimAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + void EnterCombat(Unit* /*who*/) {} + void MoveInLineOfSight(Unit* /*who*/) {} + + void JustDied(Unit* killer) + { + Player* player = killer->ToPlayer(); + if (!player) + return; + + if (player->GetQuestStatus(11611) == QUEST_STATUS_INCOMPLETE) + { + uint8 uiRand = urand(0, 99); + if (uiRand < 25) + { + player->CastSpell(me, 45532, true); + player->KilledMonsterCredit(WARSONG_PEON, 0); + } + else if (uiRand < 75) + player->CastSpell(me, nerubarVictims[urand(0, 2)], true); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_nerubar_victimAI(creature); + } +}; + +/*###### +## npc_jenny +######*/ + +enum eJenny +{ + QUEST_LOADER_UP = 11881, + + NPC_FEZZIX_GEARTWIST = 25849, + NPC_JENNY = 25969, + + SPELL_GIVE_JENNY_CREDIT = 46358, + SPELL_CRATES_CARRIED = 46340, + SPELL_DROP_CRATE = 46342 +}; + +class npc_jenny : public CreatureScript +{ +public: + npc_jenny() : CreatureScript("npc_jenny") { } + + struct npc_jennyAI : public ScriptedAI + { + npc_jennyAI(Creature* creature) : ScriptedAI(creature) {} + + bool setCrateNumber; + + void Reset() + { + if (!setCrateNumber) + setCrateNumber = true; + + me->SetReactState(REACT_PASSIVE); + + switch (CAST_PLR(me->GetOwner())->GetTeamId()) + { + case TEAM_ALLIANCE: + me->setFaction(FACTION_ESCORT_A_NEUTRAL_ACTIVE); + break; + default: + case TEAM_HORDE: + me->setFaction(FACTION_ESCORT_H_NEUTRAL_ACTIVE); + break; + } + } + + void DamageTaken(Unit* /*pDone_by*/, uint32& /*uiDamage*/) + { + DoCast(me, SPELL_DROP_CRATE, true); + } + + void UpdateAI(const uint32 /*diff*/) + { + if (setCrateNumber) + { + me->AddAura(SPELL_CRATES_CARRIED, me); + setCrateNumber = false; + } + + if (!setCrateNumber && !me->HasAura(SPELL_CRATES_CARRIED)) + me->DisappearAndDie(); + + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_jennyAI (creature); + } +}; + +/*###### +## npc_fezzix_geartwist +######*/ + +class npc_fezzix_geartwist : public CreatureScript +{ +public: + npc_fezzix_geartwist() : CreatureScript("npc_fezzix_geartwist") { } + + struct npc_fezzix_geartwistAI : public ScriptedAI + { + npc_fezzix_geartwistAI(Creature* creature) : ScriptedAI(creature) {} + + void MoveInLineOfSight(Unit* who) + { + ScriptedAI::MoveInLineOfSight(who); + + if (who->GetTypeId() != TYPEID_UNIT) + return; + + if (who->GetEntry() == NPC_JENNY && me->IsWithinDistInMap(who, 10.0f)) + { + if (Unit* owner = who->GetOwner()) + { + if (owner->GetTypeId() == TYPEID_PLAYER) + { + if (who->HasAura(SPELL_CRATES_CARRIED)) + { + owner->CastSpell(owner, SPELL_GIVE_JENNY_CREDIT, true); // Maybe is not working. + CAST_PLR(owner)->CompleteQuest(QUEST_LOADER_UP); + CAST_CRE(who)->DisappearAndDie(); + } + } + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_fezzix_geartwistAI(creature); + } +}; + +/*###### +## npc_nesingwary_trapper +######*/ + +enum eNesingwaryTrapper +{ + GO_HIGH_QUALITY_FUR = 187983, + + GO_CARIBOU_TRAP_1 = 187982, + GO_CARIBOU_TRAP_2 = 187995, + GO_CARIBOU_TRAP_3 = 187996, + GO_CARIBOU_TRAP_4 = 187997, + GO_CARIBOU_TRAP_5 = 187998, + GO_CARIBOU_TRAP_6 = 187999, + GO_CARIBOU_TRAP_7 = 188000, + GO_CARIBOU_TRAP_8 = 188001, + GO_CARIBOU_TRAP_9 = 188002, + GO_CARIBOU_TRAP_10 = 188003, + GO_CARIBOU_TRAP_11 = 188004, + GO_CARIBOU_TRAP_12 = 188005, + GO_CARIBOU_TRAP_13 = 188006, + GO_CARIBOU_TRAP_14 = 188007, + GO_CARIBOU_TRAP_15 = 188008, + + SPELL_TRAPPED = 46104, +}; + +#define CaribouTrapsNum 15 +const uint32 CaribouTraps[CaribouTrapsNum] = +{ + GO_CARIBOU_TRAP_1, GO_CARIBOU_TRAP_2, GO_CARIBOU_TRAP_3, GO_CARIBOU_TRAP_4, GO_CARIBOU_TRAP_5, + GO_CARIBOU_TRAP_6, GO_CARIBOU_TRAP_7, GO_CARIBOU_TRAP_8, GO_CARIBOU_TRAP_9, GO_CARIBOU_TRAP_10, + GO_CARIBOU_TRAP_11, GO_CARIBOU_TRAP_12, GO_CARIBOU_TRAP_13, GO_CARIBOU_TRAP_14, GO_CARIBOU_TRAP_15, +}; + +class npc_nesingwary_trapper : public CreatureScript +{ +public: + npc_nesingwary_trapper() : CreatureScript("npc_nesingwary_trapper") { } + + struct npc_nesingwary_trapperAI : public ScriptedAI + { + npc_nesingwary_trapperAI(Creature* creature) : ScriptedAI(creature) { creature->SetVisible(false); } + + uint64 go_caribouGUID; + uint8 phase; + uint32 phaseTimer; + + void Reset() + { + me->SetVisible(false); + phaseTimer = 2500; + phase = 1; + go_caribouGUID = 0; + } + + void EnterCombat(Unit* /*who*/) {} + void MoveInLineOfSight(Unit* /*who*/) {} + + void JustDied(Unit* /*killer*/) + { + if (GameObject* go_caribou = me->GetMap()->GetGameObject(go_caribouGUID)) + go_caribou->SetLootState(GO_JUST_DEACTIVATED); + + if (TempSummon* summon = me->ToTempSummon()) + if (summon->isSummon()) + if (Unit* temp = summon->GetSummoner()) + if (temp->GetTypeId() == TYPEID_PLAYER) + CAST_PLR(temp)->KilledMonsterCredit(me->GetEntry(), 0); + + if (GameObject* go_caribou = me->GetMap()->GetGameObject(go_caribouGUID)) + go_caribou->SetGoState(GO_STATE_READY); + } + + void UpdateAI(const uint32 diff) + { + if (phaseTimer <= diff) + { + switch (phase) + { + case 1: + me->SetVisible(true); + phaseTimer = 2000; + phase = 2; + break; + case 2: + if (GameObject* go_fur = me->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 11.0f)) + me->GetMotionMaster()->MovePoint(0, go_fur->GetPositionX(), go_fur->GetPositionY(), go_fur->GetPositionZ()); + phaseTimer = 1500; + phase = 3; + break; + case 3: + //Talk(SAY_NESINGWARY_1); + phaseTimer = 2000; + phase = 4; + break; + case 4: + me->HandleEmoteCommand(EMOTE_ONESHOT_LOOT); + phaseTimer = 1000; + phase = 5; + break; + case 5: + me->HandleEmoteCommand(EMOTE_ONESHOT_NONE); + phaseTimer = 500; + phase = 6; + break; + case 6: + if (GameObject* go_fur = me->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 11.0f)) + go_fur->Delete(); + phaseTimer = 500; + phase = 7; + break; + case 7: + { + GameObject* go_caribou = NULL; + for (uint8 i = 0; i < CaribouTrapsNum; ++i) + { + go_caribou = me->FindNearestGameObject(CaribouTraps[i], 5.0f); + if (go_caribou) + { + go_caribou->SetGoState(GO_STATE_ACTIVE); + go_caribouGUID = go_caribou->GetGUID(); + break; + } + } + phase = 8; + phaseTimer = 1000; + } + break; + case 8: + DoCast(me, SPELL_TRAPPED, true); + phase = 0; + break; + } + } else phaseTimer -= diff; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_nesingwary_trapperAI(creature); + } +}; + +/*###### +## npc_lurgglbr +######*/ + +enum eLurgglbr +{ + QUEST_ESCAPE_WINTERFIN_CAVERNS = 11570, + + GO_CAGE = 187369, + + FACTION_ESCORTEE_A = 774, + FACTION_ESCORTEE_H = 775, + + SAY_START_1 = 0, + SAY_START_2 = 1, + SAY_END_1 = 2, + SAY_END_2 = 3 +}; + +class npc_lurgglbr : public CreatureScript +{ +public: + npc_lurgglbr() : CreatureScript("npc_lurgglbr") { } + + struct npc_lurgglbrAI : public npc_escortAI + { + npc_lurgglbrAI(Creature* creature) : npc_escortAI(creature){} + + uint32 IntroTimer; + uint32 IntroPhase; + + void Reset() + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + { + IntroTimer = 0; + IntroPhase = 0; + } + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 0: + IntroPhase = 1; + IntroTimer = 2000; + break; + case 41: + IntroPhase = 4; + IntroTimer = 2000; + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (IntroPhase) + { + if (IntroTimer <= diff) + { + switch (IntroPhase) + { + case 1: + Talk(SAY_START_1); + IntroPhase = 2; + IntroTimer = 7500; + break; + case 2: + Talk(SAY_END_1); + IntroPhase = 3; + IntroTimer = 7500; + break; + case 3: + me->SetReactState(REACT_AGGRESSIVE); + IntroPhase = 0; + IntroTimer = 0; + break; + case 4: + Talk(SAY_START_2); + IntroPhase = 5; + IntroTimer = 8000; + break; + case 5: + Talk(SAY_END_2); + IntroPhase = 6; + IntroTimer = 2500; + break; + + case 6: + if (Player* player = GetPlayerForEscort()) + player->AreaExploredOrEventHappens(QUEST_ESCAPE_WINTERFIN_CAVERNS); + IntroPhase = 7; + IntroTimer = 2500; + break; + + case 7: + me->DespawnOrUnsummon(); + IntroPhase = 0; + IntroTimer = 0; + break; + } + } else IntroTimer -= diff; + } + npc_escortAI::UpdateAI(diff); + + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lurgglbrAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPE_WINTERFIN_CAVERNS) + { + if (GameObject* go = creature->FindNearestGameObject(GO_CAGE, 5.0f)) + { + go->SetRespawnTime(0); + go->SetGoType(GAMEOBJECT_TYPE_BUTTON); + go->UseDoorOrButton(20); + } + + if (npc_escortAI* pEscortAI = CAST_AI(npc_lurgglbr::npc_lurgglbrAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + + switch (player->GetTeam()) + { + case ALLIANCE: + creature->setFaction(FACTION_ESCORTEE_A); + break; + default: + case HORDE: + creature->setFaction(FACTION_ESCORTEE_H); + break; + } + + return true; + } + return false; + } +}; + +/*###### +## npc_nexus_drake_hatchling +######*/ + +enum eNexusDrakeHatchling +{ + SPELL_DRAKE_HARPOON = 46607, + SPELL_RED_DRAGONBLOOD = 46620, + SPELL_DRAKE_HATCHLING_SUBDUED = 46691, + SPELL_SUBDUED = 46675, + + NPC_RAELORASZ = 26117, + + QUEST_DRAKE_HUNT = 11919, + QUEST_DRAKE_HUNT_D = 11940 +}; + +class npc_nexus_drake_hatchling : public CreatureScript +{ +public: + npc_nexus_drake_hatchling() : CreatureScript("npc_nexus_drake_hatchling") { } + + struct npc_nexus_drake_hatchlingAI : public FollowerAI //The spell who makes the npc follow the player is missing, also we can use FollowerAI! + { + npc_nexus_drake_hatchlingAI(Creature* creature) : FollowerAI(creature) {} + + uint64 HarpoonerGUID; + bool WithRedDragonBlood; + + void Reset() + { + WithRedDragonBlood = false; + HarpoonerGUID = 0; + } + + void EnterCombat(Unit* who) + { + if (me->IsValidAttackTarget(who)) + AttackStart(who); + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id == SPELL_DRAKE_HARPOON && caster->GetTypeId() == TYPEID_PLAYER) + { + HarpoonerGUID = caster->GetGUID(); + DoCast(me, SPELL_RED_DRAGONBLOOD, true); + } + WithRedDragonBlood = true; + } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (!HarpoonerGUID) + return; + + if (me->HasAura(SPELL_SUBDUED) && who->GetEntry() == NPC_RAELORASZ) + { + if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) + { + if (Player* pHarpooner = Unit::GetPlayer(*me, HarpoonerGUID)) + { + pHarpooner->KilledMonsterCredit(26175, 0); + pHarpooner->RemoveAura(SPELL_DRAKE_HATCHLING_SUBDUED); + SetFollowComplete(); + HarpoonerGUID = 0; + me->DisappearAndDie(); + } + } + } + } + + void UpdateAI(const uint32 /*diff*/) + { + if (WithRedDragonBlood && HarpoonerGUID && !me->HasAura(SPELL_RED_DRAGONBLOOD)) + { + if (Player* pHarpooner = Unit::GetPlayer(*me, HarpoonerGUID)) + { + EnterEvadeMode(); + StartFollow(pHarpooner, 35, NULL); + + DoCast(me, SPELL_SUBDUED, true); + pHarpooner->CastSpell(pHarpooner, SPELL_DRAKE_HATCHLING_SUBDUED, true); + + me->AttackStop(); + WithRedDragonBlood = false; + } + } + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_nexus_drake_hatchlingAI(creature); + } +}; + +/*###### +## npc_thassarian +######*/ + +enum eThassarian +{ + QUEST_LAST_RITES = 12019, + + SPELL_TRANSFORM_VALANAR = 46753, + SPELL_STUN = 46957, + SPELL_SHADOW_BOLT = 15537, + + NPC_IMAGE_LICH_KING = 26203, + NPC_COUNSELOR_TALBOT = 25301, + NPC_PRINCE_VALANAR = 28189, + NPC_GENERAL_ARLOS = 25250, + NPC_LERYSSA = 25251, + + SAY_THASSARIAN_1 = 0, + SAY_THASSARIAN_2 = 1, + SAY_THASSARIAN_3 = 2, + SAY_THASSARIAN_4 = 3, + SAY_THASSARIAN_5 = 4, + SAY_THASSARIAN_6 = 5, + SAY_THASSARIAN_7 = 6, + + SAY_TALBOT_1 = 0, + SAY_TALBOT_2 = 1, + SAY_TALBOT_3 = 2, + SAY_TALBOT_4 = 3, + + SAY_LICH_1 = 0, + SAY_LICH_2 = 1, + SAY_LICH_3 = 2, + + SAY_ARLOS_1 = 0, + SAY_ARLOS_2 = 1, + + SAY_LERYSSA_1 = 0, + SAY_LERYSSA_2 = 1, + SAY_LERYSSA_3 = 2, + SAY_LERYSSA_4 = 3 +}; + +#define GOSSIP_ITEM_T "Let's do this, Thassarian. It's now or never." + +class npc_thassarian : public CreatureScript +{ +public: + npc_thassarian() : CreatureScript("npc_thassarian") { } + + struct npc_thassarianAI : public npc_escortAI + { + npc_thassarianAI(Creature* creature) : npc_escortAI(creature) {} + + uint64 arthasGUID; + uint64 talbotGUID; + uint64 leryssaGUID; + uint64 arlosGUID; + + bool arthasInPosition; + bool arlosInPosition; + bool leryssaInPosition; + bool talbotInPosition; + + uint32 phase; + uint32 phaseTimer; + + void Reset() + { + me->RestoreFaction(); + me->RemoveStandFlags(UNIT_STAND_STATE_SIT); + + arthasGUID = 0; + talbotGUID = 0; + leryssaGUID = 0; + arlosGUID = 0; + + arthasInPosition = false; + arlosInPosition = false; + leryssaInPosition = false; + talbotInPosition = false; + + phase = 0; + phaseTimer = 0; + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 3: + SetEscortPaused(true); + if (Creature* arthas = me->SummonCreature(NPC_IMAGE_LICH_KING, 3730.313f, 3518.689f, 473.324f, 1.562f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) + { + arthasGUID = arthas->GetGUID(); + arthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + arthas->SetReactState(REACT_PASSIVE); + arthas->SetWalk(true); + arthas->GetMotionMaster()->MovePoint(0, 3737.374756f, 3564.841309f, 477.433014f); + } + if (Creature* talbot = me->SummonCreature(NPC_COUNSELOR_TALBOT, 3747.23f, 3614.936f, 473.321f, 4.462012f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) + { + talbotGUID = talbot->GetGUID(); + talbot->SetWalk(true); + talbot->GetMotionMaster()->MovePoint(0, 3738.000977f, 3568.882080f, 477.433014f); + } + me->SetWalk(false); + break; + case 4: + SetEscortPaused(true); + phase = 7; + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (arthasInPosition && talbotInPosition) + { + phase = 1; + arthasInPosition = false; + talbotInPosition = false; + } + + if (arlosInPosition && leryssaInPosition) + { + arlosInPosition = false; + leryssaInPosition = false; + Talk(SAY_THASSARIAN_1); + SetEscortPaused(false); + } + + if (phaseTimer <= uiDiff) + { + Creature* talbot = me->GetCreature(*me, talbotGUID); + Creature* arthas = me->GetCreature(*me, arthasGUID); + switch (phase) + { + case 1: + if (talbot) + talbot->SetStandState(UNIT_STAND_STATE_KNEEL); + phaseTimer = 3000; + ++phase; + break; + + case 2: + if (talbot) + { + talbot->UpdateEntry(NPC_PRINCE_VALANAR, ALLIANCE); + talbot->setFaction(14); + talbot->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + talbot->SetReactState(REACT_PASSIVE); + } + phaseTimer = 5000; + ++phase; + break; + + case 3: + if (talbot) + talbot->AI()->Talk(SAY_TALBOT_1); + phaseTimer = 5000; + ++phase; + break; + + case 4: + if (arthas) + arthas->AI()->Talk(SAY_LICH_1); + phaseTimer = 5000; + ++phase; + break; + + case 5: + if (talbot) + talbot->AI()->Talk(SAY_TALBOT_2); + phaseTimer = 5000; + ++phase; + break; + + case 6: + if (Creature* arlos = me->SummonCreature(NPC_GENERAL_ARLOS, 3745.527100f, 3615.655029f, 473.321533f, 4.447805f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) + { + arlosGUID = arlos->GetGUID(); + arlos->SetWalk(true); + arlos->GetMotionMaster()->MovePoint(0, 3735.570068f, 3572.419922f, 477.441010f); + } + if (Creature* leryssa = me->SummonCreature(NPC_LERYSSA, 3749.654541f, 3614.959717f, 473.323486f, 4.524959f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000)) + { + leryssaGUID = leryssa->GetGUID(); + leryssa->SetWalk(false); + leryssa->SetReactState(REACT_PASSIVE); + leryssa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + leryssa->GetMotionMaster()->MovePoint(0, 3741.969971f, 3571.439941f, 477.441010f); + } + phaseTimer = 2000; + phase = 0; + break; + + case 7: + Talk(SAY_THASSARIAN_2); + phaseTimer = 5000; + ++phase; + break; + + case 8: + if (arthas && talbot) + { + arthas->SetInFront(me); //The client doesen't update with the new orientation :l + talbot->SetStandState(UNIT_STAND_STATE_STAND); + arthas->AI()->Talk(SAY_LICH_2); + } + phaseTimer = 5000; + phase = 9; + break; + + case 9: + Talk(SAY_THASSARIAN_3); + phaseTimer = 5000; + phase = 10; + break; + + case 10: + if (talbot) + talbot->AI()->Talk(SAY_TALBOT_3); + phaseTimer = 5000; + phase = 11; + break; + + case 11: + if (arthas) + arthas->AI()->Talk(SAY_LICH_3); + phaseTimer = 5000; + phase = 12; + break; + + case 12: + if (talbot) + talbot->AI()->Talk(SAY_TALBOT_4); + phaseTimer = 2000; + phase = 13; + break; + + case 13: + if (arthas) + arthas->RemoveFromWorld(); + ++phase; + break; + + case 14: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (talbot) + { + talbot->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + talbot->SetReactState(REACT_AGGRESSIVE); + talbot->CastSpell(me, SPELL_SHADOW_BOLT, false); + } + phaseTimer = 1500; + ++phase; + break; + + case 15: + me->SetReactState(REACT_AGGRESSIVE); + AttackStart(talbot); + phase = 0; + break; + + case 16: + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + phaseTimer = 20000; + ++phase; + break; + + case 17: + if (Creature* leryssa = me->GetCreature(*me, leryssaGUID)) + leryssa->RemoveFromWorld(); + if (Creature* arlos= me->GetCreature(*me, arlosGUID)) + arlos->RemoveFromWorld(); + if (talbot) + talbot->RemoveFromWorld(); + me->RemoveStandFlags(UNIT_STAND_STATE_SIT); + SetEscortPaused(false); + phaseTimer = 0; + phase = 0; + } + } else phaseTimer -= uiDiff; + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* /*killer*/) + { + if (Creature* talbot = me->GetCreature(*me, talbotGUID)) + talbot->RemoveFromWorld(); + + if (Creature* leryssa = me->GetCreature(*me, leryssaGUID)) + leryssa->RemoveFromWorld(); + + if (Creature* arlos = me->GetCreature(*me, arlosGUID)) + arlos->RemoveFromWorld(); + + if (Creature* arthas = me->GetCreature(*me, arthasGUID)) + arthas->RemoveFromWorld(); + } + }; + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_LAST_RITES) == QUEST_STATUS_INCOMPLETE && creature->GetAreaId() == 4128) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_T, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(200.0f); + break; + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_thassarianAI(creature); + } +}; + +/*###### +## npc_image_lich_king +######*/ + +class npc_image_lich_king : public CreatureScript +{ +public: + npc_image_lich_king() : CreatureScript("npc_image_lich_king") { } + + struct npc_image_lich_kingAI : public ScriptedAI + { + npc_image_lich_kingAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + me->RestoreFaction(); + } + + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + CAST_AI(npc_thassarian::npc_thassarianAI, CAST_CRE(summoner)->AI())->arthasInPosition = true; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_image_lich_kingAI(creature); + } +}; + +/*###### +## npc_general_arlos +######*/ + +class npc_general_arlos : public CreatureScript +{ +public: + npc_general_arlos() : CreatureScript("npc_general_arlos") { } + + struct npc_general_arlosAI : public ScriptedAI + { + npc_general_arlosAI(Creature* creature) : ScriptedAI(creature) {} + + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + + me->AddUnitState(UNIT_STATE_STUNNED); + me->CastSpell(me, SPELL_STUN, true); + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + CAST_AI(npc_thassarian::npc_thassarianAI, CAST_CRE(summoner)->AI())->arlosInPosition = true; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_general_arlosAI(creature); + } +}; + +/*###### +## npc_counselor_talbot +######*/ + +enum eCounselorTalbot +{ + SPELL_DEFLECTION = 51009, + SPELL_SOUL_BLAST = 50992, +}; + +class npc_counselor_talbot : public CreatureScript +{ +public: + npc_counselor_talbot() : CreatureScript("npc_counselor_talbot") { } + + struct npc_counselor_talbotAI : public ScriptedAI + { + npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature) + { + creature->RestoreFaction(); + } + + uint64 leryssaGUID; + uint64 arlosGUID; + + bool bCheck; + + uint32 shadowBoltTimer; + uint32 deflectionTimer; + uint32 soulBlastTimer; + + void Reset() + { + leryssaGUID = 0; + arlosGUID = 0; + bCheck = false; + shadowBoltTimer = urand(5000, 12000); + deflectionTimer = urand(20000, 25000); + soulBlastTimer = urand (12000, 18000); + } + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + CAST_AI(npc_thassarian::npc_thassarianAI, CAST_CRE(summoner)->AI())->talbotInPosition = true; + } + + void UpdateAI(const uint32 uiDiff) + { + if (bCheck) + { + if (Creature* leryssa = me->FindNearestCreature(NPC_LERYSSA, 50.0f, true)) + leryssaGUID = leryssa->GetGUID(); + if (Creature* arlos = me->FindNearestCreature(NPC_GENERAL_ARLOS, 50.0f, true)) + arlosGUID = arlos->GetGUID(); + bCheck = false; + } + + if (!UpdateVictim()) + return; + + if (me->GetAreaId() == 4125) + { + if (shadowBoltTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_SHADOW_BOLT); + shadowBoltTimer = urand(5000, 12000); + } else shadowBoltTimer -= uiDiff; + + if (deflectionTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_DEFLECTION); + deflectionTimer = urand(20000, 25000); + } else deflectionTimer -= uiDiff; + + if (soulBlastTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_SOUL_BLAST); + soulBlastTimer = urand (12000, 18000); + } else soulBlastTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + if (!leryssaGUID || !arlosGUID) + return; + + Creature* leryssa = Unit::GetCreature(*me, leryssaGUID); + Creature* arlos = Unit::GetCreature(*me, arlosGUID); + if (!leryssa || !arlos) + return; + + arlos->AI()->Talk(SAY_ARLOS_1); + arlos->AI()->Talk(SAY_ARLOS_2); + leryssa->AI()->Talk(SAY_LERYSSA_1); + arlos->Kill(arlos, false); + leryssa->RemoveAura(SPELL_STUN); + leryssa->ClearUnitState(UNIT_STATE_STUNNED); + leryssa->SetWalk(false); + leryssa->GetMotionMaster()->MovePoint(0, 3722.114502f, 3564.201660f, 477.441437f); + + if (Player* player = killer->ToPlayer()) + player->RewardPlayerAndGroupAtEvent(NPC_PRINCE_VALANAR, 0); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_counselor_talbotAI(creature); + } +}; + +/*###### +## npc_leryssa +######*/ + +class npc_leryssa : public CreatureScript +{ +public: + npc_leryssa() : CreatureScript("npc_leryssa") { } + + struct npc_leryssaAI : public ScriptedAI + { + npc_leryssaAI(Creature* creature) : ScriptedAI(creature) + { + bDone = false; + phase = 0; + phaseTimer = 0; + + creature->RemoveStandFlags(UNIT_STAND_STATE_SIT); + } + + bool bDone; + + uint32 phase; + uint32 phaseTimer; + + void MovementInform(uint32 type, uint32 /*uiId*/) + { + if (type != POINT_MOTION_TYPE) + return; + + if (!bDone) + { + if (Creature* talbot = me->FindNearestCreature(NPC_PRINCE_VALANAR, 50.0f, true)) + CAST_AI(npc_counselor_talbot::npc_counselor_talbotAI, talbot->GetAI())->bCheck = true; + + me->AddUnitState(UNIT_STATE_STUNNED); + me->CastSpell(me, SPELL_STUN, true); + + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + CAST_AI(npc_thassarian::npc_thassarianAI, summoner->GetAI())->leryssaInPosition = true; + bDone = true; + } + else + { + me->SetStandState(UNIT_STAND_STATE_SIT); + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + summoner->SetStandState(UNIT_STAND_STATE_SIT); + phaseTimer = 1500; + phase = 1; + } + } + + void UpdateAI(const uint32 uiDiff) + { + ScriptedAI::UpdateAI(uiDiff); + + if (phaseTimer <= uiDiff) + { + switch (phase) + { + case 1: + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (Creature* thassarian = summoner->ToCreature()) + thassarian->AI()->Talk(SAY_THASSARIAN_4); + phaseTimer = 5000; + ++phase; + break; + case 2: + Talk(SAY_LERYSSA_2); + phaseTimer = 5000; + ++phase; + break; + case 3: + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (Creature* thassarian = summoner->ToCreature()) + thassarian->AI()->Talk(SAY_THASSARIAN_5); + phaseTimer = 5000; + ++phase; + break; + case 4: + Talk(SAY_LERYSSA_3); + phaseTimer = 5000; + ++phase; + break; + case 5: + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (Creature* thassarian = summoner->ToCreature()) + thassarian->AI()->Talk(SAY_THASSARIAN_6); + phaseTimer = 5000; + ++phase; + break; + + case 6: + Talk(SAY_LERYSSA_4); + phaseTimer = 5000; + ++phase; + break; + case 7: + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (Creature* thassarian = summoner->ToCreature()) + { + thassarian->AI()->Talk(SAY_THASSARIAN_7); + CAST_AI(npc_thassarian::npc_thassarianAI, thassarian->GetAI())->phase = 16; + } + phaseTimer = 5000; + phase = 0; + break; + } + } else phaseTimer -= uiDiff; + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_leryssaAI(creature); + } +}; + +/*###### +## 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 +}; + +class npc_beryl_sorcerer : public CreatureScript +{ +public: + npc_beryl_sorcerer() : CreatureScript("npc_beryl_sorcerer") { } + + struct npc_beryl_sorcererAI : public FollowerAI + { + npc_beryl_sorcererAI(Creature* creature) : FollowerAI(creature) {} + + bool bEnslaved; + + void Reset() + { + me->SetReactState(REACT_AGGRESSIVE); + bEnslaved = false; + } + + void EnterCombat(Unit* who) + { + if (me->IsValidAttackTarget(who)) + AttackStart(who); + } + + void SpellHit(Unit* pCaster, const SpellInfo* pSpell) + { + if (pSpell->Id == SPELL_ARCANE_CHAINS && pCaster->GetTypeId() == TYPEID_PLAYER && !HealthAbovePct(50) && !bEnslaved) + { + EnterEvadeMode(); //We make sure that the npc is not attacking the player! + me->SetReactState(REACT_PASSIVE); + StartFollow(pCaster->ToPlayer(), 0, NULL); + me->UpdateEntry(NPC_CAPTURED_BERLY_SORCERER, TEAM_NEUTRAL); + DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF, true); + + if (Player* player = pCaster->ToPlayer()) + player->KilledMonsterCredit(NPC_CAPTURED_BERLY_SORCERER, 0); + + bEnslaved = true; + } + } + + void MoveInLineOfSight(Unit* who) + { + FollowerAI::MoveInLineOfSight(who); + + if (who->GetEntry() == NPC_LIBRARIAN_DONATHAN && me->IsWithinDistInMap(who, INTERACTION_DISTANCE)) + { + SetFollowComplete(); + me->DisappearAndDie(); + } + } + + void UpdateAI(const uint32 /*uiDiff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_beryl_sorcererAI(creature); + } +}; + +/*###### +## npc_imprisoned_beryl_sorcerer +######*/ +enum eImprisionedBerylSorcerer +{ + SPELL_NEURAL_NEEDLE = 45634, + + NPC_IMPRISONED_BERYL_SORCERER = 25478, + + SAY_IMPRISIONED_BERYL_1 = 0, + SAY_IMPRISIONED_BERYL_2 = 1, + SAY_IMPRISIONED_BERYL_3 = 2, + SAY_IMPRISIONED_BERYL_4 = 3, + SAY_IMPRISIONED_BERYL_5 = 4, + SAY_IMPRISIONED_BERYL_6 = 5, + SAY_IMPRISIONED_BERYL_7 = 6 +}; + +class npc_imprisoned_beryl_sorcerer : public CreatureScript +{ +public: + npc_imprisoned_beryl_sorcerer() : CreatureScript("npc_imprisoned_beryl_sorcerer") { } + + struct npc_imprisoned_beryl_sorcererAI : public ScriptedAI + { + npc_imprisoned_beryl_sorcererAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 rebuff; + + void Reset() + { + if (me->GetReactState() != REACT_PASSIVE) + me->SetReactState(REACT_PASSIVE); + + rebuff = 0; + } + + void UpdateAI(const uint32 diff) + { + UpdateVictim(); + + if (rebuff <= diff) + { + if (!me->HasAura(SPELL_COSMETIC_ENSLAVE_CHAINS_SELF)) + { + DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF); + } + rebuff = 180000; + } + else + rebuff -= diff; + + DoMeleeAttackIfReady(); + } + + void EnterCombat(Unit* /*who*/) + { + } + + void SpellHit(Unit* unit, const SpellInfo* spell) + { + if (spell->Id == SPELL_NEURAL_NEEDLE && unit->GetTypeId() == TYPEID_PLAYER) + { + if (Player* player = unit->ToPlayer()) + { + GotStinged(player->GetGUID()); + } + } + } + + void GotStinged(uint64 casterGUID) + { + if (Player* caster = Player::GetPlayer(*me, casterGUID)) + { + uint32 step = caster->GetAuraCount(SPELL_NEURAL_NEEDLE) + 1; + switch (step) + { + case 1: + Talk(SAY_IMPRISIONED_BERYL_1); + break; + case 2: + Talk(SAY_IMPRISIONED_BERYL_2, caster->GetGUID()); + break; + case 3: + Talk(SAY_IMPRISIONED_BERYL_3); + break; + case 4: + Talk(SAY_IMPRISIONED_BERYL_4); + break; + case 5: + Talk(SAY_IMPRISIONED_BERYL_5); + break; + case 6: + Talk(SAY_IMPRISIONED_BERYL_6, caster->GetGUID()); + break; + case 7: + Talk(SAY_IMPRISIONED_BERYL_7); + caster->KilledMonsterCredit(NPC_IMPRISONED_BERYL_SORCERER, 0); + break; + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_imprisoned_beryl_sorcererAI(creature); + } +}; + +/*###### +## npc_mootoo_the_younger +######*/ +enum MootooTheYounger +{ + SAY_1 = 0, + SAY_2 = 1, + SAY_3 = 2, + SAY_4 = 3, + SAY_5 = 4, + + NPC_MOOTOO_THE_YOUNGER = 25504, + QUEST_ESCAPING_THE_MIST = 11664 +}; + +class npc_mootoo_the_younger : public CreatureScript +{ +public: + npc_mootoo_the_younger() : CreatureScript("npc_mootoo_the_younger") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPING_THE_MIST) + { + switch (player->GetTeam()) + { + case ALLIANCE: + creature->setFaction(FACTION_ESCORTEE_A); + break; + case HORDE: + creature->setFaction(FACTION_ESCORTEE_H); + break; + } + creature->SetStandState(UNIT_STAND_STATE_STAND); + creature->AI()->Talk(SAY_1); + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + } + return true; + } + + struct npc_mootoo_the_youngerAI : public npc_escortAI + { + npc_mootoo_the_youngerAI(Creature* creature) : npc_escortAI(creature) {} + + void Reset() + { + SetDespawnAtFar(false); + } + + void JustDied(Unit* /*killer*/) + { + if (Player* player=GetPlayerForEscort()) + player->FailQuest(QUEST_ESCAPING_THE_MIST); + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 10: + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + Talk(SAY_2); + break; + case 12: + Talk(SAY_3); + me->HandleEmoteCommand(EMOTE_ONESHOT_LOOT); + break; + case 16: + Talk(SAY_4); + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + break; + case 20: + me->SetPhaseMask(1, true); + Talk(SAY_5); + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + player->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me); + SetRun(true); + break; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_mootoo_the_youngerAI(creature); + } +}; + +/*###### +## npc_bonker_togglevolt +######*/ + +enum BonkerTogglevolt +{ + NPC_BONKER_TOGGLEVOLT = 25589, + QUEST_GET_ME_OUTA_HERE = 11673, + + SAY_BONKER_1 = 0, + SAY_BONKER_2 = 1 +}; + +class npc_bonker_togglevolt : public CreatureScript +{ +public: + npc_bonker_togglevolt() : CreatureScript("npc_bonker_togglevolt") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_GET_ME_OUTA_HERE) + { + creature->SetStandState(UNIT_STAND_STATE_STAND); + creature->AI()->Talk(SAY_BONKER_2, player->GetGUID()); + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, true, player->GetGUID()); + } + return true; + } + + struct npc_bonker_togglevoltAI : public npc_escortAI + { + npc_bonker_togglevoltAI(Creature* creature) : npc_escortAI(creature) {} + uint32 Bonker_agro; + + void Reset() + { + Bonker_agro=0; + SetDespawnAtFar(false); + } + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_GET_ME_OUTA_HERE); + } + + void UpdateEscortAI(const uint32 /*diff*/) + { + if (GetAttack() && UpdateVictim()) + { + if (Bonker_agro == 0) + { + Talk(SAY_BONKER_1); + Bonker_agro++; + } + DoMeleeAttackIfReady(); + } + else Bonker_agro=0; + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 29: + player->GroupEventHappens(QUEST_GET_ME_OUTA_HERE, me); + break; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_bonker_togglevoltAI(creature); + } +}; + +/*###### +## Help Those That Cannot Help Themselves, Quest 11876 +######*/ + +enum eHelpThemselves +{ + QUEST_CANNOT_HELP_THEMSELVES = 11876, + GO_MAMMOTH_TRAP_1 = 188022, + GO_MAMMOTH_TRAP_2 = 188024, + GO_MAMMOTH_TRAP_3 = 188025, + GO_MAMMOTH_TRAP_4 = 188026, + GO_MAMMOTH_TRAP_5 = 188027, + GO_MAMMOTH_TRAP_6 = 188028, + GO_MAMMOTH_TRAP_7 = 188029, + GO_MAMMOTH_TRAP_8 = 188030, + GO_MAMMOTH_TRAP_9 = 188031, + GO_MAMMOTH_TRAP_10 = 188032, + GO_MAMMOTH_TRAP_11 = 188033, + GO_MAMMOTH_TRAP_12 = 188034, + GO_MAMMOTH_TRAP_13 = 188035, + GO_MAMMOTH_TRAP_14 = 188036, + GO_MAMMOTH_TRAP_15 = 188037, + GO_MAMMOTH_TRAP_16 = 188038, + GO_MAMMOTH_TRAP_17 = 188039, + GO_MAMMOTH_TRAP_18 = 188040, + GO_MAMMOTH_TRAP_19 = 188041, + GO_MAMMOTH_TRAP_20 = 188042, + GO_MAMMOTH_TRAP_21 = 188043, + GO_MAMMOTH_TRAP_22 = 188044, +}; + +#define MammothTrapsNum 22 +const uint32 MammothTraps[MammothTrapsNum] = +{ + GO_MAMMOTH_TRAP_1, GO_MAMMOTH_TRAP_2, GO_MAMMOTH_TRAP_3, GO_MAMMOTH_TRAP_4, GO_MAMMOTH_TRAP_5, + GO_MAMMOTH_TRAP_6, GO_MAMMOTH_TRAP_7, GO_MAMMOTH_TRAP_8, GO_MAMMOTH_TRAP_9, GO_MAMMOTH_TRAP_10, + GO_MAMMOTH_TRAP_11, GO_MAMMOTH_TRAP_12, GO_MAMMOTH_TRAP_13, GO_MAMMOTH_TRAP_14, GO_MAMMOTH_TRAP_15, + GO_MAMMOTH_TRAP_16, GO_MAMMOTH_TRAP_17, GO_MAMMOTH_TRAP_18, GO_MAMMOTH_TRAP_19, GO_MAMMOTH_TRAP_20, + GO_MAMMOTH_TRAP_21, GO_MAMMOTH_TRAP_22 +}; + +class npc_trapped_mammoth_calf : public CreatureScript +{ +public: + npc_trapped_mammoth_calf() : CreatureScript("npc_trapped_mammoth_calf") { } + + struct npc_trapped_mammoth_calfAI : public ScriptedAI + { + npc_trapped_mammoth_calfAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 uiTimer; + bool bStarted; + + void Reset() + { + uiTimer = 1500; + bStarted = false; + + GameObject* pTrap = NULL; + for (uint8 i = 0; i < MammothTrapsNum; ++i) + { + pTrap = me->FindNearestGameObject(MammothTraps[i], 11.0f); + if (pTrap) + { + pTrap->SetGoState(GO_STATE_ACTIVE); + return; + } + } + } + + void UpdateAI(const uint32 diff) + { + if (bStarted) + { + if (uiTimer <= diff) + { + Position pos; + me->GetRandomNearPosition(pos, 10.0f); + me->GetMotionMaster()->MovePoint(0, pos); + bStarted = false; + } + else uiTimer -= diff; + } + } + + void DoAction(const int32 param) + { + if (param == 1) + bStarted = true; + } + + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + + me->DisappearAndDie(); + + GameObject* pTrap = NULL; + for (uint8 i = 0; i < MammothTrapsNum; ++i) + { + pTrap = me->FindNearestGameObject(MammothTraps[i], 11.0f); + if (pTrap) + { + pTrap->SetLootState(GO_JUST_DEACTIVATED); + return; + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_trapped_mammoth_calfAI(creature); + } +}; + +/*###### +## Quest 11653: Hah... You're Not So Big Now! +######*/ + +enum eNotSoBig +{ + QUEST_YOU_RE_NOT_SO_BIG_NOW = 11653, + SPELL_AURA_NOTSOBIG_1 = 45672, + SPELL_AURA_NOTSOBIG_2 = 45673, + SPELL_AURA_NOTSOBIG_3 = 45677, + SPELL_AURA_NOTSOBIG_4 = 45681 +}; + +class npc_magmoth_crusher : public CreatureScript +{ +public: + npc_magmoth_crusher() : CreatureScript("npc_magmoth_crusher") { } + + struct npc_magmoth_crusherAI : public ScriptedAI + { + npc_magmoth_crusherAI(Creature* creature) : ScriptedAI(creature) {} + + void JustDied(Unit* killer) + { + Player* player = killer->ToPlayer(); + if (!player) + return; + + if (player->GetQuestStatus(QUEST_YOU_RE_NOT_SO_BIG_NOW) == QUEST_STATUS_INCOMPLETE && + (me->HasAura(SPELL_AURA_NOTSOBIG_1) || me->HasAura(SPELL_AURA_NOTSOBIG_2) || + me->HasAura(SPELL_AURA_NOTSOBIG_3) || me->HasAura(SPELL_AURA_NOTSOBIG_4))) + { + Quest const* qInfo = sObjectMgr->GetQuestTemplate(QUEST_YOU_RE_NOT_SO_BIG_NOW); + if (qInfo) + player->KilledMonsterCredit(qInfo->RequiredNpcOrGo[0], 0); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_magmoth_crusherAI(creature); + } +}; + +/*###### +## Quest 11608: Bury Those Cockroaches! +######*/ + +#define QUEST_BURY_THOSE_COCKROACHES 11608 +#define SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION 45502 + +class npc_seaforium_depth_charge : public CreatureScript +{ +public: + npc_seaforium_depth_charge() : CreatureScript("npc_seaforium_depth_charge") { } + + struct npc_seaforium_depth_chargeAI : public ScriptedAI + { + npc_seaforium_depth_chargeAI(Creature* creature) : ScriptedAI(creature) { } + + uint32 uiExplosionTimer; + + void Reset() + { + uiExplosionTimer = urand(5000, 10000); + } + + void UpdateAI(const uint32 diff) + { + if (uiExplosionTimer < diff) + { + DoCast(SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION); + for (uint8 i = 0; i < 4; ++i) + { + if (Creature* cCredit = me->FindNearestCreature(25402 + i, 10.0f))//25402-25405 credit markers + { + if (Unit* uOwner = me->GetOwner()) + { + Player* owner = uOwner->ToPlayer(); + if (owner && owner->GetQuestStatus(QUEST_BURY_THOSE_COCKROACHES) == QUEST_STATUS_INCOMPLETE) + owner->KilledMonsterCredit(cCredit->GetEntry(), cCredit->GetGUID()); + } + } + } + me->Kill(me); + return; + } else uiExplosionTimer -= diff; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_seaforium_depth_chargeAI(creature); + } +}; + +/*###### +## Help Those That Cannot Help Themselves, Quest 11876 +######*/ + +enum eValiancekeepcannons +{ + GO_VALIANCE_KEEP_CANNON_1 = 187560, + GO_VALIANCE_KEEP_CANNON_2 = 188692 +}; + +class npc_valiance_keep_cannoneer : public CreatureScript +{ +public: + npc_valiance_keep_cannoneer() : CreatureScript("npc_valiance_keep_cannoneer") { } + + struct npc_valiance_keep_cannoneerAI : public ScriptedAI + { + npc_valiance_keep_cannoneerAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 uiTimer; + + void Reset() + { + uiTimer = urand(13000, 18000); + } + + void UpdateAI(const uint32 diff) + { + if (uiTimer <= diff) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + GameObject* pCannon = me->FindNearestGameObject(GO_VALIANCE_KEEP_CANNON_1, 10); + if (!pCannon) + pCannon = me->FindNearestGameObject(GO_VALIANCE_KEEP_CANNON_2, 10); + if (pCannon) + pCannon->Use(me); + uiTimer = urand(13000, 18000); + } + else uiTimer -= diff; + + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_valiance_keep_cannoneerAI(creature); + } +}; + +/******************************************************* + * npc_warmage_coldarra + *******************************************************/ + +enum Spells +{ + SPELL_TRANSITUS_SHIELD_BEAM = 48310 +}; + +enum NPCs +{ + NPC_TRANSITUS_SHIELD_DUMMY = 27306, + NPC_WARMAGE_HOLLISTER = 27906, + NPC_WARMAGE_CALANDRA = 27173, + NPC_WARMAGE_WATKINS = 27904 +}; + +class npc_warmage_coldarra : public CreatureScript +{ +public: + npc_warmage_coldarra() : CreatureScript("npc_warmage_coldarra") { } + + struct npc_warmage_coldarraAI : public Scripted_NoMovementAI + { + npc_warmage_coldarraAI(Creature* creature) : Scripted_NoMovementAI(creature){} + + uint32 m_uiTimer; //Timer until recast + + void Reset() + { + m_uiTimer = 0; + } + + void EnterCombat(Unit* /*who*/) {} + + void AttackStart(Unit* /*who*/) {} + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiTimer <= uiDiff) + { + std::list orbList; + GetCreatureListWithEntryInGrid(orbList, me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f); + + switch (me->GetEntry()) + { + case NPC_WARMAGE_HOLLISTER: + { + if (!orbList.empty()) + { + for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) + { + if (Creature* pOrb = *itr) + if (pOrb->GetPositionY() > 6680) + DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); + } + } + m_uiTimer = urand(90000, 120000); + } + break; + case NPC_WARMAGE_CALANDRA: + { + if (!orbList.empty()) + { + for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) + { + if (Creature* pOrb = *itr) + if ((pOrb->GetPositionY() < 6680) && (pOrb->GetPositionY() > 6630)) + DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); + } + } + m_uiTimer = urand(90000, 120000); + } + break; + case NPC_WARMAGE_WATKINS: + { + if (!orbList.empty()) + { + for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) + { + if (Creature* pOrb = *itr) + if (pOrb->GetPositionY() < 6630) + DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); + } + } + m_uiTimer = urand(90000, 120000); + } + break; + } + } + else m_uiTimer -= uiDiff; + + ScriptedAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_warmage_coldarraAI(creature); + } +}; + +/*###### +## npc_hidden_cultist +######*/ + +enum eHiddenCultist +{ + SPELL_SHROUD_OF_THE_DEATH_CULTIST = 46077, //not working + SPELL_RIGHTEOUS_VISION = 46078, //player aura + + QUEST_THE_HUNT_IS_ON = 11794, + + GOSSIP_TEXT_SALTY_JOHN_THORPE = 12529, + GOSSIP_TEXT_GUARD_MITCHELSS = 12530, + GOSSIP_TEXT_TOM_HEGGER = 12528, + + NPC_TOM_HEGGER = 25827, + NPC_SALTY_JOHN_THORPE = 25248, + NPC_GUARD_MITCHELLS = 25828, + + SAY_HIDDEN_CULTIST_1 = 0, + SAY_HIDDEN_CULTIST_2 = 1, + SAY_HIDDEN_CULTIST_3 = 2, + SAY_HIDDEN_CULTIST_4 = 3 +}; + +const char* GOSSIP_ITEM_TOM_HEGGER = "What do you know about the Cult of the Damned?"; +const char* GOSSIP_ITEM_GUARD_MITCHELLS = "How long have you worked for the Cult of the Damned?"; +const char* GOSSIP_ITEM_SALTY_JOHN_THORPE = "I have a reason to believe you're involved in the cultist activity"; + +class npc_hidden_cultist : public CreatureScript +{ +public: + npc_hidden_cultist() : CreatureScript("npc_hidden_cultist") { } + + struct npc_hidden_cultistAI : public ScriptedAI + { + npc_hidden_cultistAI(Creature* creature) : ScriptedAI(creature) + { + uiEmoteState = creature->GetUInt32Value(UNIT_NPC_EMOTESTATE); + uiNpcFlags = creature->GetUInt32Value(UNIT_NPC_FLAGS); + } + + uint32 uiEmoteState; + uint32 uiNpcFlags; + + uint32 uiEventTimer; + uint8 uiEventPhase; + + uint64 uiPlayerGUID; + + void Reset() + { + if (uiEmoteState) + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, uiEmoteState); + + if (uiNpcFlags) + me->SetUInt32Value(UNIT_NPC_FLAGS, uiNpcFlags); + + uiEventTimer = 0; + uiEventPhase = 0; + + uiPlayerGUID = 0; + + DoCast(SPELL_SHROUD_OF_THE_DEATH_CULTIST); + + me->RestoreFaction(); + } + + void DoAction(const int32 /*iParam*/) + { + me->StopMoving(); + me->SetUInt32Value(UNIT_NPC_FLAGS, 0); + if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) + { + me->SetInFront(player); + me->SendMovementFlagUpdate(); + } + uiEventTimer = 3000; + uiEventPhase = 1; + } + + void SetGUID(uint64 uiGuid, int32 /*iId*/) + { + uiPlayerGUID = uiGuid; + } + + void AttackPlayer() + { + me->setFaction(14); + if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) + me->AI()->AttackStart(player); + } + + void UpdateAI(const uint32 uiDiff) + { + if (uiEventTimer && uiEventTimer <= uiDiff) + { + switch (uiEventPhase) + { + case 1: + switch (me->GetEntry()) + { + case NPC_SALTY_JOHN_THORPE: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + Talk(SAY_HIDDEN_CULTIST_1); + uiEventTimer = 5000; + uiEventPhase = 2; + break; + case NPC_GUARD_MITCHELLS: + Talk(SAY_HIDDEN_CULTIST_2); + uiEventTimer = 5000; + uiEventPhase = 2; + break; + case NPC_TOM_HEGGER: + Talk(SAY_HIDDEN_CULTIST_3); + uiEventTimer = 5000; + uiEventPhase = 2; + break; + } + break; + case 2: + switch (me->GetEntry()) + { + case NPC_SALTY_JOHN_THORPE: + Talk(SAY_HIDDEN_CULTIST_4); + if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) + { + me->SetInFront(player); + me->SendMovementFlagUpdate(); + } + uiEventTimer = 3000; + uiEventPhase = 3; + break; + case NPC_GUARD_MITCHELLS: + case NPC_TOM_HEGGER: + AttackPlayer(); + uiEventPhase = 0; + break; + } + break; + case 3: + if (me->GetEntry() == NPC_SALTY_JOHN_THORPE) + { + AttackPlayer(); + uiEventPhase = 0; + } + break; + } + }else uiEventTimer -= uiDiff; + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_hidden_cultistAI(creature); + } + + bool OnGossipHello(Player* player, Creature* creature) + { + uint32 uiGossipText = 0; + const char* charGossipItem; + + switch (creature->GetEntry()) + { + case NPC_TOM_HEGGER: + uiGossipText = GOSSIP_TEXT_TOM_HEGGER; + charGossipItem = GOSSIP_ITEM_TOM_HEGGER; + break; + case NPC_SALTY_JOHN_THORPE: + uiGossipText = GOSSIP_TEXT_SALTY_JOHN_THORPE; + charGossipItem = GOSSIP_ITEM_SALTY_JOHN_THORPE; + break; + case NPC_GUARD_MITCHELLS: + uiGossipText = GOSSIP_TEXT_GUARD_MITCHELSS; + charGossipItem = GOSSIP_ITEM_GUARD_MITCHELLS; + break; + default: + charGossipItem = ""; + return false; + } + + if (player->HasAura(SPELL_RIGHTEOUS_VISION) && player->GetQuestStatus(QUEST_THE_HUNT_IS_ON) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, charGossipItem, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + if (creature->isVendor()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(uiGossipText, creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->AI()->SetGUID(player->GetGUID()); + creature->AI()->DoAction(1); + } + + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + +}; + +void AddSC_borean_tundra() +{ + new npc_sinkhole_kill_credit(); + new npc_khunok_the_behemoth(); + new npc_keristrasza(); + new npc_corastrasza(); + new npc_iruk(); + new mob_nerubar_victim(); + new npc_jenny(); + new npc_fezzix_geartwist(); + new npc_nesingwary_trapper(); + new npc_lurgglbr(); + new npc_nexus_drake_hatchling(); + new npc_thassarian(); + new npc_image_lich_king(); + new npc_counselor_talbot(); + new npc_leryssa(); + new npc_general_arlos(); + new npc_beryl_sorcerer(); + new npc_imprisoned_beryl_sorcerer(); + new npc_mootoo_the_younger(); + new npc_bonker_togglevolt(); + new npc_trapped_mammoth_calf(); + new npc_magmoth_crusher(); + new npc_seaforium_depth_charge(); + new npc_valiance_keep_cannoneer(); + new npc_warmage_coldarra(); + new npc_hidden_cultist(); +} diff --git a/src/server/scripts/Northrend/zone_crystalsong_forest.cpp b/src/server/scripts/Northrend/zone_crystalsong_forest.cpp new file mode 100644 index 00000000000..d12b5176b15 --- /dev/null +++ b/src/server/scripts/Northrend/zone_crystalsong_forest.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* Script Data Start +SDName: CrystalSongForest +SDAuthor: Malcrom +SD%Complete: 99% +SDComment: +SDCategory: CrystalsongForest +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Player.h" + +/******************************************************* + * npc_warmage_violetstand + *******************************************************/ + +enum Spells +{ + SPELL_TRANSITUS_SHIELD_BEAM = 48310 +}; + +enum NPCs +{ + NPC_TRANSITUS_SHIELD_DUMMY = 27306, + NPC_WARMAGE_SARINA = 32369, + NPC_WARMAGE_HALISTER = 32371, + NPC_WARMAGE_ILSUDRIA = 32372 +}; + +class npc_warmage_violetstand : public CreatureScript +{ +public: + npc_warmage_violetstand() : CreatureScript("npc_warmage_violetstand") { } + + struct npc_warmage_violetstandAI : public Scripted_NoMovementAI + { + npc_warmage_violetstandAI(Creature* creature) : Scripted_NoMovementAI(creature){} + + uint64 uiTargetGUID; + + void Reset() + { + uiTargetGUID = 0; + } + + void UpdateAI(const uint32 /*uiDiff*/) + { + if (me->IsNonMeleeSpellCasted(false)) + return; + + if (me->GetEntry() == NPC_WARMAGE_SARINA) + { + if (!uiTargetGUID) + { + std::list orbList; + GetCreatureListWithEntryInGrid(orbList, me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f); + if (!orbList.empty()) + { + for (std::list::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr) + { + if (Creature* pOrb = *itr) + { + if (pOrb->GetPositionY() < 1000) + { + uiTargetGUID = pOrb->GetGUID(); + break; + } + } + } + } + } + }else + { + if (!uiTargetGUID) + if (Creature* pOrb = GetClosestCreatureWithEntry(me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f)) + uiTargetGUID = pOrb->GetGUID(); + + } + + if (Creature* pOrb = me->GetCreature(*me, uiTargetGUID)) + DoCast(pOrb, SPELL_TRANSITUS_SHIELD_BEAM); + + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_warmage_violetstandAI(creature); + } +}; + +void AddSC_crystalsong_forest() +{ + new npc_warmage_violetstand; +} diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp new file mode 100644 index 00000000000..d16b6fe4588 --- /dev/null +++ b/src/server/scripts/Northrend/zone_dalaran.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* Script Data Start +SDName: Dalaran +SDAuthor: WarHead, MaXiMiUS +SD%Complete: 99% +SDComment: For what is 63990+63991? Same function but don't work correct... +SDCategory: Dalaran +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "Player.h" +#include "WorldSession.h" + +/******************************************************* + * npc_mageguard_dalaran + *******************************************************/ + +enum Spells +{ + SPELL_TRESPASSER_A = 54028, + SPELL_TRESPASSER_H = 54029, + + SPELL_SUNREAVER_DISGUISE_FEMALE = 70973, + SPELL_SUNREAVER_DISGUISE_MALE = 70974, + SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971, + SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972, +}; + +enum NPCs // All outdoor guards are within 35.0f of these NPCs +{ + NPC_APPLEBOUGH_A = 29547, + NPC_SWEETBERRY_H = 29715, +}; + +class npc_mageguard_dalaran : public CreatureScript +{ +public: + npc_mageguard_dalaran() : CreatureScript("npc_mageguard_dalaran") { } + + struct npc_mageguard_dalaranAI : public Scripted_NoMovementAI + { + npc_mageguard_dalaranAI(Creature* creature) : Scripted_NoMovementAI(creature) + { + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true); + creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); + } + + void Reset(){} + + void EnterCombat(Unit* /*who*/){} + + void AttackStart(Unit* /*who*/){} + + void MoveInLineOfSight(Unit* who) + { + if (!who || !who->IsInWorld() || who->GetZoneId() != 4395) + return; + + if (!me->IsWithinDist(who, 65.0f, false)) + return; + + Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself(); + + if (!player || player->isGameMaster() || player->IsBeingTeleported() || + // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass + player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) || + player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE)) + return; + + switch (me->GetEntry()) + { + case 29254: + if (player->GetTeam() == HORDE) // Horde unit found in Alliance area + { + if (GetClosestCreatureWithEntry(me, NPC_APPLEBOUGH_A, 32.0f)) + { + if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me + DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out + } + else // In my line of sight, and "indoors" + DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out + } + break; + case 29255: + if (player->GetTeam() == ALLIANCE) // Alliance unit found in Horde area + { + if (GetClosestCreatureWithEntry(me, NPC_SWEETBERRY_H, 32.0f)) + { + if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me + DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out + } + else // In my line of sight, and "indoors" + DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out + } + break; + } + me->SetOrientation(me->GetHomePosition().GetOrientation()); + return; + } + + void UpdateAI(const uint32 /*diff*/){} + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_mageguard_dalaranAI(creature); + } +}; + +/*###### +## npc_hira_snowdawn +######*/ + +enum eHiraSnowdawn +{ + SPELL_COLD_WEATHER_FLYING = 54197 +}; + +#define GOSSIP_TEXT_TRAIN_HIRA "I seek training to ride a steed." + +class npc_hira_snowdawn : public CreatureScript +{ +public: + npc_hira_snowdawn() : CreatureScript("npc_hira_snowdawn") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (!creature->isVendor() || !creature->isTrainer()) + return false; + + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_TRAIN_HIRA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); + + if (player->getLevel() >= 80 && player->HasSpell(SPELL_COLD_WEATHER_FLYING)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRAIN) + player->GetSession()->SendTrainerList(creature->GetGUID()); + + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } +}; + +void AddSC_dalaran() +{ + new npc_mageguard_dalaran; + new npc_hira_snowdawn; +} diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp new file mode 100644 index 00000000000..a8fb0215902 --- /dev/null +++ b/src/server/scripts/Northrend/zone_dragonblight.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Dragonblight +SD%Complete: 100 +SDComment: +SDCategory: Dragonblight +EndScriptData */ + +/* ContentData +npc_alexstrasza_wr_gate +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "ScriptedEscortAI.h" +#include "Vehicle.h" +#include "CombatAI.h" +#include "Player.h" + +enum eEnums +{ + QUEST_RETURN_TO_AG_A = 12499, + QUEST_RETURN_TO_AG_H = 12500, + MOVIE_ID_GATES = 14 +}; + +#define GOSSIP_ITEM_WHAT_HAPPENED "Alexstrasza, can you show me what happened here?" + +class npc_alexstrasza_wr_gate : public CreatureScript +{ +public: + npc_alexstrasza_wr_gate() : CreatureScript("npc_alexstrasza_wr_gate") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestRewardStatus(QUEST_RETURN_TO_AG_A) || player->GetQuestRewardStatus(QUEST_RETURN_TO_AG_H)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WHAT_HAPPENED, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + player->SendMovieStart(MOVIE_ID_GATES); + } + + return true; + } +}; + +/*###### +## Quest Strengthen the Ancients (12096|12092) +######*/ + +enum StrengthenAncientsMisc +{ + SAY_WALKER_FRIENDLY = 0, + SAY_WALKER_ENEMY = 1, + SAY_LOTHALOR = 0, + + SPELL_CREATE_ITEM_BARK = 47550, + SPELL_CONFUSED = 47044, + + NPC_LOTHALOR = 26321, + + FACTION_WALKER_ENEMY = 14, +}; + +class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker +{ +public: + spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { } + + class spell_q12096_q12092_dummy_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + uint32 roll = rand() % 2; + + Creature* tree = GetHitCreature(); + Player* player = GetCaster()->ToPlayer(); + + if (!tree || !player) + return; + + tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + + if (roll == 1) // friendly version + { + tree->CastSpell(player, SPELL_CREATE_ITEM_BARK); + tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID()); + tree->DespawnOrUnsummon(1000); + } + else if (roll == 0) // enemy version + { + tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID()); + tree->setFaction(FACTION_WALKER_ENEMY); + tree->Attack(player, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12096_q12092_dummy_SpellScript(); + } +}; + +class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers +{ +public: + spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { } + + class spell_q12096_q12092_bark_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12096_q12092_bark_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Creature* lothalor = GetHitCreature(); + if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR) + return; + + lothalor->AI()->Talk(SAY_LOTHALOR); + lothalor->RemoveAura(SPELL_CONFUSED); + lothalor->DespawnOrUnsummon(4000); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12096_q12092_bark_SpellScript(); + } +}; + +/*###### +## Quest: Defending Wyrmrest Temple ID: 12372 +######*/ + +enum WyrmDefenderEnum +{ + // Quest data + QUEST_DEFENDING_WYRMREST_TEMPLE = 12372, + GOSSIP_TEXTID_DEF1 = 12899, + + // Gossip data + GOSSIP_TEXTID_DEF2 = 12900, + + // Spells data + SPELL_CHARACTER_SCRIPT = 49213, + SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE = 52421, // ID - 52421 Wyrmrest Defender: On Low Health Boss Emote to Controller - Random /self/ + SPELL_RENEW = 49263, // casted to heal drakes + SPELL_WYRMREST_DEFENDER_MOUNT = 49256, + + // Texts data + WHISPER_MOUNTED = 0, + BOSS_EMOTE_ON_LOW_HEALTH = 2 +}; + +#define GOSSIP_ITEM_1 "We need to get into the fight. Are you ready?" + +class npc_wyrmrest_defender : public CreatureScript +{ + public: + npc_wyrmrest_defender() : CreatureScript("npc_wyrmrest_defender") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_DEFENDING_WYRMREST_TEMPLE) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF1, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF2, creature->GetGUID()); + // Makes player cast trigger spell for 49207 on self + player->CastSpell(player, SPELL_CHARACTER_SCRIPT, true); + // The gossip should not auto close + } + + return true; + } + + struct npc_wyrmrest_defenderAI : public VehicleAI + { + npc_wyrmrest_defenderAI(Creature* creature) : VehicleAI(creature) { } + + bool hpWarningReady; + bool renewRecoveryCanCheck; + + uint32 RenewRecoveryChecker; + + void Reset() + { + hpWarningReady = true; + renewRecoveryCanCheck = false; + + RenewRecoveryChecker = 0; + } + + void UpdateAI(uint32 const diff) + { + // Check system for Health Warning should happen first time whenever get under 30%, + // after it should be able to happen only after recovery of last renew is fully done (20 sec), + // next one used won't interfere + if (hpWarningReady && me->GetHealthPct() <= 30.0f) + { + me->CastSpell(me, SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE); + hpWarningReady = false; + } + + if (renewRecoveryCanCheck) + { + if (RenewRecoveryChecker <= diff) + { + renewRecoveryCanCheck = false; + hpWarningReady = true; + } + else RenewRecoveryChecker -= diff; + } + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spell) + { + switch (spell->Id) + { + case SPELL_WYRMREST_DEFENDER_MOUNT: + Talk(WHISPER_MOUNTED, me->GetCharmerOrOwnerGUID()); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + break; + // Both below are for checking low hp warning + case SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE: + Talk(BOSS_EMOTE_ON_LOW_HEALTH, me->GetCharmerOrOwnerGUID()); + break; + case SPELL_RENEW: + if (!hpWarningReady && RenewRecoveryChecker <= 100) + { + RenewRecoveryChecker = 20000; + } + renewRecoveryCanCheck = true; + break; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_wyrmrest_defenderAI(creature); + } +}; + +void AddSC_dragonblight() +{ + new npc_alexstrasza_wr_gate; + new spell_q12096_q12092_dummy; + new spell_q12096_q12092_bark; + new npc_wyrmrest_defender; +} diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp new file mode 100644 index 00000000000..fe1f561071c --- /dev/null +++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp @@ -0,0 +1,705 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "SpellInfo.h" +#include "CreatureTextMgr.h" + +/*###### +## Quest 12027: Mr. Floppy's Perilous Adventure +######*/ + +enum eFloppy +{ + NPC_MRFLOPPY = 26589, + NPC_HUNGRY_WORG = 26586, + NPC_RAVENOUS_WORG = 26590, //RWORG + NPC_EMILY = 26588, + + QUEST_PERILOUS_ADVENTURE = 12027, + + SPELL_MRFLOPPY = 47184, //vehicle aura + + SAY_WORGHAGGRO1 = 0, //Um... I think one of those wolves is back... + SAY_WORGHAGGRO2 = 1, //He's going for Mr. Floppy! + SAY_WORGRAGGRO3 = 2, //Oh, no! Look, it's another wolf, and it's a biiiiiig one! + SAY_WORGRAGGRO4 = 3, //He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta! + SAY_RANDOMAGGRO = 4, //There's a big meanie attacking Mr. Floppy! Help! + SAY_VICTORY1 = 5, //Let's get out of here before more wolves find us! + SAY_VICTORY2 = 6, //Don't go toward the light, Mr. Floppy! + SAY_VICTORY3 = 7, //Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy! + SAY_VICTORY4 = 8, //I think I see the camp! We're almost home, Mr. Floppy! Let's go! + TEXT_EMOTE_WP1 = 9, //Mr. Floppy revives + TEXT_EMOTE_AGGRO = 10, //The Ravenous Worg chomps down on Mr. Floppy + SAY_QUEST_ACCEPT = 11, //Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves! + SAY_QUEST_COMPLETE = 12 //Thank you for helping me get back to the camp. Go tell Walter that I'm safe now! +}; + +//emily +class npc_emily : public CreatureScript +{ +public: + npc_emily() : CreatureScript("npc_emily") { } + + struct npc_emilyAI : public npc_escortAI + { + npc_emilyAI(Creature* creature) : npc_escortAI(creature) { } + + uint32 m_uiChatTimer; + + uint64 RWORGGUID; + uint64 MrfloppyGUID; + + bool Completed; + + void JustSummoned(Creature* summoned) + { + if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 50.0f)) + summoned->AI()->AttackStart(Mrfloppy); + else + summoned->AI()->AttackStart(me->getVictim()); + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 9: + if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f)) + MrfloppyGUID = Mrfloppy->GetGUID(); + break; + case 10: + if (Unit::GetCreature(*me, MrfloppyGUID)) + { + Talk(SAY_WORGHAGGRO1); + me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX()+5, me->GetPositionY()+2, me->GetPositionZ()+1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000); + } + break; + case 11: + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + break; + case 17: + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + Talk(SAY_WORGRAGGRO3); + if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX()+10, me->GetPositionY()+8, me->GetPositionZ()+2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000)) + { + RWORG->setFaction(35); + RWORGGUID = RWORG->GetGUID(); + } + break; + case 18: + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + { + if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) + RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); + DoCast(Mrfloppy, SPELL_MRFLOPPY); + } + break; + case 19: + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + { + if (Mrfloppy->HasAura(SPELL_MRFLOPPY, 0)) + { + if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) + Mrfloppy->EnterVehicle(RWORG); + } + } + break; + case 20: + if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) + RWORG->HandleEmoteCommand(34); + break; + case 21: + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + { + if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) + { + RWORG->Kill(Mrfloppy); + Mrfloppy->ExitVehicle(); + RWORG->setFaction(14); + RWORG->GetMotionMaster()->MovePoint(0, RWORG->GetPositionX()+10, RWORG->GetPositionY()+80, RWORG->GetPositionZ()); + Talk(SAY_VICTORY2); + } + } + break; + case 22: + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + { + if (Mrfloppy->isDead()) + { + if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID)) + RWORG->DisappearAndDie(); + me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ()); + Mrfloppy->setDeathState(ALIVE); + Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + Talk(SAY_VICTORY3); + } + } + break; + case 24: + if (player) + { + Completed = true; + player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me); + Talk(SAY_QUEST_COMPLETE, player->GetGUID()); + } + me->SetWalk(false); + break; + case 25: + Talk(SAY_VICTORY4); + break; + case 27: + me->DisappearAndDie(); + if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID)) + Mrfloppy->DisappearAndDie(); + break; + } + } + + void EnterCombat(Unit* /*Who*/) + { + Talk(SAY_RANDOMAGGRO); + } + + void Reset() + { + m_uiChatTimer = 4000; + MrfloppyGUID = 0; + RWORGGUID = 0; + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (m_uiChatTimer <= uiDiff) + m_uiChatTimer = 12000; + else + m_uiChatTimer -= uiDiff; + } + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_PERILOUS_ADVENTURE) + { + creature->AI()->Talk(SAY_QUEST_ACCEPT); + if (Creature* Mrfloppy = GetClosestCreatureWithEntry(creature, NPC_MRFLOPPY, 180.0f)) + Mrfloppy->GetMotionMaster()->MoveFollow(creature, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_emily::npc_emilyAI, (creature->AI()))) + pEscortAI->Start(true, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_emilyAI(creature); + } +}; + +//mrfloppy +class npc_mrfloppy : public CreatureScript +{ +public: + npc_mrfloppy() : CreatureScript("npc_mrfloppy") { } + + struct npc_mrfloppyAI : public ScriptedAI + { + npc_mrfloppyAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 EmilyGUID; + uint64 RWORGGUID; + uint64 HWORGGUID; + + void Reset() {} + + void EnterCombat(Unit* Who) + { + if (Creature* Emily = GetClosestCreatureWithEntry(me, NPC_EMILY, 50.0f)) + { + switch (Who->GetEntry()) + { + case NPC_HUNGRY_WORG: + Emily->AI()->Talk(SAY_WORGHAGGRO2); + break; + case NPC_RAVENOUS_WORG: + Emily->AI()->Talk(SAY_WORGRAGGRO4); + break; + default: + Emily->AI()->Talk(SAY_RANDOMAGGRO); + } + } + } + + void EnterEvadeMode() {} + + void MoveInLineOfSight(Unit* /*who*/) {} + + void UpdateAI(const uint32 /*diff*/) + { + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_mrfloppyAI(creature); + } +}; + +// Outhouse Bunny + +enum eOuthouseBunny +{ + SPELL_OUTHOUSE_GROANS = 48382, + SPELL_CAMERA_SHAKE = 47533, + SPELL_DUST_FIELD = 48329 +}; + +enum eSounds +{ + SOUND_FEMALE = 12671, + SOUND_MALE = 12670 +}; + +class npc_outhouse_bunny : public CreatureScript +{ +public: + npc_outhouse_bunny() : CreatureScript("npc_outhouse_bunny") { } + + struct npc_outhouse_bunnyAI : public ScriptedAI + { + npc_outhouse_bunnyAI(Creature* creature) : ScriptedAI(creature) {} + + uint8 m_counter; + uint8 m_gender; + + void Reset() + { + m_counter = 0; + m_gender = 0; + } + + void SetData(uint32 uiType, uint32 uiData) + { + if (uiType == 1) + m_gender = uiData; + } + + void SpellHit(Unit* pCaster, const SpellInfo* pSpell) + { + if (pSpell->Id == SPELL_OUTHOUSE_GROANS) + { + ++m_counter; + if (m_counter < 5) + DoCast(pCaster, SPELL_CAMERA_SHAKE, true); + else + m_counter = 0; + DoCast(me, SPELL_DUST_FIELD, true); + switch (m_gender) + { + case GENDER_FEMALE: + DoPlaySoundToSet(me, SOUND_FEMALE); + break; + + case GENDER_MALE: + DoPlaySoundToSet(me, SOUND_MALE); + break; + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_outhouse_bunnyAI(creature); + } +}; + +// Tallhorn Stage + +enum etallhornstage +{ + OBJECT_HAUNCH = 188665 +}; + +class npc_tallhorn_stag : public CreatureScript +{ +public: + npc_tallhorn_stag() : CreatureScript("npc_tallhorn_stag") { } + + struct npc_tallhorn_stagAI : public ScriptedAI + { + npc_tallhorn_stagAI(Creature* creature) : ScriptedAI(creature) {} + + uint8 m_uiPhase; + + void Reset() + { + m_uiPhase = 1; + } + + void UpdateAI(const uint32 /*uiDiff*/) + { + if (m_uiPhase == 1) + { + if (me->FindNearestGameObject(OBJECT_HAUNCH, 2.0f)) + { + me->SetStandState(UNIT_STAND_STATE_DEAD); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); + } + m_uiPhase = 0; + } + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tallhorn_stagAI(creature); + } +}; + +// Amberpine Woodsman + +enum eamberpinewoodsman +{ + TALLHORN_STAG = 26363 +}; + +class npc_amberpine_woodsman : public CreatureScript +{ +public: + npc_amberpine_woodsman() : CreatureScript("npc_amberpine_woodsman") { } + + struct npc_amberpine_woodsmanAI : public ScriptedAI + { + npc_amberpine_woodsmanAI(Creature* creature) : ScriptedAI(creature) {} + + uint8 m_uiPhase; + uint32 m_uiTimer; + + void Reset() + { + m_uiTimer = 0; + m_uiPhase = 1; + } + + void UpdateAI(const uint32 uiDiff) + { + // call this each update tick? + if (me->FindNearestCreature(TALLHORN_STAG, 0.2f)) + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); + } + else + if (m_uiPhase) + { + if (m_uiTimer <= uiDiff) + { + switch (m_uiPhase) + { + case 1: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LOOT); + m_uiTimer = 3000; + m_uiPhase = 2; + break; + case 2: + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H); + m_uiTimer = 4000; + m_uiPhase = 1; + break; + } + } + else + m_uiTimer -= uiDiff; + } + ScriptedAI::UpdateAI(uiDiff); + + UpdateVictim(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_amberpine_woodsmanAI(creature); + } +}; +/*###### +## Quest 12288: Overwhelmed! +######*/ + +enum eSkirmisher +{ + SPELL_RENEW_SKIRMISHER = 48812, + CREDIT_NPC = 27466, + + RANDOM_SAY = 0, +}; + +class npc_wounded_skirmisher : public CreatureScript +{ +public: + npc_wounded_skirmisher() : CreatureScript("npc_wounded_skirmisher") { } + + struct npc_wounded_skirmisherAI : public ScriptedAI + { + npc_wounded_skirmisherAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 uiPlayerGUID; + + uint32 DespawnTimer; + + void Reset() + { + DespawnTimer = 5000; + uiPlayerGUID = 0; + } + + void MovementInform(uint32, uint32 id) + { + if (id == 1) + me->DespawnOrUnsummon(DespawnTimer); + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id == SPELL_RENEW_SKIRMISHER && caster->GetTypeId() == TYPEID_PLAYER + && caster->ToPlayer()->GetQuestStatus(12288) == QUEST_STATUS_INCOMPLETE) + { + caster->ToPlayer()->KilledMonsterCredit(CREDIT_NPC, 0); + sCreatureTextMgr->SendChat(me, RANDOM_SAY, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, caster->ToPlayer()); + if (me->IsStandState()) + me->GetMotionMaster()->MovePoint(1, me->GetPositionX()+7, me->GetPositionY()+7, me->GetPositionZ()); + else + { + me->SetStandState(UNIT_STAND_STATE_STAND); + me->DespawnOrUnsummon(DespawnTimer); + } + } + } + + void UpdateAI(const uint32 /*diff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_wounded_skirmisherAI(creature); + } +}; + +/*Lightning Sentry - if you kill it when you have your Minion with you, you will get a quest credit*/ +enum eSentry +{ + QUEST_OR_MAYBE_WE_DONT_A = 12138, + QUEST_OR_MAYBE_WE_DONT_H = 12198, + + NPC_LIGHTNING_SENTRY = 26407, + NPC_WAR_GOLEM = 27017, + + SPELL_CHARGED_SENTRY_TOTEM = 52703, +}; + +class npc_lightning_sentry : public CreatureScript +{ +public: + npc_lightning_sentry() : CreatureScript("npc_lightning_sentry") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_lightning_sentryAI(creature); + } + + struct npc_lightning_sentryAI : public ScriptedAI + { + npc_lightning_sentryAI(Creature* creature) : ScriptedAI(creature) { } + + uint32 uiChargedSentryTotem; + + void Reset() + { + uiChargedSentryTotem = urand(10000, 12000); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (uiChargedSentryTotem <= uiDiff) + { + DoCast(SPELL_CHARGED_SENTRY_TOTEM); + uiChargedSentryTotem = urand(10000, 12000); + } + else + uiChargedSentryTotem -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + if (killer->ToPlayer() && killer->ToPlayer()->GetTypeId() == TYPEID_PLAYER) + { + if (me->FindNearestCreature(NPC_WAR_GOLEM, 10.0f, true)) + { + if (killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_A) == QUEST_STATUS_INCOMPLETE || + killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_H) == QUEST_STATUS_INCOMPLETE) + killer->ToPlayer()->KilledMonsterCredit(NPC_WAR_GOLEM, 0); + } + } + } + }; +}; + +/*Venture co. Straggler - when you cast Smoke Bomb, he will yell and run away*/ +enum eSmokeEmOut +{ + SAY_SEO = 0, + QUEST_SMOKE_EM_OUT_A = 12323, + QUEST_SMOKE_EM_OUT_H = 12324, + SPELL_SMOKE_BOMB = 49075, + SPELL_CHOP = 43410, + SPELL_VENTURE_STRAGGLER_CREDIT = 49093, +}; + +class npc_venture_co_straggler : public CreatureScript +{ + public: + npc_venture_co_straggler() : CreatureScript("npc_venture_co_straggler") { } + + struct npc_venture_co_stragglerAI : public ScriptedAI + { + npc_venture_co_stragglerAI(Creature* creature) : ScriptedAI(creature) { } + + uint64 uiPlayerGUID; + uint32 uiRunAwayTimer; + uint32 uiTimer; + uint32 uiChopTimer; + + void Reset() + { + uiPlayerGUID = 0; + uiTimer = 0; + uiRunAwayTimer = 0; + uiChopTimer = urand(10000, 12500); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_AGGRESSIVE); + } + + void UpdateAI(const uint32 uiDiff) + { + if (uiPlayerGUID && uiRunAwayTimer <= uiDiff) + { + if (Player* player = Unit::GetPlayer(*me, uiPlayerGUID)) + { + switch (uiTimer) + { + case 0: + DoCast(player, SPELL_VENTURE_STRAGGLER_CREDIT); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()+7, me->GetPositionZ()); + uiRunAwayTimer = 2500; + ++uiTimer; + break; + case 1: + Talk(SAY_SEO); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()-5, me->GetPositionZ()); + uiRunAwayTimer = 2500; + ++uiTimer; + break; + case 2: + me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-5, me->GetPositionY()-5, me->GetPositionZ()); + uiRunAwayTimer = 2500; + ++uiTimer; + break; + case 3: + me->DisappearAndDie(); + uiTimer = 0; + break; + } + } + } + else if (uiRunAwayTimer) + uiRunAwayTimer -= uiDiff; + + if (!UpdateVictim()) + return; + + if (uiChopTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_CHOP); + uiChopTimer = urand(10000, 12000); + } + else + uiChopTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) + { + if (spell->Id == SPELL_SMOKE_BOMB && caster->GetTypeId() == TYPEID_PLAYER) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_PASSIVE); + me->CombatStop(false); + uiPlayerGUID = caster->GetGUID(); + uiRunAwayTimer = 3500; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_venture_co_stragglerAI(creature); + } +}; + +void AddSC_grizzly_hills() +{ + new npc_emily(); + new npc_mrfloppy(); + new npc_outhouse_bunny(); + new npc_tallhorn_stag(); + new npc_amberpine_woodsman(); + new npc_wounded_skirmisher(); + new npc_lightning_sentry(); + new npc_venture_co_straggler(); +} diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp new file mode 100644 index 00000000000..ff4d8ec7a79 --- /dev/null +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* ScriptData +SDName: Sholazar_Basin +SD%Complete: 100 +SDComment: Quest support: 11253, 11241. +SDCategory: howling_fjord +EndScriptData */ + +/* ContentData +npc_plaguehound_tracker +npc_apothecary_hanes +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_apothecary_hanes +######*/ +enum Entries +{ + NPC_APOTHECARY_HANES = 23784, + FACTION_ESCORTEE_A = 774, + FACTION_ESCORTEE_H = 775, + NPC_HANES_FIRE_TRIGGER = 23968, + QUEST_TRAIL_OF_FIRE = 11241, + SPELL_COSMETIC_LOW_POLY_FIRE = 56274 +}; + +class npc_apothecary_hanes : public CreatureScript +{ +public: + npc_apothecary_hanes() : CreatureScript("npc_apothecary_hanes") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_TRAIL_OF_FIRE) + { + switch (player->GetTeam()) + { + case ALLIANCE: + creature->setFaction(FACTION_ESCORTEE_A); + break; + case HORDE: + creature->setFaction(FACTION_ESCORTEE_H); + break; + } + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + } + return true; + } + + struct npc_Apothecary_HanesAI : public npc_escortAI + { + npc_Apothecary_HanesAI(Creature* creature) : npc_escortAI(creature){} + uint32 PotTimer; + + void Reset() + { + SetDespawnAtFar(false); + PotTimer = 10000; //10 sec cooldown on potion + } + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_TRAIL_OF_FIRE); + } + + void UpdateEscortAI(const uint32 diff) + { + if (HealthBelowPct(75)) + { + if (PotTimer <= diff) + { + DoCast(me, 17534, true); + PotTimer = 10000; + } else PotTimer -= diff; + } + if (GetAttack() && UpdateVictim()) + DoMeleeAttackIfReady(); + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 1: + me->SetReactState(REACT_AGGRESSIVE); + SetRun(true); + break; + case 23: + player->GroupEventHappens(QUEST_TRAIL_OF_FIRE, me); + me->DespawnOrUnsummon(); + break; + case 5: + if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) + Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); + SetRun(false); + break; + case 6: + if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) + Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); + SetRun(true); + break; + case 8: + if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) + Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); + SetRun(false); + break; + case 9: + if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) + Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); + break; + case 10: + SetRun(true); + break; + case 13: + SetRun(false); + break; + case 14: + if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER, 10.0f)) + Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false); + SetRun(true); + break; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_Apothecary_HanesAI(creature); + } +}; + +/*###### +## npc_plaguehound_tracker +######*/ + +enum ePlaguehound +{ + QUEST_SNIFF_OUT_ENEMY = 11253 +}; + +class npc_plaguehound_tracker : public CreatureScript +{ +public: + npc_plaguehound_tracker() : CreatureScript("npc_plaguehound_tracker") { } + + struct npc_plaguehound_trackerAI : public npc_escortAI + { + npc_plaguehound_trackerAI(Creature* creature) : npc_escortAI(creature) { } + + void Reset() + { + uint64 summonerGUID = 0; + + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (summoner->GetTypeId() == TYPEID_PLAYER) + summonerGUID = summoner->GetGUID(); + + if (!summonerGUID) + return; + + me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); + Start(false, false, summonerGUID); + } + + void WaypointReached(uint32 waypointId) + { + if (waypointId != 26) + return; + + me->DespawnOrUnsummon(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_plaguehound_trackerAI(creature); + } +}; + +/*###### +## npc_razael_and_lyana +######*/ + +#define GOSSIP_RAZAEL_REPORT "High Executor Anselm wants a report on the situation." +#define GOSSIP_LYANA_REPORT "High Executor Anselm requests your report." + +enum eRazael +{ + QUEST_REPORTS_FROM_THE_FIELD = 11221, + NPC_RAZAEL = 23998, + NPC_LYANA = 23778, + GOSSIP_TEXTID_RAZAEL1 = 11562, + GOSSIP_TEXTID_RAZAEL2 = 11564, + GOSSIP_TEXTID_LYANA1 = 11586, + GOSSIP_TEXTID_LYANA2 = 11588 +}; + +class npc_razael_and_lyana : public CreatureScript +{ +public: + npc_razael_and_lyana() : CreatureScript("npc_razael_and_lyana") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_REPORTS_FROM_THE_FIELD) == QUEST_STATUS_INCOMPLETE) + switch (creature->GetEntry()) + { + case NPC_RAZAEL: + if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_RAZAEL)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_RAZAEL_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL1, creature->GetGUID()); + return true; + } + break; + case NPC_LYANA: + if (!player->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_LYANA)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LYANA_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA1, creature->GetGUID()); + return true; + } + break; + } + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL2, creature->GetGUID()); + player->TalkedToCreature(NPC_RAZAEL, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA2, creature->GetGUID()); + player->TalkedToCreature(NPC_LYANA, creature->GetGUID()); + break; + } + return true; + } +}; + +/*###### +## npc_mcgoyver +######*/ + +#define GOSSIP_ITEM_MG_I "Walt sent me to pick up some dark iron ingots." +#define GOSSIP_ITEM_MG_II "Yarp." + +enum eMcGoyver +{ + QUEST_WE_CAN_REBUILD_IT = 11483, + + SPELL_CREATURE_DARK_IRON_INGOTS = 44512, + SPELL_TAXI_EXPLORERS_LEAGUE = 44280, + + GOSSIP_TEXTID_MCGOYVER = 12193 +}; + +class npc_mcgoyver : public CreatureScript +{ +public: + npc_mcgoyver() : CreatureScript("npc_mcgoyver") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_WE_CAN_REBUILD_IT) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_II, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, creature->GetGUID()); + player->CastSpell(player, SPELL_CREATURE_DARK_IRON_INGOTS, true); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->CastSpell(player, SPELL_TAXI_EXPLORERS_LEAGUE, true); + player->CLOSE_GOSSIP_MENU(); + break; + } + return true; + } +}; + +/*###### +## npc_daegarn +######*/ + +enum eDaegarnn +{ + QUEST_DEFEAT_AT_RING = 11300, + + NPC_FIRJUS = 24213, + NPC_JLARBORN = 24215, + NPC_YOROS = 24214, + NPC_OLUF = 23931, + + NPC_PRISONER_1 = 24253, // looks the same but has different abilities + NPC_PRISONER_2 = 24254, + NPC_PRISONER_3 = 24255, +}; + +static float afSummon[] = {838.81f, -4678.06f, -94.182f}; +static float afCenter[] = {801.88f, -4721.87f, -96.143f}; + +class npc_daegarn : public CreatureScript +{ +public: + npc_daegarn() : CreatureScript("npc_daegarn") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_DEFEAT_AT_RING) + { + if (npc_daegarnAI* pDaegarnAI = CAST_AI(npc_daegarn::npc_daegarnAI, creature->AI())) + pDaegarnAI->StartEvent(player->GetGUID()); + } + + return true; + } + + // TODO: make prisoners help (unclear if summoned or using npc's from surrounding cages (summon inside small cages?)) + struct npc_daegarnAI : public ScriptedAI + { + npc_daegarnAI(Creature* creature) : ScriptedAI(creature) { } + + bool bEventInProgress; + uint64 uiPlayerGUID; + + void Reset() + { + bEventInProgress = false; + uiPlayerGUID = 0; + } + + void StartEvent(uint64 uiGUID) + { + if (bEventInProgress) + return; + + uiPlayerGUID = uiGUID; + + SummonGladiator(NPC_FIRJUS); + } + + void JustSummoned(Creature* summon) + { + if (Player* player = me->GetPlayer(*me, uiPlayerGUID)) + { + if (player->isAlive()) + { + summon->SetWalk(false); + summon->GetMotionMaster()->MovePoint(0, afCenter[0], afCenter[1], afCenter[2]); + summon->AI()->AttackStart(player); + return; + } + } + + Reset(); + } + + void SummonGladiator(uint32 uiEntry) + { + me->SummonCreature(uiEntry, afSummon[0], afSummon[1], afSummon[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30*IN_MILLISECONDS); + } + + void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) + { + uint32 uiEntry = 0; + + // will eventually reset the event if something goes wrong + switch (summoned->GetEntry()) + { + case NPC_FIRJUS: uiEntry = NPC_JLARBORN; break; + case NPC_JLARBORN: uiEntry = NPC_YOROS; break; + case NPC_YOROS: uiEntry = NPC_OLUF; break; + case NPC_OLUF: Reset(); return; + } + + SummonGladiator(uiEntry); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_daegarnAI(creature); + } +}; + +void AddSC_howling_fjord() +{ + new npc_apothecary_hanes; + new npc_plaguehound_tracker; + new npc_razael_and_lyana; + new npc_mcgoyver; + new npc_daegarn; + } diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp new file mode 100644 index 00000000000..2ec5a3e8164 --- /dev/null +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -0,0 +1,878 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Icecrown +SD%Complete: 100 +SDComment: Quest support: 12807 +SDCategory: Icecrown +EndScriptData */ + +/* ContentData +npc_arete +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "SpellAuras.h" +#include "Player.h" + +/*###### +## npc_arete +######*/ + +#define GOSSIP_ARETE_ITEM1 "Lord-Commander, I would hear your tale." +#define GOSSIP_ARETE_ITEM2 "" +#define GOSSIP_ARETE_ITEM3 "I thought that they now called themselves the Scarlet Onslaught?" +#define GOSSIP_ARETE_ITEM4 "Where did the grand admiral go?" +#define GOSSIP_ARETE_ITEM5 "That's fine. When do I start?" +#define GOSSIP_ARETE_ITEM6 "Let's finish this!" +#define GOSSIP_ARETE_ITEM7 "That's quite a tale, Lord-Commander." + +enum eArete +{ + GOSSIP_TEXTID_ARETE1 = 13525, + GOSSIP_TEXTID_ARETE2 = 13526, + GOSSIP_TEXTID_ARETE3 = 13527, + GOSSIP_TEXTID_ARETE4 = 13528, + GOSSIP_TEXTID_ARETE5 = 13529, + GOSSIP_TEXTID_ARETE6 = 13530, + GOSSIP_TEXTID_ARETE7 = 13531, + + QUEST_THE_STORY_THUS_FAR = 12807 +}; + +class npc_arete : public CreatureScript +{ +public: + npc_arete() : CreatureScript("npc_arete") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_THE_STORY_THUS_FAR) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE1, creature->GetGUID()); + return true; + } + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE2, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE3, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE4, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE5, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE6, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE7, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(QUEST_THE_STORY_THUS_FAR); + break; + } + + return true; + } +}; + +/*###### +## npc_squire_david +######*/ + +enum eSquireDavid +{ + QUEST_THE_ASPIRANT_S_CHALLENGE_H = 13680, + QUEST_THE_ASPIRANT_S_CHALLENGE_A = 13679, + + NPC_ARGENT_VALIANT = 33448, + + GOSSIP_TEXTID_SQUIRE = 14407 +}; + +#define GOSSIP_SQUIRE_ITEM_1 "I am ready to fight!" +#define GOSSIP_SQUIRE_ITEM_2 "How do the Argent Crusader raiders fight?" + +class npc_squire_david : public CreatureScript +{ +public: + npc_squire_david() : CreatureScript("npc_squire_david") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_THE_ASPIRANT_S_CHALLENGE_H) == QUEST_STATUS_INCOMPLETE || + player->GetQuestStatus(QUEST_THE_ASPIRANT_S_CHALLENGE_A) == QUEST_STATUS_INCOMPLETE)//We need more info about it. + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SQUIRE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SQUIRE_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + } + + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_SQUIRE, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->SummonCreature(NPC_ARGENT_VALIANT, 8575.451f, 952.472f, 547.554f, 0.38f); + } + return true; + } +}; + +/*###### +## npc_argent_valiant +######*/ + +enum eArgentValiant +{ + SPELL_CHARGE = 63010, + SPELL_SHIELD_BREAKER = 65147, + SPELL_KILL_CREDIT = 63049 +}; + +class npc_argent_valiant : public CreatureScript +{ +public: + npc_argent_valiant() : CreatureScript("npc_argent_valiant") { } + + struct npc_argent_valiantAI : public ScriptedAI + { + npc_argent_valiantAI(Creature* creature) : ScriptedAI(creature) + { + creature->GetMotionMaster()->MovePoint(0, 8599.258f, 963.951f, 547.553f); + creature->setFaction(35); //wrong faction in db? + } + + uint32 uiChargeTimer; + uint32 uiShieldBreakerTimer; + + void Reset() + { + uiChargeTimer = 7000; + uiShieldBreakerTimer = 10000; + } + + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + + me->setFaction(14); + } + + void DamageTaken(Unit* pDoneBy, uint32& uiDamage) + { + if (uiDamage > me->GetHealth() && pDoneBy->GetTypeId() == TYPEID_PLAYER) + { + uiDamage = 0; + pDoneBy->CastSpell(pDoneBy, SPELL_KILL_CREDIT, true); + me->setFaction(35); + me->DespawnOrUnsummon(5000); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + EnterEvadeMode(); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (uiChargeTimer <= uiDiff) + { + DoCastVictim(SPELL_CHARGE); + uiChargeTimer = 7000; + } else uiChargeTimer -= uiDiff; + + if (uiShieldBreakerTimer <= uiDiff) + { + DoCastVictim(SPELL_SHIELD_BREAKER); + uiShieldBreakerTimer = 10000; + } else uiShieldBreakerTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_argent_valiantAI(creature); + } +}; + +/*###### +## npc_guardian_pavilion +######*/ + +enum eGuardianPavilion +{ + SPELL_TRESPASSER_H = 63987, + AREA_SUNREAVER_PAVILION = 4676, + + AREA_SILVER_COVENANT_PAVILION = 4677, + SPELL_TRESPASSER_A = 63986, +}; + +class npc_guardian_pavilion : public CreatureScript +{ +public: + npc_guardian_pavilion() : CreatureScript("npc_guardian_pavilion") { } + + struct npc_guardian_pavilionAI : public Scripted_NoMovementAI + { + npc_guardian_pavilionAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + + void MoveInLineOfSight(Unit* who) + { + if (me->GetAreaId() != AREA_SUNREAVER_PAVILION && me->GetAreaId() != AREA_SILVER_COVENANT_PAVILION) + return; + + if (!who || who->GetTypeId() != TYPEID_PLAYER || !me->IsHostileTo(who) || !me->isInBackInMap(who, 5.0f)) + return; + + if (who->HasAura(SPELL_TRESPASSER_H) || who->HasAura(SPELL_TRESPASSER_A)) + return; + + if (who->ToPlayer()->GetTeamId() == TEAM_ALLIANCE) + who->CastSpell(who, SPELL_TRESPASSER_H, true); + else + who->CastSpell(who, SPELL_TRESPASSER_A, true); + + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_guardian_pavilionAI(creature); + } +}; + +/*###### +## npc_vereth_the_cunning +######*/ + +enum eVerethTheCunning +{ + NPC_GEIST_RETURN_BUNNY_KC = 31049, + NPC_LITHE_STALKER = 30894, + SPELL_SUBDUED_LITHE_STALKER = 58151, +}; + +class npc_vereth_the_cunning : public CreatureScript +{ +public: + npc_vereth_the_cunning() : CreatureScript("npc_vereth_the_cunning") { } + + struct npc_vereth_the_cunningAI : public ScriptedAI + { + npc_vereth_the_cunningAI(Creature* creature) : ScriptedAI(creature) {} + + void MoveInLineOfSight(Unit* who) + { + ScriptedAI::MoveInLineOfSight(who); + + if (who->GetEntry() == NPC_LITHE_STALKER && me->IsWithinDistInMap(who, 10.0f)) + { + if (Unit* owner = who->GetCharmer()) + { + if (who->HasAura(SPELL_SUBDUED_LITHE_STALKER)) + { + owner->ToPlayer()->KilledMonsterCredit(NPC_GEIST_RETURN_BUNNY_KC, 0); + who->ToCreature()->DisappearAndDie(); + + } + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_vereth_the_cunningAI(creature); + } +}; + +/*###### +* npc_tournament_training_dummy +######*/ +enum TournamentDummy +{ + NPC_CHARGE_TARGET = 33272, + NPC_MELEE_TARGET = 33229, + NPC_RANGED_TARGET = 33243, + + SPELL_CHARGE_CREDIT = 62658, + SPELL_MELEE_CREDIT = 62672, + SPELL_RANGED_CREDIT = 62673, + + SPELL_PLAYER_THRUST = 62544, + SPELL_PLAYER_BREAK_SHIELD = 62626, + SPELL_PLAYER_CHARGE = 62874, + + SPELL_RANGED_DEFEND = 62719, + SPELL_CHARGE_DEFEND = 64100, + SPELL_VULNERABLE = 62665, + + SPELL_COUNTERATTACK = 62709, + + EVENT_DUMMY_RECAST_DEFEND = 1, + EVENT_DUMMY_RESET = 2, +}; + +class npc_tournament_training_dummy : public CreatureScript +{ + public: + npc_tournament_training_dummy(): CreatureScript("npc_tournament_training_dummy"){} + + struct npc_tournament_training_dummyAI : Scripted_NoMovementAI + { + npc_tournament_training_dummyAI(Creature* creature) : Scripted_NoMovementAI(creature) {} + + EventMap events; + bool isVulnerable; + + void Reset() + { + me->SetControlled(true, UNIT_STATE_STUNNED); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); + isVulnerable = false; + + // Cast Defend spells to max stack size + switch (me->GetEntry()) + { + case NPC_CHARGE_TARGET: + DoCast(SPELL_CHARGE_DEFEND); + break; + case NPC_RANGED_TARGET: + me->CastCustomSpell(SPELL_RANGED_DEFEND, SPELLVALUE_AURA_STACK, 3, me); + break; + } + + events.Reset(); + events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000); + } + + void EnterEvadeMode() + { + if (!_EnterEvadeMode()) + return; + + Reset(); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + damage = 0; + events.RescheduleEvent(EVENT_DUMMY_RESET, 10000); + } + + void SpellHit(Unit* caster, SpellInfo const* spell) + { + switch (me->GetEntry()) + { + case NPC_CHARGE_TARGET: + if (spell->Id == SPELL_PLAYER_CHARGE) + if (isVulnerable) + DoCast(caster, SPELL_CHARGE_CREDIT, true); + break; + case NPC_MELEE_TARGET: + if (spell->Id == SPELL_PLAYER_THRUST) + { + DoCast(caster, SPELL_MELEE_CREDIT, true); + + if (Unit* target = caster->GetVehicleBase()) + DoCast(target, SPELL_COUNTERATTACK, true); + } + break; + case NPC_RANGED_TARGET: + if (spell->Id == SPELL_PLAYER_BREAK_SHIELD) + if (isVulnerable) + DoCast(caster, SPELL_RANGED_CREDIT, true); + break; + } + + if (spell->Id == SPELL_PLAYER_BREAK_SHIELD) + if (!me->HasAura(SPELL_CHARGE_DEFEND) && !me->HasAura(SPELL_RANGED_DEFEND)) + isVulnerable = true; + } + + void UpdateAI(uint32 const diff) + { + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_DUMMY_RECAST_DEFEND: + switch (me->GetEntry()) + { + case NPC_CHARGE_TARGET: + { + if (!me->HasAura(SPELL_CHARGE_DEFEND)) + DoCast(SPELL_CHARGE_DEFEND); + break; + } + case NPC_RANGED_TARGET: + { + Aura* defend = me->GetAura(SPELL_RANGED_DEFEND); + if (!defend || defend->GetStackAmount() < 3 || defend->GetDuration() <= 8000) + DoCast(SPELL_RANGED_DEFEND); + break; + } + } + isVulnerable = false; + events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000); + break; + case EVENT_DUMMY_RESET: + if (UpdateVictim()) + { + EnterEvadeMode(); + events.ScheduleEvent(EVENT_DUMMY_RESET, 10000); + } + break; + } + + if (!UpdateVictim()) + return; + + if (!me->HasUnitState(UNIT_STATE_STUNNED)) + me->SetControlled(true, UNIT_STATE_STUNNED); + } + + void MoveInLineOfSight(Unit* /*who*/){} + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tournament_training_dummyAI(creature); + } + +}; + +// Battle for Crusaders' Pinnacle +enum BlessedBanner +{ + SPELL_BLESSING_OF_THE_CRUSADE = 58026, + SPELL_THREAT_PULSE = 58113, + SPELL_CRUSADERS_SPIRE_VICTORY = 58084, + SPELL_TORCH = 58121, + + NPC_BLESSED_BANNER = 30891, + NPC_CRUSADER_LORD_DALFORS = 31003, + NPC_ARGENT_BATTLE_PRIEST = 30919, + NPC_ARGENT_MASON = 30900, + NPC_REANIMATED_CAPTAIN = 30986, + NPC_SCOURGE_DRUDGE = 30984, + NPC_HIDEOUS_PLAGEBRINGER = 30987, + NPC_HALOF_THE_DEATHBRINGER = 30989, + NPC_LK = 31013, + + BANNER_SAY = 0, // "The Blessed Banner of the Crusade has been planted.\n Defend the banner from all attackers!" + DALFORS_SAY_PRE_1 = 0, // "BY THE LIGHT! Those damned monsters! Look at what they've done to our people!" + DALFORS_SAY_PRE_2 = 1, // "Burn it down, boys. Burn it all down." + DALFORS_SAY_START = 2, // "Let 'em come. They'll pay for what they've done!" + DALFORS_YELL_FINISHED = 3, // "We've done it, lads! We've taken the pinnacle from the Scourge! Report to Father Gustav at once and tell him the good news! We're gonna get to buildin' and settin' up! Go!" + LK_TALK_1 = 0, // "Leave no survivors!" + LK_TALK_2 = 1, // "Cower before my terrible creations!" + LK_TALK_3 = 2, // "Feast my children! Feast upon the flesh of the living!" + LK_TALK_4 = 3, // "Lay down your arms and surrender your souls!" + + EVENT_SPAWN = 1, + EVENT_INTRO_1 = 2, + EVENT_INTRO_2 = 3, + EVENT_INTRO_3 = 4, + EVENT_MASON_ACTION = 5, + EVENT_START_FIGHT = 6, + EVENT_WAVE_SPAWN = 7, + EVENT_HALOF = 8, + EVENT_ENDED = 9, +}; + +Position const DalforsPos[3] = +{ + {6458.703f, 403.858f, 490.498f, 3.1205f}, // Dalfors spawn point + {6422.950f, 423.335f, 510.451f, 0.0f}, // Dalfors intro pos + {6426.343f, 420.515f, 508.650f, 0.0f}, // Dalfors fight pos +}; + +Position const Priest1Pos[2] = +{ + {6462.025f, 403.681f, 489.721f, 3.1007f}, // priest1 spawn point + {6421.480f, 423.576f, 510.781f, 5.7421f}, // priest1 intro pos +}; + +Position const Priest2Pos[2] = +{ + {6463.969f, 407.198f, 489.240f, 2.2689f}, // priest2 spawn point + {6419.778f, 421.404f, 510.972f, 5.7421f}, // priest2 intro pos +}; + +Position const Priest3Pos[2] = +{ + {6464.371f, 400.944f, 489.186f, 6.1610f}, // priest3 spawn point + {6423.516f, 425.782f, 510.774f, 5.7421f}, // priest3 intro pos +}; + +Position const Mason1Pos[3] = +{ + {6462.929f, 409.826f, 489.392f, 3.0968f}, // mason1 spawn point + {6428.163f, 421.960f, 508.297f, 0.0f}, // mason1 intro pos + {6414.335f, 454.904f, 511.395f, 2.8972f}, // mason1 action pos +}; + +Position const Mason2Pos[3] = +{ + {6462.650f, 405.670f, 489.576f, 2.9414f}, // mason2 spawn point + {6426.250f, 419.194f, 508.219f, 0.0f}, // mason2 intro pos + {6415.014f, 446.849f, 511.395f, 3.1241f}, // mason2 action pos +}; + +Position const Mason3Pos[3] = +{ + {6462.646f, 401.218f, 489.601f, 2.7864f}, // mason3 spawn point + {6423.855f, 416.598f, 508.305f, 0.0f}, // mason3 intro pos + {6417.070f, 438.824f, 511.395f, 3.6651f}, // mason3 action pos +}; + +class npc_blessed_banner : public CreatureScript +{ +public: + npc_blessed_banner() : CreatureScript("npc_blessed_banner") { } + + struct npc_blessed_bannerAI : public Scripted_NoMovementAI + { + npc_blessed_bannerAI(Creature* creature) : Scripted_NoMovementAI(creature) , Summons(me) + { + HalofSpawned = false; + PhaseCount = 0; + Summons.DespawnAll(); + } + + EventMap events; + + bool HalofSpawned; + + uint32 PhaseCount; + + SummonList Summons; + + uint64 guidDalfors; + uint64 guidPriest[3]; + uint64 guidMason[3]; + uint64 guidHalof; + + void Reset() + { + me->setRegeneratingHealth(false); + DoCast(SPELL_THREAT_PULSE); + me->AI()->Talk(BANNER_SAY); + events.ScheduleEvent(EVENT_SPAWN,3000); + } + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* /*who*/) {} + + void JustSummoned(Creature* Summoned) + { + Summons.Summon(Summoned); + } + + void JustDied(Unit* /*killer*/) + { + Summons.DespawnAll(); + me->DespawnOrUnsummon(); + } + + void UpdateAI(uint32 const diff) + { + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_SPAWN: + { + if (Creature* Dalfors = DoSummon(NPC_CRUSADER_LORD_DALFORS, DalforsPos[0])) + { + guidDalfors = Dalfors->GetGUID(); + Dalfors->GetMotionMaster()->MovePoint(0, DalforsPos[1]); + } + if (Creature* Priest1 = DoSummon(NPC_ARGENT_BATTLE_PRIEST, Priest1Pos[0])) + { + guidPriest[0] = Priest1->GetGUID(); + Priest1->GetMotionMaster()->MovePoint(0, Priest1Pos[1]); + } + if (Creature* Priest2 = DoSummon(NPC_ARGENT_BATTLE_PRIEST, Priest2Pos[0])) + { + guidPriest[1] = Priest2->GetGUID(); + Priest2->GetMotionMaster()->MovePoint(0, Priest2Pos[1]); + } + if (Creature* Priest3 = DoSummon(NPC_ARGENT_BATTLE_PRIEST, Priest3Pos[0])) + { + guidPriest[2] = Priest3->GetGUID(); + Priest3->GetMotionMaster()->MovePoint(0, Priest3Pos[1]); + } + if (Creature* Mason1 = DoSummon(NPC_ARGENT_MASON, Mason1Pos[0])) + { + guidMason[0] = Mason1->GetGUID(); + Mason1->GetMotionMaster()->MovePoint(0, Mason1Pos[1]); + } + if (Creature* Mason2 = DoSummon(NPC_ARGENT_MASON, Mason2Pos[0])) + { + guidMason[1] = Mason2->GetGUID(); + Mason2->GetMotionMaster()->MovePoint(0, Mason2Pos[1]); + } + if (Creature* Mason3 = DoSummon(NPC_ARGENT_MASON, Mason3Pos[0])) + { + guidMason[2] = Mason3->GetGUID(); + Mason3->GetMotionMaster()->MovePoint(0, Mason3Pos[1]); + } + events.ScheduleEvent(EVENT_INTRO_1,15000); + } + break; + case EVENT_INTRO_1: + { + if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) + Dalfors->AI()->Talk(DALFORS_SAY_PRE_1); + events.ScheduleEvent(EVENT_INTRO_2,5000); + } + break; + case EVENT_INTRO_2: + { + if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) + { + Dalfors->SetFacingTo(6.215f); + Dalfors->AI()->Talk(DALFORS_SAY_PRE_2); + } + events.ScheduleEvent(EVENT_INTRO_3,5000); + } + break; + case EVENT_INTRO_3: + { + if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) + { + Dalfors->GetMotionMaster()->MovePoint(0, DalforsPos[2]); + Dalfors->SetHomePosition(DalforsPos[2]); + } + if (Creature* Priest1 = me->GetCreature(*me,guidPriest[0])) + { + Priest1->SetFacingTo(5.7421f); + Priest1->SetHomePosition(Priest1Pos[1]); + } + if (Creature* Priest2 = me->GetCreature(*me,guidPriest[1])) + { + Priest2->SetFacingTo(5.7421f); + Priest2->SetHomePosition(Priest2Pos[1]); + } + if (Creature* Priest3 = me->GetCreature(*me,guidPriest[2])) + { + Priest3->SetFacingTo(5.7421f); + Priest3->SetHomePosition(Priest3Pos[1]); + } + if (Creature* Mason1 = me->GetCreature(*me,guidMason[0])) + { + Mason1->GetMotionMaster()->MovePoint(0, Mason1Pos[2]); + Mason1->SetHomePosition(Mason1Pos[2]); + } + if (Creature* Mason2 = me->GetCreature(*me,guidMason[1])) + { + Mason2->GetMotionMaster()->MovePoint(0, Mason2Pos[2]); + Mason2->SetHomePosition(Mason2Pos[2]); + } + if (Creature* Mason3 = me->GetCreature(*me,guidMason[2])) + { + Mason3->GetMotionMaster()->MovePoint(0, Mason3Pos[2]); + Mason3->SetHomePosition(Mason3Pos[2]); + } + events.ScheduleEvent(EVENT_START_FIGHT,5000); + events.ScheduleEvent(EVENT_MASON_ACTION,15000); + } + break; + case EVENT_MASON_ACTION: + { + if (Creature* Mason1 = me->GetCreature(*me,guidMason[0])) + { + Mason1->SetFacingTo(2.8972f); + Mason1->AI()->SetData(1,1); // triggers SAI actions on npc + } + if (Creature* Mason2 = me->GetCreature(*me,guidMason[1])) + { + Mason2->SetFacingTo(3.1241f); + Mason2->AI()->SetData(1,1); // triggers SAI actions on npc + } + if (Creature* Mason3 = me->GetCreature(*me,guidMason[2])) + { + Mason3->SetFacingTo(3.6651f); + Mason3->AI()->SetData(1,1); // triggers SAI actions on npc + } + } + break; + case EVENT_START_FIGHT: + { + if(Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) + LK->AI()->Talk(LK_TALK_1); + if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) + Dalfors->AI()->Talk(DALFORS_SAY_START); + events.ScheduleEvent(EVENT_WAVE_SPAWN,1000); + } + break; + case EVENT_WAVE_SPAWN: + { + if (PhaseCount == 3) + { + if (Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) + LK->AI()->Talk(LK_TALK_2); + } + else if (PhaseCount == 6) + { + if (Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) + LK->AI()->Talk(LK_TALK_3); + } + if (Creature* tempsum = DoSummon(NPC_SCOURGE_DRUDGE,Mason3Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + if (urand(0,1) == 0) + { + if (Creature* tempsum = DoSummon(NPC_HIDEOUS_PLAGEBRINGER,Mason1Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + if (Creature* tempsum = DoSummon(NPC_HIDEOUS_PLAGEBRINGER,Mason2Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + } + else + { + if (Creature* tempsum = DoSummon(NPC_REANIMATED_CAPTAIN,Mason1Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + if (Creature* tempsum = DoSummon(NPC_REANIMATED_CAPTAIN,Mason2Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + } + + PhaseCount++; + + if (PhaseCount < 8) + events.ScheduleEvent(EVENT_WAVE_SPAWN,urand(10000,20000)); + else + events.ScheduleEvent(EVENT_HALOF,urand(10000,20000)); + } + break; + case EVENT_HALOF: + { + if (Creature* LK = GetClosestCreatureWithEntry(me,NPC_LK,100)) + LK->AI()->Talk(LK_TALK_4); + if (Creature* tempsum = DoSummon(NPC_SCOURGE_DRUDGE,Mason1Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + if (Creature* tempsum = DoSummon(NPC_SCOURGE_DRUDGE,Mason2Pos[0])) + { + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + if (Creature* tempsum = DoSummon(NPC_HALOF_THE_DEATHBRINGER,DalforsPos[0])) + { + HalofSpawned = true; + guidHalof = tempsum->GetGUID(); + tempsum->SetHomePosition(DalforsPos[2]); + tempsum->AI()->AttackStart(GetClosestCreatureWithEntry(me,NPC_BLESSED_BANNER,100)); + } + } + break; + case EVENT_ENDED: + { + Summons.DespawnAll(); + me->DespawnOrUnsummon(); + } + break; + } + + if (PhaseCount == 8) + if (Creature* Halof = me->GetCreature(*me,guidHalof)) + if (Halof->isDead()) + { + DoCast(me,SPELL_CRUSADERS_SPIRE_VICTORY,true); + Summons.DespawnEntry(NPC_HIDEOUS_PLAGEBRINGER); + Summons.DespawnEntry(NPC_REANIMATED_CAPTAIN); + Summons.DespawnEntry(NPC_SCOURGE_DRUDGE); + Summons.DespawnEntry(NPC_HALOF_THE_DEATHBRINGER); + if (Creature* Dalfors = me->GetCreature(*me,guidDalfors)) + Dalfors->AI()->Talk(DALFORS_YELL_FINISHED); + events.ScheduleEvent(EVENT_ENDED,10000); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_blessed_bannerAI(creature); + } +}; + +void AddSC_icecrown() +{ + new npc_arete; + new npc_squire_david; + new npc_argent_valiant; + new npc_guardian_pavilion; + new npc_vereth_the_cunning; + new npc_tournament_training_dummy; + new npc_blessed_banner(); +} diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp new file mode 100644 index 00000000000..2aa355084a1 --- /dev/null +++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp @@ -0,0 +1,1048 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* ScriptData +SDName: Sholazar_Basin +SD%Complete: 100 +SDComment: Quest support: 12570, 12573, 12621, 12726 +SDCategory: Sholazar_Basin +EndScriptData */ + +/* ContentData +npc_injured_rainspeaker_oracle +npc_vekjik +avatar_of_freya +npc_haiphoon (Quest: "Song of Wind and Water") +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "SpellScript.h" +#include "SpellAuras.h" +#include "Vehicle.h" +#include "CombatAI.h" +#include "Player.h" + +/*###### +## npc_injured_rainspeaker_oracle +######*/ + +#define GOSSIP_ITEM1 "I am ready to travel to your village now." + +enum eRainspeaker +{ + SAY_START_IRO = 0, + SAY_QUEST_ACCEPT_IRO = 1, + SAY_END_IRO = 2, + + QUEST_FORTUNATE_MISUNDERSTANDINGS = 12570, + FACTION_ESCORTEE_A = 774, + FACTION_ESCORTEE_H = 775 +}; + +class npc_injured_rainspeaker_oracle : public CreatureScript +{ +public: + npc_injured_rainspeaker_oracle() : CreatureScript("npc_injured_rainspeaker_oracle") { } + + struct npc_injured_rainspeaker_oracleAI : public npc_escortAI + { + npc_injured_rainspeaker_oracleAI(Creature* creature) : npc_escortAI(creature) { c_guid = creature->GetGUID(); } + + uint64 c_guid; + + void Reset() + { + me->RestoreFaction(); + // if we will have other way to assign this to only one npc remove this part + if (GUID_LOPART(me->GetGUID()) != 101030) + { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 1: + SetRun(); + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING); + me->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING); + me->SetSpeed(MOVE_SWIM, 0.85f, true); + me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_DISABLE_GRAVITY); + break; + case 19: + me->SetUnitMovementFlags(MOVEMENTFLAG_FALLING); + break; + case 28: + player->GroupEventHappens(QUEST_FORTUNATE_MISUNDERSTANDINGS, me); + // me->RestoreFaction(); + Talk(SAY_END_IRO); + SetRun(false); + break; + } + } + + void JustDied(Unit* /*killer*/) + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + return; + + if (Player* player = GetPlayerForEscort()) + { + if (player->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) != QUEST_STATUS_COMPLETE) + player->FailQuest(QUEST_FORTUNATE_MISUNDERSTANDINGS); + } + } + }; + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(35.0f); + creature->SetUnitMovementFlags(MOVEMENTFLAG_FALLING); + creature->AI()->Talk(SAY_START_IRO); + + switch (player->GetTeam()){ + case ALLIANCE: + creature->setFaction(FACTION_ESCORTEE_A); + break; + case HORDE: + creature->setFaction(FACTION_ESCORTEE_H); + break; + } + } + return true; + } + + bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* /*_Quest*/) + { + creature->AI()->Talk(SAY_QUEST_ACCEPT_IRO); + return false; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_injured_rainspeaker_oracleAI(creature); + } +}; + +/*###### +## npc_vekjik +######*/ + +#define GOSSIP_VEKJIK_ITEM1 "Shaman Vekjik, I have spoken with the big-tongues and they desire peace. I have brought this offering on their behalf." +#define GOSSIP_VEKJIK_ITEM2 "No no... I had no intentions of betraying your people. I was only defending myself. it was all a misunderstanding." + +enum eVekjik +{ + GOSSIP_TEXTID_VEKJIK1 = 13137, + GOSSIP_TEXTID_VEKJIK2 = 13138, + + SAY_TEXTID_VEKJIK1 = 0, + + SPELL_FREANZYHEARTS_FURY = 51469, + + QUEST_MAKING_PEACE = 12573 +}; + +class npc_vekjik : public CreatureScript +{ +public: + npc_vekjik() : CreatureScript("npc_vekjik") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_MAKING_PEACE) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK1, creature->GetGUID()); + return true; + } + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK2, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->CLOSE_GOSSIP_MENU(); + creature->AI()->Talk(SAY_TEXTID_VEKJIK1, player->GetGUID()); + player->AreaExploredOrEventHappens(QUEST_MAKING_PEACE); + creature->CastSpell(player, SPELL_FREANZYHEARTS_FURY, false); + break; + } + + return true; + } +}; + +/*###### +## avatar_of_freya +######*/ + +#define GOSSIP_ITEM_AOF1 "I want to stop the Scourge as much as you do. How can I help?" +#define GOSSIP_ITEM_AOF2 "You can trust me. I am no friend of the Lich King." +#define GOSSIP_ITEM_AOF3 "I will not fail." + +enum eFreya +{ + QUEST_FREYA_PACT = 12621, + + SPELL_FREYA_CONVERSATION = 52045, + + GOSSIP_TEXTID_AVATAR1 = 13303, + GOSSIP_TEXTID_AVATAR2 = 13304, + GOSSIP_TEXTID_AVATAR3 = 13305 +}; + +class npc_avatar_of_freya : public CreatureScript +{ +public: + npc_avatar_of_freya() : CreatureScript("npc_avatar_of_freya") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_FREYA_PACT) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR1, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR2, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR3, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->CastSpell(player, SPELL_FREYA_CONVERSATION, true); + player->CLOSE_GOSSIP_MENU(); + break; + } + return true; + } +}; + +/*###### +## npc_bushwhacker +######*/ + +class npc_bushwhacker : public CreatureScript +{ +public: + npc_bushwhacker() : CreatureScript("npc_bushwhacker") { } + + struct npc_bushwhackerAI : public ScriptedAI + { + npc_bushwhackerAI(Creature* creature) : ScriptedAI(creature) + { + } + + void InitializeAI() + { + if (me->isDead()) + return; + + if (TempSummon* summ = me->ToTempSummon()) + if (Unit* summoner = summ->GetSummoner()) + me->GetMotionMaster()->MovePoint(0, summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ()); + + Reset(); + } + + void UpdateAI(const uint32 /*uiDiff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_bushwhackerAI(creature); + } +}; + +/*###### +## npc_engineer_helice +######*/ + +enum eEnums +{ + SPELL_EXPLODE_CRYSTAL = 62487, + SPELL_FLAMES = 64561, + + SAY_WP_1 = 0, + SAY_WP_2 = 1, + SAY_WP_3 = 2, + SAY_WP_4 = 3, + SAY_WP_5 = 4, + SAY_WP_6 = 5, + SAY_WP_7 = 6, + + QUEST_DISASTER = 12688 +}; + +class npc_engineer_helice : public CreatureScript +{ +public: + npc_engineer_helice() : CreatureScript("npc_engineer_helice") { } + + struct npc_engineer_heliceAI : public npc_escortAI + { + npc_engineer_heliceAI(Creature* creature) : npc_escortAI(creature) { } + + uint32 m_uiChatTimer; + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + + switch (waypointId) + { + case 0: + Talk(SAY_WP_2); + break; + case 1: + Talk(SAY_WP_3); + me->CastSpell(5918.33f, 5372.91f, -98.770f, SPELL_EXPLODE_CRYSTAL, true); + me->SummonGameObject(184743, 5918.33f, 5372.91f, -98.770f, 0, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN); //approx 3 to 4 seconds + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); + break; + case 2: + Talk(SAY_WP_4); + break; + case 7: + Talk(SAY_WP_5); + break; + case 8: + me->CastSpell(5887.37f, 5379.39f, -91.289f, SPELL_EXPLODE_CRYSTAL, true); + me->SummonGameObject(184743, 5887.37f, 5379.39f, -91.289f, 0, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN); //approx 3 to 4 seconds + me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH); + break; + case 9: + Talk(SAY_WP_6); + break; + case 13: + if (player) + { + player->GroupEventHappens(QUEST_DISASTER, me); + Talk(SAY_WP_7); + } + break; + } + } + + void Reset() + { + m_uiChatTimer = 4000; + } + + void JustDied(Unit* /*killer*/) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_DISASTER); + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (HasEscortState(STATE_ESCORT_ESCORTING)) + { + if (m_uiChatTimer <= uiDiff) + { + m_uiChatTimer = 12000; + } + else + m_uiChatTimer -= uiDiff; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_engineer_heliceAI(creature); + } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_DISASTER) + { + if (npc_engineer_heliceAI* pEscortAI = CAST_AI(npc_engineer_helice::npc_engineer_heliceAI, creature->AI())) + { + creature->GetMotionMaster()->MoveJumpTo(0, 0.4f, 0.4f); + creature->setFaction(113); + + pEscortAI->Start(false, false, player->GetGUID()); + creature->AI()->Talk(SAY_WP_1); + } + } + return true; + } +}; + +/*##### +## npc_jungle_punch_target +#####*/ + +#define SAY_OFFER "Care to try Grimbooze Thunderbrew's new jungle punch?" +#define SAY_HEMET_1 "Aye, I'll try it." +#define SAY_HEMET_2 "That's exactly what I needed!" +#define SAY_HEMET_3 "It's got my vote! That'll put hair on your chest like nothing else will." +#define SAY_HADRIUS_1 "I'm always up for something of Grimbooze's." +#define SAY_HADRIUS_2 "Well, so far, it tastes like something my wife would drink..." +#define SAY_HADRIUS_3 "Now, there's the kick I've come to expect from Grimbooze's drinks! I like it!" +#define SAY_TAMARA_1 "Sure!" +#define SAY_TAMARA_2 "Oh my..." +#define SAY_TAMARA_3 "Tastes like I'm drinking... engine degreaser!" + +enum utils +{ + NPC_HEMET = 27986, + NPC_HADRIUS = 28047, + NPC_TAMARA = 28568, + SPELL_OFFER = 51962, + QUEST_ENTRY = 12645, +}; + +enum NesingwaryChildrensWeek +{ + SPELL_ORPHAN_OUT = 58818, + + QUEST_THE_MIGHTY_HEMET_NESINGWARY = 13957, + + ORPHAN_WOLVAR = 33532, + + TEXT_WOLVAR_ORPHAN_6 = 6, + TEXT_WOLVAR_ORPHAN_7 = 7, + TEXT_WOLVAR_ORPHAN_8 = 8, + TEXT_WOLVAR_ORPHAN_9 = 9, + + TEXT_NESINGWARY_1 = 1, +}; + +class npc_jungle_punch_target : public CreatureScript +{ +public: + npc_jungle_punch_target() : CreatureScript("npc_jungle_punch_target") { } + + struct npc_jungle_punch_targetAI : public ScriptedAI + { + npc_jungle_punch_targetAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + sayTimer = 3500; + sayStep = 0; + timer = 0; + phase = 0; + playerGUID = 0; + orphanGUID = 0; + } + + void MoveInLineOfSight(Unit* who) + { + if (!phase && who && who->GetDistance2d(me) < 10.0f) + if (Player* player = who->ToPlayer()) + if (player->GetQuestStatus(QUEST_THE_MIGHTY_HEMET_NESINGWARY) == QUEST_STATUS_INCOMPLETE) + { + playerGUID = player->GetGUID(); + if (Aura* orphanOut = player->GetAura(SPELL_ORPHAN_OUT)) + if (orphanOut->GetCaster() && orphanOut->GetCaster()->GetEntry() == ORPHAN_WOLVAR) + { + orphanGUID = orphanOut->GetCaster()->GetGUID(); + phase = 1; + } + } + } + + void proceedCwEvent(const uint32 diff) + { + if (timer <= diff) + { + Player* player = Player::GetPlayer(*me, playerGUID); + Creature* orphan = Creature::GetCreature(*me, orphanGUID); + + if(!orphan || !player) + { + Reset(); + return; + } + + switch(phase) + { + case 1: + orphan->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(me->GetOrientation()) * 5, me->GetPositionY() + sin(me->GetOrientation()) * 5, me->GetPositionZ()); + orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_6); + timer = 5000; + break; + case 2: + orphan->SetFacingToObject(me); + orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_7); + timer = 5000; + break; + case 3: + Talk(TEXT_NESINGWARY_1); + timer = 5000; + break; + case 4: + orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_8); + timer = 5000; + break; + case 5: + orphan->AI()->Talk(TEXT_WOLVAR_ORPHAN_9); + timer = 5000; + break; + case 6: + orphan->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); + player->GroupEventHappens(QUEST_THE_MIGHTY_HEMET_NESINGWARY, me); + Reset(); + return; + } + ++phase; + } + else + timer -= diff; + } + + void UpdateAI(const uint32 uiDiff) + { + if (phase) + proceedCwEvent(uiDiff); + + if (!sayStep) + return; + + if (sayTimer < uiDiff) + { + switch (sayStep) + { + case 0: + { + switch (me->GetEntry()) + { + case NPC_HEMET: me->MonsterSay(SAY_HEMET_1, LANG_UNIVERSAL, 0); break; + case NPC_HADRIUS: me->MonsterSay(SAY_HADRIUS_1, LANG_UNIVERSAL, 0); break; + case NPC_TAMARA: me->MonsterSay(SAY_TAMARA_1, LANG_UNIVERSAL, 0); break; + } + sayTimer = 3000; + sayStep++; + break; + } + case 1: + { + switch (me->GetEntry()) + { + case NPC_HEMET: me->MonsterSay(SAY_HEMET_2, LANG_UNIVERSAL, 0); break; + case NPC_HADRIUS: me->MonsterSay(SAY_HADRIUS_2, LANG_UNIVERSAL, 0); break; + case NPC_TAMARA: me->MonsterSay(SAY_TAMARA_2, LANG_UNIVERSAL, 0); break; + } + sayTimer = 3000; + sayStep++; + break; + } + case 2: + { + switch (me->GetEntry()) + { + case NPC_HEMET: me->MonsterSay(SAY_HEMET_3, LANG_UNIVERSAL, 0); break; + case NPC_HADRIUS: me->MonsterSay(SAY_HADRIUS_3, LANG_UNIVERSAL, 0); break; + case NPC_TAMARA: me->MonsterSay(SAY_TAMARA_3, LANG_UNIVERSAL, 0); break; + } + sayTimer = 3000; + sayStep = 0; + break; + } + } + } + else + sayTimer -= uiDiff; + } + + void SpellHit(Unit* caster, const SpellInfo* proto) + { + if (!proto || proto->Id != SPELL_OFFER) + return; + + if (!caster->ToPlayer()) + return; + + QuestStatusMap::const_iterator itr = caster->ToPlayer()->getQuestStatusMap().find(QUEST_ENTRY); + if (itr->second.Status != QUEST_STATUS_INCOMPLETE) + return; + + for (uint8 i=0; i<3; i++) + { + switch (i) + { + case 0: + if (NPC_HEMET != me->GetEntry()) + continue; + else + break; + case 1: + if (NPC_HADRIUS != me->GetEntry()) + continue; + else + break; + case 2: + if (NPC_TAMARA != me->GetEntry()) + continue; + else + break; + } + + if (itr->second.CreatureOrGOCount[i] != 0) + continue; + + caster->ToPlayer()->KilledMonsterCredit(me->GetEntry(), 0); + caster->ToPlayer()->Say(SAY_OFFER, LANG_UNIVERSAL); + sayStep = 0; + break; + } + } + + private: + uint16 sayTimer; + uint8 sayStep; + uint32 timer; + int8 phase; + uint64 playerGUID; + uint64 orphanGUID; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_jungle_punch_targetAI(creature); + } +}; + +/*###### +## npc_adventurous_dwarf +######*/ + +#define GOSSIP_OPTION_ORANGE "Can you spare an orange?" +#define GOSSIP_OPTION_BANANAS "Have a spare bunch of bananas?" +#define GOSSIP_OPTION_PAPAYA "I could really use a papaya." + +enum eAdventurousDwarf +{ + QUEST_12634 = 12634, + + ITEM_BANANAS = 38653, + ITEM_PAPAYA = 38655, + ITEM_ORANGE = 38656, + + SPELL_ADD_ORANGE = 52073, + SPELL_ADD_BANANAS = 52074, + SPELL_ADD_PAPAYA = 52076, + + GOSSIP_MENU_DWARF = 13307, + + SAY_DWARF_OUCH = 0, + SAY_DWARF_HELP = 1 +}; + +class npc_adventurous_dwarf : public CreatureScript +{ +public: + npc_adventurous_dwarf() : CreatureScript("npc_adventurous_dwarf") { } + + struct npc_adventurous_dwarfAI : public ScriptedAI + { + npc_adventurous_dwarfAI(Creature* creature) : ScriptedAI(creature) + { + Talk(SAY_DWARF_OUCH); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_adventurous_dwarfAI(creature); + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_12634) != QUEST_STATUS_INCOMPLETE) + return false; + + if (player->GetItemCount(ITEM_ORANGE) < 1) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OPTION_ORANGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + if (player->GetItemCount(ITEM_BANANAS) < 2) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OPTION_BANANAS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + + if (player->GetItemCount(ITEM_PAPAYA) < 1) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OPTION_PAPAYA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + + player->PlayerTalkClass->SendGossipMenu(GOSSIP_MENU_DWARF, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + uint32 spellId = 0; + + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + spellId = SPELL_ADD_ORANGE; + break; + case GOSSIP_ACTION_INFO_DEF + 2: + spellId = SPELL_ADD_BANANAS; + break; + case GOSSIP_ACTION_INFO_DEF + 3: + spellId = SPELL_ADD_PAPAYA; + break; + } + + if (spellId) + player->CastSpell(player, spellId, true); + + creature->AI()->Talk(SAY_DWARF_HELP); + creature->DespawnOrUnsummon(); + return true; + } +}; + +/*###### +## Quest The Lifewarden's Wrath +######*/ + +enum MiscLifewarden +{ + NPC_PRESENCE = 28563, // Freya's Presence + NPC_SABOTEUR = 28538, // Cultist Saboteur + NPC_SERVANT = 28320, // Servant of Freya + + WHISPER_ACTIVATE = 0, + + SPELL_FREYA_DUMMY = 51318, + SPELL_LIFEFORCE = 51395, + SPELL_FREYA_DUMMY_TRIGGER = 51335, + SPELL_LASHER_EMERGE = 48195, + SPELL_WILD_GROWTH = 52948, +}; + +class spell_q12620_the_lifewarden_wrath : public SpellScriptLoader +{ +public: + spell_q12620_the_lifewarden_wrath() : SpellScriptLoader("spell_q12620_the_lifewarden_wrath") { } + + class spell_q12620_the_lifewarden_wrath_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12620_the_lifewarden_wrath_SpellScript); + + void HandleSendEvent(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + + if (Unit* caster = GetCaster()) + { + if (Creature* presence = caster->FindNearestCreature(NPC_PRESENCE, 50.0f)) + { + presence->AI()->Talk(WHISPER_ACTIVATE, caster->GetGUID()); + presence->CastSpell(presence, SPELL_FREYA_DUMMY, true); // will target plants + // Freya Dummy could be scripted with the following code + + // Revive plants + std::list servants; + GetCaster()->GetCreatureListWithEntryInGrid(servants, NPC_SERVANT, 200.0f); + for (std::list::iterator itr = servants.begin(); itr != servants.end(); ++itr) + { + // Couldn't find a spell that does this + if ((*itr)->isDead()) + (*itr)->Respawn(true); + + (*itr)->CastSpell(*itr, SPELL_FREYA_DUMMY_TRIGGER, true); + (*itr)->CastSpell(*itr, SPELL_LASHER_EMERGE, false); + (*itr)->CastSpell(*itr, SPELL_WILD_GROWTH, false); + + if (Unit* target = (*itr)->SelectNearestTarget(150.0f)) + (*itr)->AI()->AttackStart(target); + } + + // Kill nearby enemies + std::list saboteurs; + caster->GetCreatureListWithEntryInGrid(saboteurs, NPC_SABOTEUR, 200.0f); + for (std::list::iterator itr = saboteurs.begin(); itr != saboteurs.end(); ++itr) + if ((*itr)->isAlive()) + // Lifeforce has a cast duration, it should be cast at all saboteurs one by one + presence->CastSpell((*itr), SPELL_LIFEFORCE, false); + } + } + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_q12620_the_lifewarden_wrath_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12620_the_lifewarden_wrath_SpellScript(); + } +}; + +/*###### +## Quest Kick, What Kick? (12589) +######*/ + +enum KickWhatKick +{ + NPC_LUCKY_WILHELM = 28054, + NPC_APPLE = 28053, + NPC_DROSTAN = 28328, + NPC_CRUNCHY = 28346, + NPC_THICKBIRD = 28093, + + SPELL_HIT_APPLE = 51331, + SPELL_MISS_APPLE = 51332, + SPELL_MISS_BIRD_APPLE = 51366, + SPELL_APPLE_FALL = 51371, + SPELL_BIRD_FALL = 51369, + + EVENT_MISS = 0, + EVENT_HIT = 1, + EVENT_MISS_BIRD = 2, + + SAY_WILHELM_MISS = 0, + SAY_WILHELM_HIT = 1, + SAY_DROSTAN_REPLY_MISS = 0, +}; + +class spell_q12589_shoot_rjr : public SpellScriptLoader +{ +public: + spell_q12589_shoot_rjr() : SpellScriptLoader("spell_q12589_shoot_rjr") { } + + class spell_q12589_shoot_rjr_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q12589_shoot_rjr_SpellScript); + + SpellCastResult CheckCast() + { + if (Unit* target = GetExplTargetUnit()) + if (target->GetEntry() == NPC_LUCKY_WILHELM) + return SPELL_CAST_OK; + + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM); + return SPELL_FAILED_CUSTOM_ERROR; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + uint32 roll = urand(1, 100); + + uint8 ev; + if (roll <= 50) + ev = EVENT_MISS; + else if (roll <= 83) + ev = EVENT_HIT; + else + ev = EVENT_MISS_BIRD; + + Unit* shooter = GetCaster(); + Creature* wilhelm = GetHitUnit()->ToCreature(); + Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30); + Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30); + + if (!wilhelm || !apple || !drostan) + return; + + switch (ev) + { + case EVENT_MISS_BIRD: + { + Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30); + Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30); + + if (!bird || !crunchy) + ; // fall to EVENT_MISS + else + { + shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE); + bird->CastSpell(bird, SPELL_BIRD_FALL); + wilhelm->AI()->Talk(SAY_WILHELM_MISS); + drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); + + bird->Kill(bird); + crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(), + bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ())); + // TODO: Make crunchy perform emote eat when he reaches the bird + + break; + } + } + case EVENT_MISS: + { + shooter->CastSpell(wilhelm, SPELL_MISS_APPLE); + wilhelm->AI()->Talk(SAY_WILHELM_MISS); + drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS); + break; + } + case EVENT_HIT: + { + shooter->CastSpell(apple, SPELL_HIT_APPLE); + apple->CastSpell(apple, SPELL_APPLE_FALL); + wilhelm->AI()->Talk(SAY_WILHELM_HIT); + if (Player* player = shooter->ToPlayer()) + player->KilledMonsterCredit(NPC_APPLE, 0); + apple->DespawnOrUnsummon(); + + break; + } + } + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_q12589_shoot_rjr_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_q12589_shoot_rjr_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q12589_shoot_rjr_SpellScript(); + } +}; + +/*###### +## Quest: Song of Wind and Water ID: 12726 +######*/ +/*This quest precisly needs core script since battle vehicles are not well integrated with SAI, +may be easily converted to SAI when they get.*/ +enum SongOfWindAndWater +{ + // Spells + SPELL_DEVOUR_WIND = 52862, + SPELL_DEVOUR_WATER = 52864, + // NPCs + NPC_HAIPHOON_WATER = 28999, + NPC_HAIPHOON_AIR = 28985 +}; + +class npc_haiphoon : public CreatureScript +{ +public: + npc_haiphoon() : CreatureScript("npc_haiphoon") { } + + struct npc_haiphoonAI : public VehicleAI + { + npc_haiphoonAI(Creature* creature) : VehicleAI(creature) { } + + void SpellHitTarget(Unit* target, SpellInfo const* spell) + { + if (target == me) + return; + + if (spell->Id == SPELL_DEVOUR_WIND && me->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + me->UpdateEntry(NPC_HAIPHOON_AIR); + } + else if (spell->Id == SPELL_DEVOUR_WATER && me->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + me->UpdateEntry(NPC_HAIPHOON_WATER); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_haiphoonAI(creature); + } +}; + +void AddSC_sholazar_basin() +{ + new npc_injured_rainspeaker_oracle(); + new npc_vekjik(); + new npc_avatar_of_freya(); + new npc_bushwhacker(); + new npc_engineer_helice(); + new npc_adventurous_dwarf(); + new npc_jungle_punch_target(); + new spell_q12620_the_lifewarden_wrath(); + new spell_q12589_shoot_rjr(); + new npc_haiphoon(); +} diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp new file mode 100644 index 00000000000..85ab1dc1127 --- /dev/null +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -0,0 +1,629 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Vehicle.h" +#include "CombatAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npc_agnetta_tyrsdottar +######*/ + +#define GOSSIP_AGNETTA "Skip the warmup, sister... or are you too scared to face soemeone your own size?" + +enum eAgnetta +{ + QUEST_ITS_THAT_YOUR_GOBLIN = 12969, + FACTION_HOSTILE_AT1 = 45, + SAY_AGGRO = 0 +}; + +class npc_agnetta_tyrsdottar : public CreatureScript +{ +public: + npc_agnetta_tyrsdottar() : CreatureScript("npc_agnetta_tyrsdottar") { } + + struct npc_agnetta_tyrsdottarAI : public ScriptedAI + { + npc_agnetta_tyrsdottarAI(Creature* creature) : ScriptedAI(creature) { } + + void Reset() + { + me->RestoreFaction(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_agnetta_tyrsdottarAI(creature); + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_ITS_THAT_YOUR_GOBLIN) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_AGNETTA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(13691, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + creature->AI()->Talk(SAY_AGGRO); + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_HOSTILE_AT1); + creature->AI()->AttackStart(player); + } + + return true; + } +}; + +/*###### +## npc_frostborn_scout +######*/ + +#define GOSSIP_ITEM1 "Are you okay? I've come to take you back to Frosthold if you can stand." +#define GOSSIP_ITEM2 "I'm sorry that I didn't get here sooner. What happened?" +#define GOSSIP_ITEM3 "I'll go get some help. Hang in there." + +enum eFrostbornScout +{ + QUEST_MISSING_SCOUTS = 12864 +}; + +class npc_frostborn_scout : public CreatureScript +{ +public: + npc_frostborn_scout() : CreatureScript("npc_frostborn_scout") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + + if (player->GetQuestStatus(QUEST_MISSING_SCOUTS) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->PlayerTalkClass->SendGossipMenu(13611, creature->GetGUID()); + } + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->PlayerTalkClass->SendGossipMenu(13612, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->PlayerTalkClass->SendGossipMenu(13613, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->PlayerTalkClass->SendGossipMenu(13614, creature->GetGUID()); + player->AreaExploredOrEventHappens(QUEST_MISSING_SCOUTS); + break; + } + + return true; + } +}; + +///////////////////// +///npc_injured_goblin +///////////////////// + +enum eInjuredGoblin +{ + QUEST_BITTER_DEPARTURE = 12832, + SAY_QUEST_ACCEPT = 0, + SAY_END_WP_REACHED = 1 +}; + +#define GOSSIP_ITEM_1 "I am ready, lets get you out of here" + +class npc_injured_goblin : public CreatureScript +{ +public: + npc_injured_goblin() : CreatureScript("npc_injured_goblin") { } + + struct npc_injured_goblinAI : public npc_escortAI + { + npc_injured_goblinAI(Creature* creature) : npc_escortAI(creature) { } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 26: + Talk(SAY_END_WP_REACHED, player->GetGUID()); + break; + case 27: + player->GroupEventHappens(QUEST_BITTER_DEPARTURE, me); + break; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void Reset() {} + + void JustDied(Unit* /*killer*/) + { + Player* player = GetPlayerForEscort(); + if (HasEscortState(STATE_ESCORT_ESCORTING) && player) + player->FailQuest(QUEST_BITTER_DEPARTURE); + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + if (!UpdateVictim()) + return; + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_injured_goblinAI(creature); + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_BITTER_DEPARTURE) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->PlayerTalkClass->SendGossipMenu(9999999, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(999999, creature->GetGUID()); + return true; + } + + bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_BITTER_DEPARTURE) + creature->AI()->Talk(SAY_QUEST_ACCEPT); + + return false; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + npc_escortAI* pEscortAI = CAST_AI(npc_injured_goblin::npc_injured_goblinAI, creature->AI()); + + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + pEscortAI->Start(true, true, player->GetGUID()); + creature->setFaction(113); + } + return true; + } +}; + +/*###### +## npc_roxi_ramrocket +######*/ + +#define SPELL_MECHANO_HOG 60866 +#define SPELL_MEKGINEERS_CHOPPER 60867 + +class npc_roxi_ramrocket : public CreatureScript +{ +public: + npc_roxi_ramrocket() : CreatureScript("npc_roxi_ramrocket") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + //Quest Menu + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + //Trainer Menu + if ( creature->isTrainer() ) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN); + + //Vendor Menu + if ( creature->isVendor() ) + if (player->HasSpell(SPELL_MECHANO_HOG) || player->HasSpell(SPELL_MEKGINEERS_CHOPPER)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_TRAIN: + player->GetSession()->SendTrainerList(creature->GetGUID()); + break; + case GOSSIP_ACTION_TRADE: + player->GetSession()->SendListInventory(creature->GetGUID()); + break; + } + return true; + } +}; + +/*###### +## npc_brunnhildar_prisoner +######*/ + +enum BrunnhildarPrisoner { + SPELL_ICE_PRISON = 54894, + SPELL_ICE_LANCE = 55046, + SPELL_FREE_PRISONER = 55048, + SPELL_RIDE_DRAKE = 55074, + SPELL_SHARD_IMPACT = 55047 +}; + +class npc_brunnhildar_prisoner : public CreatureScript +{ +public: + npc_brunnhildar_prisoner() : CreatureScript("npc_brunnhildar_prisoner") { } + + struct npc_brunnhildar_prisonerAI : public ScriptedAI + { + npc_brunnhildar_prisonerAI(Creature* creature) : ScriptedAI(creature) {} + + bool freed; + + void Reset() + { + freed = false; + me->CastSpell(me, SPELL_ICE_PRISON, true); + } + + void JustRespawned() + { + Reset(); + } + + void UpdateAI(const uint32 /*diff*/) + { + if (!freed) + return; + + if (!me->HasUnitState(UNIT_STATE_ONVEHICLE)) + { + me->DespawnOrUnsummon(); + } + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id != SPELL_ICE_LANCE) + return; + + if (caster->GetVehicleKit()->GetAvailableSeatCount() != 0) + { + me->CastSpell(me, SPELL_FREE_PRISONER, true); + me->CastSpell(caster, SPELL_RIDE_DRAKE, true); + me->CastSpell(me, SPELL_SHARD_IMPACT, true); + freed = true; + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_brunnhildar_prisonerAI(creature); + } +}; + +/*###### +## npc_freed_protodrake +######*/ + +enum FreedProtoDrake +{ + AREA_VALLEY_OF_ANCIENT_WINTERS = 4437, + TEXT_EMOTE = 0, + SPELL_KILL_CREDIT_PRISONER = 55144, + SPELL_SUMMON_LIBERATED = 55073, + SPELL_KILL_CREDIT_DRAKE = 55143 +}; + +const Position FreedDrakeWaypoints[16] = +{ + {7294.96f, -2418.733f, 823.869f, 0.0f}, + {7315.984f, -2331.46f, 826.3972f, 0.0f}, + {7271.826f, -2271.479f, 833.5917f, 0.0f}, + {7186.253f, -2218.475f, 847.5632f, 0.0f}, + {7113.195f, -2164.288f, 850.2301f, 0.0f}, + {7078.018f, -2063.106f, 854.7581f, 0.0f}, + {7073.221f, -1983.382f, 861.9246f, 0.0f}, + {7061.455f, -1885.899f, 865.119f, 0.0f}, + {7033.32f, -1826.775f, 876.2578f, 0.0f}, + {6999.902f, -1784.012f, 897.4521f, 0.0f}, + {6954.913f, -1747.043f, 897.4521f, 0.0f}, + {6933.856f, -1720.698f, 882.2022f, 0.0f}, + {6932.729f, -1687.306f, 866.1189f, 0.0f}, + {6952.458f, -1663.802f, 849.8133f, 0.0f}, + {7002.819f, -1651.681f, 831.397f, 0.0f}, + {7026.531f, -1649.239f, 828.8406f, 0.0f} +}; + + +class npc_freed_protodrake : public CreatureScript +{ +public: + npc_freed_protodrake() : CreatureScript("npc_freed_protodrake") { } + + struct npc_freed_protodrakeAI : public VehicleAI + { + npc_freed_protodrakeAI(Creature* creature) : VehicleAI(creature) {} + + bool autoMove; + bool wpReached; + uint16 CheckTimer; + uint16 countWP; + + void Reset() + { + autoMove = false; + wpReached = false; + CheckTimer = 5000; + countWP = 0; + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id < 15) + { + ++countWP; + wpReached = true; + } + else + // drake reached village + { + // get player that rides drake (from seat 0) + Unit* player = me->GetVehicleKit()->GetPassenger(0); + if (player && player->GetTypeId() == TYPEID_PLAYER) + { + // for each prisoner on drake,give credit + for (uint8 i = 1; i < 4; ++i) + if (Unit* prisoner = me->GetVehicleKit()->GetPassenger(i)) + { + if (prisoner->GetTypeId() != TYPEID_UNIT) + return; + prisoner->CastSpell(player, SPELL_KILL_CREDIT_PRISONER, true); + prisoner->CastSpell(prisoner, SPELL_SUMMON_LIBERATED, true); + prisoner->ExitVehicle(); + } + me->CastSpell(me, SPELL_KILL_CREDIT_DRAKE, true); + player->ExitVehicle(); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (!autoMove) + { + if (CheckTimer < diff) + { + CheckTimer = 5000; + if (me->GetAreaId() == AREA_VALLEY_OF_ANCIENT_WINTERS) + { + Talk(TEXT_EMOTE, me->GetVehicleKit()->GetPassenger(0)->GetGUID()); + autoMove = true; + wpReached = true; + } + } + else + CheckTimer -= diff; + } + + if (wpReached && autoMove) + { + wpReached = false; + me->GetMotionMaster()->MovePoint(countWP, FreedDrakeWaypoints[countWP]); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_freed_protodrakeAI(creature); + } +}; + +class npc_icefang : public CreatureScript +{ +public: + npc_icefang() : CreatureScript("npc_icefang") { } + + struct npc_icefangAI : public npc_escortAI + { + npc_icefangAI(Creature* creature) : npc_escortAI(creature) {} + + void AttackStart(Unit* /*who*/) {} + void EnterCombat(Unit* /*who*/) {} + void EnterEvadeMode() {} + + void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) + { + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (apply) + Start(false, true, who->GetGUID()); + } + } + + void WaypointReached(uint32 /*waypointId*/) + { + } + + void JustDied(Unit* /*killer*/) + { + } + + void OnCharmed(bool /*apply*/) + { + } + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_icefangAI (creature); + } +}; + +class npc_hyldsmeet_protodrake : public CreatureScript +{ + enum NPCs + { + NPC_HYLDSMEET_DRAKERIDER = 29694 + }; + + public: + npc_hyldsmeet_protodrake() : CreatureScript("npc_hyldsmeet_protodrake") { } + + class npc_hyldsmeet_protodrakeAI : public CreatureAI + { + public: + npc_hyldsmeet_protodrakeAI(Creature* creature) : CreatureAI(creature), _accessoryRespawnTimer(0), _vehicleKit(creature->GetVehicleKit()) {} + + void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) + { + if (apply) + return; + + if (who->GetEntry() == NPC_HYLDSMEET_DRAKERIDER) + _accessoryRespawnTimer = 5 * MINUTE * IN_MILLISECONDS; + } + + void UpdateAI(uint32 const diff) + { + //! We need to manually reinstall accessories because the vehicle itself is friendly to players, + //! so EnterEvadeMode is never triggered. The accessory on the other hand is hostile and killable. + if (_accessoryRespawnTimer && _accessoryRespawnTimer <= diff && _vehicleKit) + { + _vehicleKit->InstallAllAccessories(true); + _accessoryRespawnTimer = 0; + } + else + _accessoryRespawnTimer -= diff; + } + + private: + uint32 _accessoryRespawnTimer; + Vehicle* _vehicleKit; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_hyldsmeet_protodrakeAI (creature); + } +}; + +enum CloseRift +{ + SPELL_DESPAWN_RIFT = 61665 +}; + +class spell_close_rift : public SpellScriptLoader +{ + public: + spell_close_rift() : SpellScriptLoader("spell_close_rift") { } + + class spell_close_rift_AuraScript : public AuraScript + { + PrepareAuraScript(spell_close_rift_AuraScript); + + bool Load() + { + _counter = 0; + return true; + } + + bool Validate(SpellInfo const* /*spell*/) + { + return sSpellMgr->GetSpellInfo(SPELL_DESPAWN_RIFT); + } + + void HandlePeriodic(AuraEffect const* /* aurEff */) + { + if (++_counter == 5) + GetTarget()->CastSpell((Unit*)NULL, SPELL_DESPAWN_RIFT, true); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_close_rift_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + + private: + uint8 _counter; + + }; + + AuraScript* GetAuraScript() const + { + return new spell_close_rift_AuraScript(); + } +}; + +void AddSC_storm_peaks() +{ + new npc_agnetta_tyrsdottar(); + new npc_frostborn_scout(); + new npc_injured_goblin(); + new npc_roxi_ramrocket(); + new npc_brunnhildar_prisoner(); + new npc_freed_protodrake(); + new npc_icefang(); + new npc_hyldsmeet_protodrake(); + new spell_close_rift(); +} diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp new file mode 100644 index 00000000000..8935c77b30e --- /dev/null +++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp @@ -0,0 +1,624 @@ +/* Copyright (C) 2008 - 2009 Trinity + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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 "BattlefieldMgr.h" +#include "BattlefieldWG.h" +#include "Battlefield.h" +#include "ScriptSystem.h" +#include "WorldSession.h" +#include "ObjectMgr.h" +#include "Vehicle.h" +#include "GameObjectAI.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "SpellScript.h" +#include "Player.h" + +#define GOSSIP_HELLO_DEMO1 "Build catapult." +#define GOSSIP_HELLO_DEMO2 "Build demolisher." +#define GOSSIP_HELLO_DEMO3 "Build siege engine." +#define GOSSIP_HELLO_DEMO4 "I cannot build more!" + +enum WGqueuenpctext +{ + WG_NPCQUEUE_TEXT_H_NOWAR = 14775, + WG_NPCQUEUE_TEXT_H_QUEUE = 14790, + WG_NPCQUEUE_TEXT_H_WAR = 14777, + WG_NPCQUEUE_TEXT_A_NOWAR = 14782, + WG_NPCQUEUE_TEXT_A_QUEUE = 14791, + WG_NPCQUEUE_TEXT_A_WAR = 14781, + WG_NPCQUEUE_TEXTOPTION_JOIN = -1850507, +}; + +enum Spells +{ + // Demolisher engineers spells + SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE = 61409, + SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE = 56662, + SPELL_BUILD_CATAPULT_FORCE = 56664, + SPELL_BUILD_DEMOLISHER_FORCE = 56659, + SPELL_ACTIVATE_CONTROL_ARMS = 49899, + SPELL_RIDE_WG_VEHICLE = 60968, + + SPELL_VEHICLE_TELEPORT = 49759, + + // Spirit guide + SPELL_CHANNEL_SPIRIT_HEAL = 22011, +}; + +enum CreatureIds +{ + NPC_GOBLIN_MECHANIC = 30400, + NPC_GNOMISH_ENGINEER = 30499, + + NPC_WINTERGRASP_CONTROL_ARMS = 27852, + + NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC = 23472, +}; + +enum QuestIds +{ + QUEST_BONES_AND_ARROWS_HORDE_ATT = 13193, + QUEST_JINXING_THE_WALLS_HORDE_ATT = 13202, + QUEST_SLAY_THEM_ALL_HORDE_ATT = 13180, + QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT = 13200, + QUEST_HEALING_WITH_ROSES_HORDE_ATT = 13201, + QUEST_DEFEND_THE_SIEGE_HORDE_ATT = 13223, + + QUEST_BONES_AND_ARROWS_HORDE_DEF = 13199, + QUEST_WARDING_THE_WALLS_HORDE_DEF = 13192, + QUEST_SLAY_THEM_ALL_HORDE_DEF = 13178, + QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF = 13191, + QUEST_HEALING_WITH_ROSES_HORDE_DEF = 13194, + QUEST_TOPPLING_THE_TOWERS_HORDE_DEF = 13539, + QUEST_STOP_THE_SIEGE_HORDE_DEF = 13185, + + QUEST_BONES_AND_ARROWS_ALLIANCE_ATT = 13196, + QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT = 13198, + QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT = 13179, + QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT = 13222, + QUEST_A_RARE_HERB_ALLIANCE_ATT = 13195, + + QUEST_BONES_AND_ARROWS_ALLIANCE_DEF = 13154, + QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF = 13153, + QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF = 13177, + QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF = 13538, + QUEST_STOP_THE_SIEGE_ALLIANCE_DEF = 13186, + QUEST_A_RARE_HERB_ALLIANCE_DEF = 13156, +}; + +uint8 const MAX_WINTERGRASP_VEHICLES = 4; + +uint32 const vehiclesList[MAX_WINTERGRASP_VEHICLES] = +{ + NPC_WINTERGRASP_CATAPULT, + NPC_WINTERGRASP_DEMOLISHER, + NPC_WINTERGRASP_SIEGE_ENGINE_ALLIANCE, + NPC_WINTERGRASP_SIEGE_ENGINE_HORDE +}; + +class npc_wg_demolisher_engineer : public CreatureScript +{ + public: + npc_wg_demolisher_engineer() : CreatureScript("npc_wg_demolisher_engineer") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (canBuild(creature)) + { + if (player->HasAura(SPELL_CORPORAL)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + else if (player->HasAura(SPELL_LIEUTENANT)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + } + } + else + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->CLOSE_GOSSIP_MENU(); + + if (canBuild(creature)) + { + switch (action - GOSSIP_ACTION_INFO_DEF) + { + case 0: + creature->CastSpell(player, SPELL_BUILD_CATAPULT_FORCE, true); + break; + case 1: + creature->CastSpell(player, SPELL_BUILD_DEMOLISHER_FORCE, true); + break; + case 2: + creature->CastSpell(player, player->GetTeamId() == TEAM_ALLIANCE ? SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE : SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE, true); + break; + } + if (Creature* controlArms = creature->FindNearestCreature(NPC_WINTERGRASP_CONTROL_ARMS, 30.0f, true)) + creature->CastSpell(controlArms, SPELL_ACTIVATE_CONTROL_ARMS, true); + } + return true; + } + + private: + bool canBuild(Creature* creature) + { + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return false; + + switch (creature->GetEntry()) + { + case NPC_GOBLIN_MECHANIC: + return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_H)); + case NPC_GNOMISH_ENGINEER: + return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_A)); + default: + return false; + } + } +}; + +class npc_wg_spirit_guide : public CreatureScript +{ + public: + npc_wg_spirit_guide() : CreatureScript("npc_wg_spirit_guide") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; + + GraveyardVect graveyard = wintergrasp->GetGraveyardVector(); + for (uint8 i = 0; i < graveyard.size(); i++) + if (graveyard[i]->GetControlTeamId() == player->GetTeamId()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(((BfGraveyardWG*)graveyard[i])->GetTextId()), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + i); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->CLOSE_GOSSIP_MENU(); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (wintergrasp) + { + GraveyardVect gy = wintergrasp->GetGraveyardVector(); + for (uint8 i = 0; i < gy.size(); i++) + if (action - GOSSIP_ACTION_INFO_DEF == i && gy[i]->GetControlTeamId() == player->GetTeamId()) + if (WorldSafeLocsEntry const* safeLoc = sWorldSafeLocsStore.LookupEntry(gy[i]->GetGraveyardId())) + player->TeleportTo(safeLoc->map_id, safeLoc->x, safeLoc->y, safeLoc->z, 0); + } + return true; + } + + struct npc_wg_spirit_guideAI : public ScriptedAI + { + npc_wg_spirit_guideAI(Creature* creature) : ScriptedAI(creature) { } + + void UpdateAI(uint32 const /*diff*/) + { + if (!me->HasUnitState(UNIT_STATE_CASTING)) + DoCast(me, SPELL_CHANNEL_SPIRIT_HEAL); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_wg_spirit_guideAI(creature); + } +}; + +class npc_wg_queue : public CreatureScript +{ + public: + npc_wg_queue() : CreatureScript("npc_wg_queue") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; + + if (wintergrasp->IsWarTime()) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(WG_NPCQUEUE_TEXTOPTION_JOIN), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_WAR : WG_NPCQUEUE_TEXT_A_WAR, creature->GetGUID()); + } + else + { + uint32 timer = wintergrasp->GetTimer() / 1000; + player->SendUpdateWorldState(4354, time(NULL) + timer); + if (timer < 15 * MINUTE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(WG_NPCQUEUE_TEXTOPTION_JOIN), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_QUEUE : WG_NPCQUEUE_TEXT_A_QUEUE, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_NOWAR : WG_NPCQUEUE_TEXT_A_NOWAR, creature->GetGUID()); + } + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/ , uint32 /*sender*/ , uint32 /*action*/) + { + player->CLOSE_GOSSIP_MENU(); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; + + if (wintergrasp->IsWarTime()) + wintergrasp->InvitePlayerToWar(player); + else + { + uint32 timer = wintergrasp->GetTimer() / 1000; + if (timer < 15 * MINUTE) + wintergrasp->InvitePlayerToQueue(player); + } + return true; + } +}; + +class go_wg_vehicle_teleporter : public GameObjectScript +{ + public: + go_wg_vehicle_teleporter() : GameObjectScript("go_wg_vehicle_teleporter") { } + + struct go_wg_vehicle_teleporterAI : public GameObjectAI + { + go_wg_vehicle_teleporterAI(GameObject* gameObject) : GameObjectAI(gameObject), _checkTimer(1000) { } + + void UpdateAI(uint32 diff) + { + if (_checkTimer <= diff) + { + if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + // Tabulation madness in the hole! + for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++) + if (Creature* vehicleCreature = go->FindNearestCreature(vehiclesList[i], 3.0f, true)) + if (!vehicleCreature->HasAura(SPELL_VEHICLE_TELEPORT) && vehicleCreature->getFaction() == WintergraspFaction[wg->GetDefenderTeam()]) + if (Creature* teleportTrigger = vehicleCreature->FindNearestCreature(NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC, 100.0f, true)) + teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true); + + _checkTimer = 1000; + } + else _checkTimer -= diff; + } + + private: + uint32 _checkTimer; + }; + + GameObjectAI* GetAI(GameObject* go) const + { + return new go_wg_vehicle_teleporterAI(go); + } +}; + +class npc_wg_quest_giver : public CreatureScript +{ + public: + npc_wg_quest_giver() : CreatureScript("npc_wg_quest_giver") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; + + if (creature->isQuestGiver()) + { + QuestRelationBounds objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry()); + QuestRelationBounds objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(creature->GetEntry()); + + QuestMenu& qm = player->PlayerTalkClass->GetQuestMenu(); + qm.ClearMenu(); + + for (QuestRelations::const_iterator i = objectQIR.first; i != objectQIR.second; ++i) + { + uint32 questId = i->second; + QuestStatus status = player->GetQuestStatus(questId); + if (status == QUEST_STATUS_COMPLETE) + qm.AddMenuItem(questId, 4); + else if (status == QUEST_STATUS_INCOMPLETE) + qm.AddMenuItem(questId, 4); + //else if (status == QUEST_STATUS_AVAILABLE) + // qm.AddMenuItem(quest_id, 2); + } + + for (QuestRelations::const_iterator i = objectQR.first; i != objectQR.second; ++i) + { + uint32 questId = i->second; + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); + if (!quest) + continue; + + switch (questId) + { + // Horde attacker + case QUEST_BONES_AND_ARROWS_HORDE_ATT: + case QUEST_JINXING_THE_WALLS_HORDE_ATT: + case QUEST_SLAY_THEM_ALL_HORDE_ATT: + case QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT: + case QUEST_HEALING_WITH_ROSES_HORDE_ATT: + case QUEST_DEFEND_THE_SIEGE_HORDE_ATT: + if (wintergrasp->GetAttackerTeam() == TEAM_HORDE) + { + QuestStatus status = player->GetQuestStatus(questId); + + if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 4); + else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 2); + } + break; + // Horde defender + case QUEST_BONES_AND_ARROWS_HORDE_DEF: + case QUEST_WARDING_THE_WALLS_HORDE_DEF: + case QUEST_SLAY_THEM_ALL_HORDE_DEF: + case QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF: + case QUEST_HEALING_WITH_ROSES_HORDE_DEF: + case QUEST_TOPPLING_THE_TOWERS_HORDE_DEF: + case QUEST_STOP_THE_SIEGE_HORDE_DEF: + if (wintergrasp->GetDefenderTeam() == TEAM_HORDE) + { + QuestStatus status = player->GetQuestStatus(questId); + + if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 4); + else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 2); + } + break; + // Alliance attacker + case QUEST_BONES_AND_ARROWS_ALLIANCE_ATT: + case QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT: + case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT: + case QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT: + case QUEST_A_RARE_HERB_ALLIANCE_ATT: + if (wintergrasp->GetAttackerTeam() == TEAM_ALLIANCE) + { + QuestStatus status = player->GetQuestStatus(questId); + + if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 4); + else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 2); + } + break; + // Alliance defender + case QUEST_BONES_AND_ARROWS_ALLIANCE_DEF: + case QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF: + case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF: + case QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF: + case QUEST_STOP_THE_SIEGE_ALLIANCE_DEF: + case QUEST_A_RARE_HERB_ALLIANCE_DEF: + if (wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE) + { + QuestStatus status = player->GetQuestStatus(questId); + + if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 4); + else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 2); + } + break; + default: + QuestStatus status = player->GetQuestStatus(questId); + + if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 4); + else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) + qm.AddMenuItem(questId, 2); + break; + } + } + } + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } +}; + +class spell_wintergrasp_force_building : public SpellScriptLoader +{ + public: + spell_wintergrasp_force_building() : SpellScriptLoader("spell_wintergrasp_force_building") { } + + class spell_wintergrasp_force_building_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wintergrasp_force_building_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_BUILD_CATAPULT_FORCE) + || !sSpellMgr->GetSpellInfo(SPELL_BUILD_DEMOLISHER_FORCE) + || !sSpellMgr->GetSpellInfo(SPELL_BUILD_SIEGE_VEHICLE_FORCE_HORDE) + || !sSpellMgr->GetSpellInfo(SPELL_BUILD_SIEGE_VEHICLE_FORCE_ALLIANCE)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), GetEffectValue(), false); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_force_building_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wintergrasp_force_building_SpellScript(); + } +}; + +class spell_wintergrasp_grab_passenger : public SpellScriptLoader +{ + public: + spell_wintergrasp_grab_passenger() : SpellScriptLoader("spell_wintergrasp_grab_passenger") { } + + class spell_wintergrasp_grab_passenger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wintergrasp_grab_passenger_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* target = GetHitPlayer()) + target->CastSpell(GetCaster(), SPELL_RIDE_WG_VEHICLE, false); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_grab_passenger_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wintergrasp_grab_passenger_SpellScript(); + } +}; + +class achievement_wg_didnt_stand_a_chance : public AchievementCriteriaScript +{ +public: + achievement_wg_didnt_stand_a_chance() : AchievementCriteriaScript("achievement_wg_didnt_stand_a_chance") { } + + bool OnCheck(Player* source, Unit* target) + { + if (!target) + return false; + + if (Player* victim = target->ToPlayer()) + { + if (!victim->IsMounted()) + return false; + + if (Vehicle* vehicle = source->GetVehicle()) + if (vehicle->GetVehicleInfo()->m_ID == 244) // Wintergrasp Tower Cannon + return true; + } + + return false; + } +}; + +enum WgTeleport +{ + SPELL_WINTERGRASP_TELEPORT_TRIGGER = 54643, +}; + +class spell_wintergrasp_defender_teleport : public SpellScriptLoader +{ +public: + spell_wintergrasp_defender_teleport() : SpellScriptLoader("spell_wintergrasp_defender_teleport") { } + + class spell_wintergrasp_defender_teleport_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wintergrasp_defender_teleport_SpellScript); + + SpellCastResult CheckCast() + { + if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) + if (Player* target = GetExplTargetUnit()->ToPlayer()) + // check if we are in Wintergrasp at all, SotA uses same teleport spells + if ((target->GetZoneId() == 4197 && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER)) + return SPELL_FAILED_BAD_TARGETS; + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_wintergrasp_defender_teleport_SpellScript::CheckCast); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wintergrasp_defender_teleport_SpellScript(); + } +}; + +class spell_wintergrasp_defender_teleport_trigger : public SpellScriptLoader +{ +public: + spell_wintergrasp_defender_teleport_trigger() : SpellScriptLoader("spell_wintergrasp_defender_teleport_trigger") { } + + class spell_wintergrasp_defender_teleport_trigger_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wintergrasp_defender_teleport_trigger_SpellScript); + + void HandleDummy(SpellEffIndex /*effindex*/) + { + if (Unit* target = GetHitUnit()) + { + WorldLocation loc; + target->GetPosition(&loc); + SetExplTargetDest(loc); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_defender_teleport_trigger_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wintergrasp_defender_teleport_trigger_SpellScript(); + } +}; + +void AddSC_wintergrasp() +{ + new npc_wg_queue(); + new npc_wg_spirit_guide(); + new npc_wg_demolisher_engineer(); + new go_wg_vehicle_teleporter(); + new npc_wg_quest_giver(); + new spell_wintergrasp_force_building(); + new spell_wintergrasp_grab_passenger(); + new achievement_wg_didnt_stand_a_chance(); + new spell_wintergrasp_defender_teleport(); + new spell_wintergrasp_defender_teleport_trigger(); +} diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp new file mode 100644 index 00000000000..69e8d900435 --- /dev/null +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -0,0 +1,1431 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "SpellInfo.h" + +/*#### +## npc_drakuru_shackles +####*/ + +enum eDrakuruShackles +{ + SPELL_LEFT_CHAIN = 59951, + SPELL_RIGHT_CHAIN = 59952, + SPELL_UNLOCK_SHACKLE = 55083, + SPELL_FREE_RAGECLAW = 55223, + + NPC_RAGECLAW = 29686, + QUEST_TROLLS_IS_GONE_CRAZY = 12861, +}; + +class npc_drakuru_shackles : public CreatureScript +{ +public: + npc_drakuru_shackles() : CreatureScript("npc_drakuru_shackles") { } + + struct npc_drakuru_shacklesAI : public ScriptedAI + { + npc_drakuru_shacklesAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 RageclawGUID; + + void Reset() + { + RageclawGUID = 0; + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + float x, y, z; + me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 0.1f); + + if (Unit* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000)) + { + RageclawGUID = summon->GetGUID(); + LockRageclaw(); + } + } + + void LockRageclaw() + { + Unit* Rageclaw = Unit::GetCreature(*me, RageclawGUID); + // pointer check not needed + me->SetInFront(Rageclaw); + Rageclaw->SetInFront(me); + + DoCast(Rageclaw, SPELL_LEFT_CHAIN, true); + DoCast(Rageclaw, SPELL_RIGHT_CHAIN, true); + } + + void UnlockRageclaw(Unit* who) + { + if (!who) + return; + + Creature* Rageclaw = Unit::GetCreature(*me, RageclawGUID); + // pointer check not needed + DoCast(Rageclaw, SPELL_FREE_RAGECLAW, true); + + me->setDeathState(DEAD); + } + + void SpellHit(Unit* pCaster, const SpellInfo* pSpell) + { + if (pSpell->Id == SPELL_UNLOCK_SHACKLE) + { + if (pCaster->ToPlayer()->GetQuestStatus(QUEST_TROLLS_IS_GONE_CRAZY) == QUEST_STATUS_INCOMPLETE) + { + if (Creature* pRageclaw = Unit::GetCreature(*me, RageclawGUID)) + { + UnlockRageclaw(pCaster); + pCaster->ToPlayer()->KilledMonster(pRageclaw->GetCreatureTemplate(), RageclawGUID); + me->DisappearAndDie(); + } + else + me->setDeathState(JUST_DIED); + } + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_drakuru_shacklesAI(creature); + } +}; + +/*#### +## npc_captured_rageclaw +####*/ + +enum eRageclaw +{ + SPELL_UNSHACKLED = 55085, + SPELL_KNEEL = 39656 +}; + +const char* SAY_RAGECLAW_1 = "I poop on you, trollses!"; +const char* SAY_RAGECLAW_2 = "ARRRROOOOGGGGAAAA!"; +const char* SAY_RAGECLAW_3 = "No more mister nice wolvar!"; + +#define SAY_RAGECLAW RAND(SAY_RAGECLAW_1, SAY_RAGECLAW_2, SAY_RAGECLAW_3) + +class npc_captured_rageclaw : public CreatureScript +{ +public: + npc_captured_rageclaw() : CreatureScript("npc_captured_rageclaw") { } + + struct npc_captured_rageclawAI : public ScriptedAI + { + npc_captured_rageclawAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 DespawnTimer; + bool Despawn; + + void Reset() + { + Despawn = false; + DespawnTimer = 0; + me->setFaction(35); + DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P + } + + void MoveInLineOfSight(Unit* /*who*/){} + + void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) + { + if (pSpell->Id == SPELL_FREE_RAGECLAW) + { + me->RemoveAurasDueToSpell(SPELL_LEFT_CHAIN); + + me->RemoveAurasDueToSpell(SPELL_RIGHT_CHAIN); + + me->RemoveAurasDueToSpell(SPELL_KNEEL); + + me->setFaction(me->GetCreatureTemplate()->faction_H); + + DoCast(me, SPELL_UNSHACKLED, true); + me->MonsterSay(SAY_RAGECLAW, LANG_UNIVERSAL, 0); + me->GetMotionMaster()->MoveRandom(10); + + DespawnTimer = 10000; + Despawn = true; + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (UpdateVictim()) + { + DoMeleeAttackIfReady(); + return; + } + + if (!Despawn) + return; + + if (DespawnTimer <= uiDiff) + me->DisappearAndDie(); + else DespawnTimer -= uiDiff; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_captured_rageclawAI(creature); + } +}; + +/*#### +## npc_gymer +####*/ + +#define GOSSIP_ITEM_G "I'm ready, Gymer. Let's go!" + +enum eGymer +{ + QUEST_STORM_KING_VENGEANCE = 12919, + SPELL_GYMER = 55568 +}; + +class npc_gymer : public CreatureScript +{ +public: + npc_gymer() : CreatureScript("npc_gymer") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_STORM_KING_VENGEANCE) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_G, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(13640, creature->GetGUID()); + } + + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + player->CastSpell(player, SPELL_GYMER, true); + } + + return true; + } +}; + +/*#### +## npc_gurgthock +####*/ + +enum eGurgthock +{ + QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON = 12935, + QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER = 12936, + QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2 = 12954, + QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1 = 12932, + QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR = 12933, + QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND = 12934, + + NPC_ORINOKO_TUSKBREAKER = 30020, + NPC_KORRAK_BLOODRAGER = 30023, + NPC_YGGDRAS = 30014, + NPC_STINKBEARD = 30017, + NPC_AZ_BARIN = 30026, // air + NPC_DUKE_SINGEN = 30019, // fire + NPC_ERATHIUS = 30025, // earth + NPC_GARGORAL = 30024, // water + NPC_FIEND_WATER = 30044, + NPC_FIEND_AIR = 30045, + NPC_FIEND_FIRE = 30042, + NPC_FIEND_EARTH = 30043, + + SAY_QUEST_ACCEPT_TUSKARRMAGEDON = 0, + SAY_QUEST_ACCEPT_KORRAK_1 = 1, + SAY_QUEST_ACCEPT_KORRAK_2 = 2, + SAY_QUEST_ACCEPT_MAGNATAUR = 3, + EMOTE_YGGDRAS_SPAWN = 4, + SAY_STINKBEARD_SPAWN = 5, + SAY_GURGTHOCK_ELEMENTAL_SPAWN = 6, + + SAY_CALL_FOR_HELP = 0, + SAY_RECRUIT = 0, + + SPELL_CRASHING_WAVE = 55909, // water + SPELL_SHOCKWAVE = 55918, // earth + SPELL_BLAST_OF_AIR = 55912, // air + SPELL_MAGMA_WAVE = 55916, // fire + + SPELL_ORB_OF_WATER = 55888, // fiend of water spell + SPELL_ORB_OF_STORMS = 55882, // fiend of air spell + SPELL_BOULDER = 55886, // fiend of earth spell + SPELL_ORB_OF_FLAME = 55872, // fiend of fire spell +}; + +struct BossAndAdd +{ + uint32 uiBoss; + uint32 uiAdd; + uint32 uiSpell; + uint32 uiAddSpell; +}; + +static BossAndAdd Boss[]= +{ + {NPC_GARGORAL, NPC_FIEND_WATER, SPELL_CRASHING_WAVE, SPELL_ORB_OF_WATER}, + {NPC_AZ_BARIN, NPC_FIEND_AIR, SPELL_BLAST_OF_AIR, SPELL_ORB_OF_STORMS}, + {NPC_DUKE_SINGEN, NPC_FIEND_FIRE, SPELL_MAGMA_WAVE, SPELL_ORB_OF_FLAME}, + {NPC_ERATHIUS, NPC_FIEND_EARTH, SPELL_SHOCKWAVE, SPELL_BOULDER}, +}; + +const Position SpawnPosition[] = +{ + {5754.692f, -2939.46f, 286.276123f, 5.156380f}, // stinkbeard || orinoko || korrak + {5762.054199f, -2954.385010f, 273.826955f, 5.108289f}, //yggdras + {5776.855f, -2989.77979f, 272.96814f, 5.194f} // elementals +}; + +const Position AddSpawnPosition[] = +{ + {5722.487f, -3010.75f, 312.751648f, 0.478f}, // caster location + {5724.983f, -2969.89551f, 286.359619f, 0.478f}, + {5733.76025f, -3000.34644f, 286.359619f, 0.478f}, + {5739.8125f, -2981.524f, 290.7671f, 0.478f}, // caster location + {5742.101f, -2950.75586f, 286.2643f, 5.21f}, + {5743.305f, -3011.29736f, 290.7671f, 0.478f}, // caster location + {5744.417f, -3025.528f, 286.35965f, 0.478f}, + {5763.189f, -3029.67529f, 290.7671f, 0.478f}, + {5769.401f, -2935.121f, 286.335754f, 5.21f}, + {5793.061f, -2934.593f, 286.359619f, 3.53f}, + {5797.32129f, -2955.26855f, 290.7671f, 3.53f}, // caster location + {5813.94531f, -2956.74683f, 286.359619f, 3.53f}, + {5816.85547f, -2974.476f, 290.7671f, 3.53f}, // caster location + {5820.30859f, -3002.83716f, 290.7671f, 3.53f}, // caster location + {5828.50244f, -2981.737f, 286.359619f, 3.53f}, + {5828.899f, -2960.15479f, 312.751648f, 3.53f}, // caster location +}; + +class npc_gurgthock : public CreatureScript +{ +public: + npc_gurgthock() : CreatureScript("npc_gurgthock") { } + + struct npc_gurgthockAI : public ScriptedAI + { + npc_gurgthockAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 SummonGUID; + uint64 uiPlayerGUID; + + uint32 uiTimer; + uint32 uiPhase; + uint32 uiRemoveFlagTimer; + uint32 uiQuest; + uint8 uiBossRandom; + + bool bRemoveFlag; + + void Reset() + { + SummonGUID = 0; + uiPlayerGUID = 0; + + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + uiTimer = 0; + uiPhase = 0; + uiQuest = 0; + uiRemoveFlagTimer = 5000; + + uiBossRandom = 0; + + bRemoveFlag = false; + } + + void SetGUID(uint64 guid, int32 /*id*/) + { + uiPlayerGUID = guid; + } + + void SetData(uint32 uiId, uint32 uiValue) + { + bRemoveFlag = true; + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + + switch (uiId) + { + case 1: + switch (uiValue) + { + case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON: + Talk(SAY_QUEST_ACCEPT_TUSKARRMAGEDON); + uiPhase = 1; + uiTimer = 4000; + break; + case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER: + Talk(SAY_QUEST_ACCEPT_KORRAK_1); + uiPhase = 3; + uiTimer = 3000; + break; + case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2: + case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1: + uiPhase = 6; + uiTimer = 3000; + break; + case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR: + uiTimer = 5000; + uiPhase = 7; + break; + case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND: + uiTimer = 2000; + uiPhase = 12; + break; + } + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + ScriptedAI::UpdateAI(uiDiff); + + if (bRemoveFlag) + { + if (uiRemoveFlagTimer <= uiDiff) + { + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + bRemoveFlag = false; + + uiRemoveFlagTimer = 10000; + } else uiRemoveFlagTimer -= uiDiff; + } + + if (uiPhase) + { + Player* player = me->GetPlayer(*me, uiPlayerGUID); + + if (uiTimer <= uiDiff) + { + switch (uiPhase) + { + case 1: + if (Creature* summon = me->SummonCreature(NPC_ORINOKO_TUSKBREAKER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000)) + SummonGUID = summon->GetGUID(); + uiPhase = 2; + uiTimer = 4000; + break; + case 2: + if (Creature* summon = Unit::GetCreature(*me, SummonGUID)) + summon->GetMotionMaster()->MoveJump(5776.319824f, -2981.005371f, 273.100037f, 10.0f, 20.0f); + uiPhase = 0; + SummonGUID = 0; + break; + case 3: + Talk(SAY_QUEST_ACCEPT_KORRAK_2); + uiTimer = 3000; + uiPhase = 4; + break; + case 4: + if (Creature* summon = me->SummonCreature(NPC_KORRAK_BLOODRAGER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000)) + SummonGUID = summon->GetGUID(); + uiTimer = 3000; + uiPhase = 0; + break; + case 6: + { + if (!player) + return; + + std::string sText = ("The grand Amphitheater of Anguish awaits, " + std::string(player->GetName()) + ". Remember, once a battle starts you have to stay in the area. WIN OR DIE!"); + + me->MonsterSay(sText.c_str(), LANG_UNIVERSAL, 0); + uiTimer = 5000; + uiPhase = 9; + } + break; + case 7: + { + if (!player) + return; + + std::string sText = ("Prepare to make you stand, " + std::string(player->GetName()) + "! Get in the Amphitheater and stand ready! Remember, you and your opponent must stay in the arena at all times or you will be disqualified!"); + me->MonsterSay(sText.c_str(), LANG_UNIVERSAL, 0); + uiTimer = 3000; + uiPhase = 8; + } + break; + case 8: + Talk(SAY_QUEST_ACCEPT_MAGNATAUR); + uiTimer = 5000; + uiPhase = 11; + break; + case 9: + { + if (!player) + return; + + std::string sText = ("Here we are once again, ladies and gentlemen. The epic struggle between life and death in the Amphitheater of Anguish! For this round we have " + std::string(player->GetName()) + " versus the hulking jormungar, Yg... Yggd? Yggdoze? Who comes up with these names?! " + std::string(player->GetName()) + " versus big worm!"); + me->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); + uiTimer = 10000; + uiPhase = 10; + } + break; + case 10: + me->SummonCreature(NPC_YGGDRAS, SpawnPosition[1], TEMPSUMMON_CORPSE_DESPAWN, 1000); + Talk(EMOTE_YGGDRAS_SPAWN); + uiPhase = 0; + break; + case 11: + if (Creature* creature = me->SummonCreature(NPC_STINKBEARD, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000)) + creature->AI()->Talk(SAY_STINKBEARD_SPAWN); + uiPhase = 0; + break; + case 12: + { + if (!player) + return; + + std::string sText = ("Prepare to make you stand, " + std::string(player->GetName()) + "! Get in the Amphitheater and stand ready! Remember, you and your opponent must stay in the arena at all times or you will be disqualified!"); + me->MonsterSay(sText.c_str(), LANG_UNIVERSAL, 0); + uiTimer = 5000; + uiPhase = 13; + } + break; + case 13: + Talk(SAY_GURGTHOCK_ELEMENTAL_SPAWN); + uiTimer = 3000; + uiPhase = 14; + break; + case 14: + uiBossRandom = urand(0, 3); + if (Creature* creature = me->SummonCreature(Boss[uiBossRandom].uiBoss, SpawnPosition[2], TEMPSUMMON_CORPSE_DESPAWN, 1000)) + creature->AI()->SetData(1, uiBossRandom); + uiPhase = 0; + break; + } + }else uiTimer -= uiDiff; + } + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + switch (quest->GetQuestId()) + { + case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON: + creature->AI()->SetData(1, quest->GetQuestId()); + break; + case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER: + creature->AI()->SetData(1, quest->GetQuestId()); + break; + case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2: + case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1: + creature->AI()->SetData(1, quest->GetQuestId()); + break; + case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR: + creature->AI()->SetData(1, quest->GetQuestId()); + break; + case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND: + creature->AI()->SetData(1, quest->GetQuestId()); + break; + } + + creature->AI()->SetGUID(player->GetGUID()); + + return false; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_gurgthockAI(creature); + } +}; + +/*#### +## npc_orinoko_tuskbreaker +####*/ + +enum eOrinokoTuskbreaker +{ + SPELL_BATTLE_SHOUT = 32064, + SPELL_FISHY_SCENT = 55937, + SPELL_IMPALE = 55929, + SPELL_SUMMON_WHISKER = 55946, + + NPC_WHISKER = 30113, + NPC_HUNGRY_PENGUIN = 30110 +}; + +class npc_orinoko_tuskbreaker : public CreatureScript +{ +public: + npc_orinoko_tuskbreaker() : CreatureScript("npc_orinoko_tuskbreaker") { } + + struct npc_orinoko_tuskbreakerAI : public ScriptedAI + { + npc_orinoko_tuskbreakerAI(Creature* creature) : ScriptedAI(creature) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_PASSIVE); + } + + bool bSummoned; + bool bBattleShout; + bool bFishyScent; + + uint32 uiBattleShoutTimer; + uint32 uiFishyScentTimer; + + uint64 AffectedGUID; + uint64 uiWhisker; + + void Reset() + { + bSummoned = false; + bBattleShout = false; + bFishyScent = false; + uiBattleShoutTimer = 0; + uiFishyScentTimer = 20000; + uiWhisker = 0; + AffectedGUID = 0; + } + + void EnterEvadeMode() + { + if (Creature* pWhisker = me->GetCreature(*me, uiWhisker)) + pWhisker->RemoveFromWorld(); + } + + void MovementInform(uint32 type, uint32 /*pointId*/) + { + if (type != EFFECT_MOTION_TYPE) + return; + + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_AGGRESSIVE); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + uiBattleShoutTimer = 7000; + } + + void EnterCombat(Unit* who) + { + DoCast(who, SPELL_IMPALE); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (!bBattleShout && uiBattleShoutTimer <= uiDiff) + { + DoCast(me, SPELL_BATTLE_SHOUT); + bBattleShout = true; + } else uiBattleShoutTimer -= uiDiff; + + if (uiFishyScentTimer <= uiDiff) + { + if (Unit* pAffected = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + DoCast(pAffected, SPELL_FISHY_SCENT); + AffectedGUID = pAffected->GetGUID(); + } + uiFishyScentTimer = 20000; + } else uiFishyScentTimer -= uiDiff; + + if (!bSummoned && !HealthAbovePct(50)) + { + Talk(SAY_CALL_FOR_HELP); + //DoCast(me->getVictim(), SPELL_SUMMON_WHISKER); petai is not working correctly??? + + if (Creature* pWhisker = me->SummonCreature(NPC_WHISKER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0)) + uiWhisker = pWhisker->GetGUID(); + bSummoned = true; + } + + DoMeleeAttackIfReady(); + } + + void JustSummoned(Creature* summon) + { + switch (summon->GetEntry()) + { + case NPC_WHISKER: + summon->AI()->AttackStart(me->getVictim()); + break; + case NPC_HUNGRY_PENGUIN: + if (Unit* pAffected = Unit::GetUnit(*me, AffectedGUID)) + { + if (pAffected->isAlive()) + summon->AI()->AttackStart(pAffected); + } + break; + } + } + + void JustDied(Unit* killer) + { + if (uiWhisker) + if (Creature* pWhisker = me->GetCreature(*me, uiWhisker)) + pWhisker->RemoveFromWorld(); + + if (killer->GetTypeId() == TYPEID_PLAYER) + killer->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON, killer); + + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_orinoko_tuskbreakerAI(creature); + } +}; + +/*#### +## npc_korrak_bloodrager +####*/ + +enum eKorrakBloodrager +{ + SPELL_GROW = 55948, + SPELL_CHARGE = 24193, + SPELL_UPPERCUT = 30471, + SPELL_ENRAGE = 42745 +}; + +class npc_korrak_bloodrager : public CreatureScript +{ +public: + npc_korrak_bloodrager() : CreatureScript("npc_korrak_bloodrager") { } + + struct npc_korrak_bloodragerAI : public npc_escortAI + { + npc_korrak_bloodragerAI(Creature* creature) : npc_escortAI(creature) + { + Start(true, true, 0, NULL); + SetDespawnAtEnd(false); + } + + uint32 uiChargeTimer; + uint32 uiUppercutTimer; + + bool bEnrage; + + void Reset() + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_PASSIVE); + uiChargeTimer = 15000; + uiUppercutTimer = 12000; + bEnrage = false; + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 6: + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_AGGRESSIVE); + break; + } + } + + void EnterCombat(Unit* /*who*/) + { + DoCast(me, SPELL_GROW); + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + + if (uiUppercutTimer <= uiDiff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0)) + DoCast(target, SPELL_UPPERCUT); + uiUppercutTimer = 12000; + } else uiUppercutTimer -= uiDiff; + + if (uiChargeTimer <= uiDiff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0)) + DoCast(target, SPELL_CHARGE); + uiChargeTimer = 15000; + } else uiChargeTimer -= uiDiff; + + if (!bEnrage && !HealthAbovePct(20)) + { + DoCast(me, SPELL_ENRAGE); + bEnrage = true; + } + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) + player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER, killer); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_korrak_bloodragerAI(creature); + } +}; + +/*#### +## npc_yggdras +####*/ + +enum eYggdras +{ + SPELL_CLEAVE = 40504, + SPELL_CORRODE_FLESH = 57076, + SPELL_JORMUNGAR_SPAWN = 55859 +}; + +class npc_yggdras : public CreatureScript +{ +public: + npc_yggdras() : CreatureScript("npc_yggdras") { } + + struct npc_yggdrasAI : public ScriptedAI + { + npc_yggdrasAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 uiCleaveTimer; + uint32 uiCorrodeFleshTimer; + + void Reset() + { + uiCleaveTimer = 9000; + uiCorrodeFleshTimer = 6000; + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (me->getVictim()->GetPositionZ() >= 286.276f) + { + std::list t_list = me->getThreatManager().getThreatList(); + for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + { + if (unit->GetPositionZ() <= 286.276f) + { + me->getThreatManager().resetAllAggro(); + me->AddThreat(unit, 5.0f); + break; + } + EnterEvadeMode(); + } + } + } + + if (uiCleaveTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_CLEAVE); + uiCleaveTimer = 9000; + } else uiCleaveTimer -= uiDiff; + + if (uiCorrodeFleshTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_CORRODE_FLESH); + uiCorrodeFleshTimer = 6000; + } else uiCorrodeFleshTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + { + std::string sText = (std::string(killer->GetName()) + " has defeated Yg.. Yggg-really big worm!"); + summoner->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); + } + + if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1, killer); + player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2, killer); + } + + for (uint8 i = 0; i < 3; ++i) + DoCast(killer, SPELL_JORMUNGAR_SPAWN, true); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_yggdrasAI(creature); + } +}; + +/*#### +## npc_stinkbeard +####*/ + +enum eStinkbeard +{ + SPELL_ENRAGE_STINKBEARD = 50420, + SPELL_KNOCK_AWAY = 31389, + SPELL_STINKY_BEARD = 55867, + SPELL_THUNDERBLADE = 55866, + SPELL_THUNDERCLAP = 15588 +}; + +class npc_stinkbeard : public CreatureScript +{ +public: + npc_stinkbeard() : CreatureScript("npc_stinkbeard") { } + + struct npc_stinkbeardAI : public npc_escortAI + { + npc_stinkbeardAI(Creature* creature) : npc_escortAI(creature) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_PASSIVE); + Start(true, true, 0, NULL); + SetDespawnAtEnd(false); + } + + uint32 uiKnockAwayTimer; + uint32 uiStinkyBeardTimer; + + bool bEnrage; + bool bThunderClap; + + void Reset() + { + me->AddAura(SPELL_THUNDERBLADE, me); + uiKnockAwayTimer = 10000; + uiStinkyBeardTimer = 15000; + bEnrage = false; + bThunderClap = false; + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 7: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + me->SetReactState(REACT_AGGRESSIVE); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + break; + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + + if (Unit* victim = me->getVictim()) + { + if (victim->GetPositionZ() >= 286.276f) + { + std::list t_list = me->getThreatManager().getThreatList(); + for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + { + if (unit->GetPositionZ() <= 286.276f) + { + me->getThreatManager().resetAllAggro(); + me->AddThreat(unit, 5.0f); + break; + } + EnterEvadeMode(); + } + } + } + } + + if (bThunderClap && !HealthAbovePct(10)) + { + DoCastAOE(SPELL_THUNDERCLAP); + bThunderClap = true; + } + + if (uiKnockAwayTimer <= uiDiff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + if (target && target->isAlive()) + DoCast(target, SPELL_KNOCK_AWAY); + } + uiKnockAwayTimer = 10000; + } else uiKnockAwayTimer -= uiDiff; + + if (uiStinkyBeardTimer <= uiDiff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + if (target && target->isAlive()) + DoCast(target, SPELL_STINKY_BEARD); + } + uiStinkyBeardTimer = 15000; + } else uiStinkyBeardTimer -= uiDiff; + + if (!bEnrage && !HealthAbovePct(20)) + { + DoCast(me, SPELL_ENRAGE_STINKBEARD); + bEnrage = true; + } + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) + player->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR, killer); + + std::string sText = ("And with AUTHORITY, " + std::string(killer->GetName()) + " dominates the magnataur lord! Stinkbeard's clan is gonna miss him back home in the Dragonblight!"); + me->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_stinkbeardAI(creature); + } +}; + +/*#### +## npc_elemental_lord +####*/ + +class npc_elemental_lord : public CreatureScript +{ +public: + npc_elemental_lord() : CreatureScript("npc_elemental_lord") { } + + struct npc_elemental_lordAI : public ScriptedAI + { + npc_elemental_lordAI(Creature* creature) : ScriptedAI(creature) {} + + std::list SummonList; + + uint32 uiElementalSpellTimer; + + uint8 uiBossRandom; + uint32 uiSpellInfo; + + bool bAddAttack; + + void Reset() + { + uiBossRandom = 0; + uiSpellInfo = 0; + uiElementalSpellTimer = urand(5000, 8000); + + bAddAttack = false; + } + + void SetData(uint32 uiData, uint32 uiValue) + { + if (uiData == 1) + { + uiBossRandom = uiValue; + SummonAdds(); + } + } + + void SummonAdds() + { + if (!Boss[uiBossRandom].uiAdd) + return; + + SummonList.clear(); + + for (uint8 uiI = 0; uiI < 16; uiI++) + { + if (Creature* summon = me->SummonCreature(Boss[uiBossRandom].uiAdd, AddSpawnPosition[uiI])) + { + summon->AI()->SetData(1, uiBossRandom); + SummonList.push_back(summon->GetGUID()); + } + } + + } + + void EnterCombat(Unit* unit) + { + if (!SummonList.empty()) + for (std::list::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) + { + if (Creature* temp = Unit::GetCreature(*me, *itr)) + { + temp->m_CombatDistance = 100.0f; // ugly hack? we are not in a instance sorry. :( + temp->AI()->AttackStart(unit); + } + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (me->getVictim()->GetPositionZ() >= 286.276f) + { + std::list t_list = me->getThreatManager().getThreatList(); + for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + { + if (unit->GetPositionZ() <= 286.276f) + { + me->getThreatManager().resetAllAggro(); + me->AddThreat(unit, 5.0f); + break; + } + EnterEvadeMode(); + } + } + } + + if (uiElementalSpellTimer <= uiDiff) + { + DoCastVictim(Boss[uiBossRandom].uiSpell); + + uiElementalSpellTimer = urand(5000, 8000); + } else uiElementalSpellTimer -= uiDiff; + + if (!bAddAttack && !HealthAbovePct(20)) + { + if (!SummonList.empty()) + for (std::list::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) + { + if (Creature* temp = Unit::GetCreature(*me, *itr)) + { + if (temp->GetPositionZ() >= 287.00f) + continue; + + if (temp->getVictim()) + temp->GetMotionMaster()->MoveChase(temp->getVictim()); + } + } + + bAddAttack = true; + } + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + if (!SummonList.empty()) + for (std::list::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) + if (Creature* temp = Unit::GetCreature(*me, *itr)) + temp->DespawnOrUnsummon(); + + if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) + player->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND, killer); + + std::string sText = (std::string(killer->GetName()) + " is victorious once more!"); + + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + summoner->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_elemental_lordAI(creature); + } +}; + +/*#### +## npc_fiend_elemental +####*/ + +class npc_fiend_elemental : public CreatureScript +{ +public: + npc_fiend_elemental() : CreatureScript("npc_fiend_elemental") { } + + struct npc_fiend_elementalAI : public ScriptedAI + { + npc_fiend_elementalAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 uiMissleTimer; + uint32 uiSpell; + + void Reset() + { + if (me->GetPositionZ() >= 287.0f) + me->GetMotionMaster()->MoveIdle(); + + uiSpell = 0; + uiMissleTimer = urand(2000, 7000); + } + + void AttackStart(Unit* who) + { + if (!who) + return; + + AttackStartNoMove(who); + } + + void SetData(uint32 uiData, uint32 uiValue) + { + if (uiData == 1) + uiSpell = Boss[uiValue].uiAddSpell; + + } + + void UpdateAI(const uint32 uiDiff) + { + if (!UpdateVictim()) + return; + + if (me->GetPositionZ() >= 287.0f) + { + if (uiMissleTimer <= uiDiff) + { + if (uiSpell) // Sometimes it is 0, why? + DoCast(me, uiSpell); // this spell (what spell) is not supported ... YET! + uiMissleTimer = urand(2000, 7000); + } else uiMissleTimer -= uiDiff; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_fiend_elementalAI(creature); + } +}; + +/*#### +## npc_released_offspring_harkoa +####*/ + +class npc_released_offspring_harkoa : public CreatureScript +{ +public: + npc_released_offspring_harkoa() : CreatureScript("npc_released_offspring_harkoa") { } + + struct npc_released_offspring_harkoaAI : public ScriptedAI + { + npc_released_offspring_harkoaAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + float x, y, z; + me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 25.0f); + me->GetMotionMaster()->MovePoint(0, x, y, z); + } + + void MovementInform(uint32 uiType, uint32 /*uiId*/) + { + if (uiType != POINT_MOTION_TYPE) + return; + me->DisappearAndDie(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_released_offspring_harkoaAI(creature); + } +}; + +/*###### +## npc_crusade_recruit +######*/ + +enum eCrusade_recruit +{ + SPELL_QUEST_CREDIT = 50633, + + QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE = 12509, + + GOSSIP_CRUSADE_TEXT = 13069 +}; + +#define GOSSIP_ITEM_1 "Get out there and make those Scourge wish they were never reborn!" + +class npc_crusade_recruit : public CreatureScript +{ +public: + npc_crusade_recruit() : CreatureScript("npc_crusade_recruit") { } + + struct npc_crusade_recruitAI : public ScriptedAI + { + npc_crusade_recruitAI(Creature* creature) : ScriptedAI(creature) {} + + uint8 m_uiPhase; //The current phase we are in + uint32 m_uiTimer; //Timer until phase transition + float m_heading; //Store creature heading + + void Reset() + { + m_uiTimer = 0; + m_uiPhase = 0; + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); + m_heading = me->GetOrientation(); + } + + void UpdateAI(const uint32 uiDiff) + { + if (m_uiPhase) + { + if (m_uiTimer <= uiDiff) + { + switch (m_uiPhase) + { + case 1: + // say random text + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); + Talk(SAY_RECRUIT); + m_uiTimer = 3000; + m_uiPhase = 2; + break; + case 2: + // walk forward + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + (cos(m_heading) * 10), me->GetPositionY() + (sin(m_heading) * 10), me->GetPositionZ()); + m_uiTimer = 5000; + m_uiPhase = 3; + break; + case 3: + // despawn + me->DisappearAndDie(); + m_uiTimer = 0; + m_uiPhase = 0; + break; + } + } + else + m_uiTimer -= uiDiff; + } + ScriptedAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_crusade_recruitAI(creature); + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + player->SEND_GOSSIP_MENU(GOSSIP_CRUSADE_TEXT, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF +1) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_QUEST_CREDIT, true); + CAST_AI(npc_crusade_recruit::npc_crusade_recruitAI, (creature->AI()))->m_uiPhase = 1; + creature->SetInFront(player); + creature->SendMovementFlagUpdate(); + } + + return true; + } +}; + +/*###### +## Quest 12916: Our Only Hope! +## go_scourge_enclosure +######*/ + +enum eScourgeEnclosure +{ + QUEST_OUR_ONLY_HOPE = 12916, + NPC_GYMER_DUMMY = 29928 //from quest template +}; + +class go_scourge_enclosure : public GameObjectScript +{ +public: + go_scourge_enclosure() : GameObjectScript("go_scourge_enclosure") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + if (player->GetQuestStatus(QUEST_OUR_ONLY_HOPE) == QUEST_STATUS_INCOMPLETE) + { + Creature* pGymerDummy = go->FindNearestCreature(NPC_GYMER_DUMMY, 20.0f); + if (pGymerDummy) + { + player->KilledMonsterCredit(pGymerDummy->GetEntry(), pGymerDummy->GetGUID()); + pGymerDummy->CastSpell(pGymerDummy, 55529, true); + pGymerDummy->DisappearAndDie(); + } + } + return true; + } +}; + +void AddSC_zuldrak() +{ + new npc_drakuru_shackles; + new npc_captured_rageclaw; + new npc_gymer; + new npc_gurgthock; + new npc_orinoko_tuskbreaker; + new npc_korrak_bloodrager; + new npc_yggdras; + new npc_stinkbeard; + new npc_released_offspring_harkoa; + new npc_crusade_recruit; + new npc_elemental_lord; + new npc_fiend_elemental; + new go_scourge_enclosure; +} diff --git a/src/server/scripts/Northrend/zuldrak.cpp b/src/server/scripts/Northrend/zuldrak.cpp deleted file mode 100644 index 69e8d900435..00000000000 --- a/src/server/scripts/Northrend/zuldrak.cpp +++ /dev/null @@ -1,1431 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "SpellInfo.h" - -/*#### -## npc_drakuru_shackles -####*/ - -enum eDrakuruShackles -{ - SPELL_LEFT_CHAIN = 59951, - SPELL_RIGHT_CHAIN = 59952, - SPELL_UNLOCK_SHACKLE = 55083, - SPELL_FREE_RAGECLAW = 55223, - - NPC_RAGECLAW = 29686, - QUEST_TROLLS_IS_GONE_CRAZY = 12861, -}; - -class npc_drakuru_shackles : public CreatureScript -{ -public: - npc_drakuru_shackles() : CreatureScript("npc_drakuru_shackles") { } - - struct npc_drakuru_shacklesAI : public ScriptedAI - { - npc_drakuru_shacklesAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 RageclawGUID; - - void Reset() - { - RageclawGUID = 0; - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - float x, y, z; - me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 0.1f); - - if (Unit* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000)) - { - RageclawGUID = summon->GetGUID(); - LockRageclaw(); - } - } - - void LockRageclaw() - { - Unit* Rageclaw = Unit::GetCreature(*me, RageclawGUID); - // pointer check not needed - me->SetInFront(Rageclaw); - Rageclaw->SetInFront(me); - - DoCast(Rageclaw, SPELL_LEFT_CHAIN, true); - DoCast(Rageclaw, SPELL_RIGHT_CHAIN, true); - } - - void UnlockRageclaw(Unit* who) - { - if (!who) - return; - - Creature* Rageclaw = Unit::GetCreature(*me, RageclawGUID); - // pointer check not needed - DoCast(Rageclaw, SPELL_FREE_RAGECLAW, true); - - me->setDeathState(DEAD); - } - - void SpellHit(Unit* pCaster, const SpellInfo* pSpell) - { - if (pSpell->Id == SPELL_UNLOCK_SHACKLE) - { - if (pCaster->ToPlayer()->GetQuestStatus(QUEST_TROLLS_IS_GONE_CRAZY) == QUEST_STATUS_INCOMPLETE) - { - if (Creature* pRageclaw = Unit::GetCreature(*me, RageclawGUID)) - { - UnlockRageclaw(pCaster); - pCaster->ToPlayer()->KilledMonster(pRageclaw->GetCreatureTemplate(), RageclawGUID); - me->DisappearAndDie(); - } - else - me->setDeathState(JUST_DIED); - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_drakuru_shacklesAI(creature); - } -}; - -/*#### -## npc_captured_rageclaw -####*/ - -enum eRageclaw -{ - SPELL_UNSHACKLED = 55085, - SPELL_KNEEL = 39656 -}; - -const char* SAY_RAGECLAW_1 = "I poop on you, trollses!"; -const char* SAY_RAGECLAW_2 = "ARRRROOOOGGGGAAAA!"; -const char* SAY_RAGECLAW_3 = "No more mister nice wolvar!"; - -#define SAY_RAGECLAW RAND(SAY_RAGECLAW_1, SAY_RAGECLAW_2, SAY_RAGECLAW_3) - -class npc_captured_rageclaw : public CreatureScript -{ -public: - npc_captured_rageclaw() : CreatureScript("npc_captured_rageclaw") { } - - struct npc_captured_rageclawAI : public ScriptedAI - { - npc_captured_rageclawAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 DespawnTimer; - bool Despawn; - - void Reset() - { - Despawn = false; - DespawnTimer = 0; - me->setFaction(35); - DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P - } - - void MoveInLineOfSight(Unit* /*who*/){} - - void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) - { - if (pSpell->Id == SPELL_FREE_RAGECLAW) - { - me->RemoveAurasDueToSpell(SPELL_LEFT_CHAIN); - - me->RemoveAurasDueToSpell(SPELL_RIGHT_CHAIN); - - me->RemoveAurasDueToSpell(SPELL_KNEEL); - - me->setFaction(me->GetCreatureTemplate()->faction_H); - - DoCast(me, SPELL_UNSHACKLED, true); - me->MonsterSay(SAY_RAGECLAW, LANG_UNIVERSAL, 0); - me->GetMotionMaster()->MoveRandom(10); - - DespawnTimer = 10000; - Despawn = true; - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (UpdateVictim()) - { - DoMeleeAttackIfReady(); - return; - } - - if (!Despawn) - return; - - if (DespawnTimer <= uiDiff) - me->DisappearAndDie(); - else DespawnTimer -= uiDiff; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_captured_rageclawAI(creature); - } -}; - -/*#### -## npc_gymer -####*/ - -#define GOSSIP_ITEM_G "I'm ready, Gymer. Let's go!" - -enum eGymer -{ - QUEST_STORM_KING_VENGEANCE = 12919, - SPELL_GYMER = 55568 -}; - -class npc_gymer : public CreatureScript -{ -public: - npc_gymer() : CreatureScript("npc_gymer") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_STORM_KING_VENGEANCE) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_G, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(13640, creature->GetGUID()); - } - - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - player->CastSpell(player, SPELL_GYMER, true); - } - - return true; - } -}; - -/*#### -## npc_gurgthock -####*/ - -enum eGurgthock -{ - QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON = 12935, - QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER = 12936, - QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2 = 12954, - QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1 = 12932, - QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR = 12933, - QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND = 12934, - - NPC_ORINOKO_TUSKBREAKER = 30020, - NPC_KORRAK_BLOODRAGER = 30023, - NPC_YGGDRAS = 30014, - NPC_STINKBEARD = 30017, - NPC_AZ_BARIN = 30026, // air - NPC_DUKE_SINGEN = 30019, // fire - NPC_ERATHIUS = 30025, // earth - NPC_GARGORAL = 30024, // water - NPC_FIEND_WATER = 30044, - NPC_FIEND_AIR = 30045, - NPC_FIEND_FIRE = 30042, - NPC_FIEND_EARTH = 30043, - - SAY_QUEST_ACCEPT_TUSKARRMAGEDON = 0, - SAY_QUEST_ACCEPT_KORRAK_1 = 1, - SAY_QUEST_ACCEPT_KORRAK_2 = 2, - SAY_QUEST_ACCEPT_MAGNATAUR = 3, - EMOTE_YGGDRAS_SPAWN = 4, - SAY_STINKBEARD_SPAWN = 5, - SAY_GURGTHOCK_ELEMENTAL_SPAWN = 6, - - SAY_CALL_FOR_HELP = 0, - SAY_RECRUIT = 0, - - SPELL_CRASHING_WAVE = 55909, // water - SPELL_SHOCKWAVE = 55918, // earth - SPELL_BLAST_OF_AIR = 55912, // air - SPELL_MAGMA_WAVE = 55916, // fire - - SPELL_ORB_OF_WATER = 55888, // fiend of water spell - SPELL_ORB_OF_STORMS = 55882, // fiend of air spell - SPELL_BOULDER = 55886, // fiend of earth spell - SPELL_ORB_OF_FLAME = 55872, // fiend of fire spell -}; - -struct BossAndAdd -{ - uint32 uiBoss; - uint32 uiAdd; - uint32 uiSpell; - uint32 uiAddSpell; -}; - -static BossAndAdd Boss[]= -{ - {NPC_GARGORAL, NPC_FIEND_WATER, SPELL_CRASHING_WAVE, SPELL_ORB_OF_WATER}, - {NPC_AZ_BARIN, NPC_FIEND_AIR, SPELL_BLAST_OF_AIR, SPELL_ORB_OF_STORMS}, - {NPC_DUKE_SINGEN, NPC_FIEND_FIRE, SPELL_MAGMA_WAVE, SPELL_ORB_OF_FLAME}, - {NPC_ERATHIUS, NPC_FIEND_EARTH, SPELL_SHOCKWAVE, SPELL_BOULDER}, -}; - -const Position SpawnPosition[] = -{ - {5754.692f, -2939.46f, 286.276123f, 5.156380f}, // stinkbeard || orinoko || korrak - {5762.054199f, -2954.385010f, 273.826955f, 5.108289f}, //yggdras - {5776.855f, -2989.77979f, 272.96814f, 5.194f} // elementals -}; - -const Position AddSpawnPosition[] = -{ - {5722.487f, -3010.75f, 312.751648f, 0.478f}, // caster location - {5724.983f, -2969.89551f, 286.359619f, 0.478f}, - {5733.76025f, -3000.34644f, 286.359619f, 0.478f}, - {5739.8125f, -2981.524f, 290.7671f, 0.478f}, // caster location - {5742.101f, -2950.75586f, 286.2643f, 5.21f}, - {5743.305f, -3011.29736f, 290.7671f, 0.478f}, // caster location - {5744.417f, -3025.528f, 286.35965f, 0.478f}, - {5763.189f, -3029.67529f, 290.7671f, 0.478f}, - {5769.401f, -2935.121f, 286.335754f, 5.21f}, - {5793.061f, -2934.593f, 286.359619f, 3.53f}, - {5797.32129f, -2955.26855f, 290.7671f, 3.53f}, // caster location - {5813.94531f, -2956.74683f, 286.359619f, 3.53f}, - {5816.85547f, -2974.476f, 290.7671f, 3.53f}, // caster location - {5820.30859f, -3002.83716f, 290.7671f, 3.53f}, // caster location - {5828.50244f, -2981.737f, 286.359619f, 3.53f}, - {5828.899f, -2960.15479f, 312.751648f, 3.53f}, // caster location -}; - -class npc_gurgthock : public CreatureScript -{ -public: - npc_gurgthock() : CreatureScript("npc_gurgthock") { } - - struct npc_gurgthockAI : public ScriptedAI - { - npc_gurgthockAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 SummonGUID; - uint64 uiPlayerGUID; - - uint32 uiTimer; - uint32 uiPhase; - uint32 uiRemoveFlagTimer; - uint32 uiQuest; - uint8 uiBossRandom; - - bool bRemoveFlag; - - void Reset() - { - SummonGUID = 0; - uiPlayerGUID = 0; - - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - uiTimer = 0; - uiPhase = 0; - uiQuest = 0; - uiRemoveFlagTimer = 5000; - - uiBossRandom = 0; - - bRemoveFlag = false; - } - - void SetGUID(uint64 guid, int32 /*id*/) - { - uiPlayerGUID = guid; - } - - void SetData(uint32 uiId, uint32 uiValue) - { - bRemoveFlag = true; - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - - switch (uiId) - { - case 1: - switch (uiValue) - { - case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON: - Talk(SAY_QUEST_ACCEPT_TUSKARRMAGEDON); - uiPhase = 1; - uiTimer = 4000; - break; - case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER: - Talk(SAY_QUEST_ACCEPT_KORRAK_1); - uiPhase = 3; - uiTimer = 3000; - break; - case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2: - case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1: - uiPhase = 6; - uiTimer = 3000; - break; - case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR: - uiTimer = 5000; - uiPhase = 7; - break; - case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND: - uiTimer = 2000; - uiPhase = 12; - break; - } - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - ScriptedAI::UpdateAI(uiDiff); - - if (bRemoveFlag) - { - if (uiRemoveFlagTimer <= uiDiff) - { - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - bRemoveFlag = false; - - uiRemoveFlagTimer = 10000; - } else uiRemoveFlagTimer -= uiDiff; - } - - if (uiPhase) - { - Player* player = me->GetPlayer(*me, uiPlayerGUID); - - if (uiTimer <= uiDiff) - { - switch (uiPhase) - { - case 1: - if (Creature* summon = me->SummonCreature(NPC_ORINOKO_TUSKBREAKER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000)) - SummonGUID = summon->GetGUID(); - uiPhase = 2; - uiTimer = 4000; - break; - case 2: - if (Creature* summon = Unit::GetCreature(*me, SummonGUID)) - summon->GetMotionMaster()->MoveJump(5776.319824f, -2981.005371f, 273.100037f, 10.0f, 20.0f); - uiPhase = 0; - SummonGUID = 0; - break; - case 3: - Talk(SAY_QUEST_ACCEPT_KORRAK_2); - uiTimer = 3000; - uiPhase = 4; - break; - case 4: - if (Creature* summon = me->SummonCreature(NPC_KORRAK_BLOODRAGER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000)) - SummonGUID = summon->GetGUID(); - uiTimer = 3000; - uiPhase = 0; - break; - case 6: - { - if (!player) - return; - - std::string sText = ("The grand Amphitheater of Anguish awaits, " + std::string(player->GetName()) + ". Remember, once a battle starts you have to stay in the area. WIN OR DIE!"); - - me->MonsterSay(sText.c_str(), LANG_UNIVERSAL, 0); - uiTimer = 5000; - uiPhase = 9; - } - break; - case 7: - { - if (!player) - return; - - std::string sText = ("Prepare to make you stand, " + std::string(player->GetName()) + "! Get in the Amphitheater and stand ready! Remember, you and your opponent must stay in the arena at all times or you will be disqualified!"); - me->MonsterSay(sText.c_str(), LANG_UNIVERSAL, 0); - uiTimer = 3000; - uiPhase = 8; - } - break; - case 8: - Talk(SAY_QUEST_ACCEPT_MAGNATAUR); - uiTimer = 5000; - uiPhase = 11; - break; - case 9: - { - if (!player) - return; - - std::string sText = ("Here we are once again, ladies and gentlemen. The epic struggle between life and death in the Amphitheater of Anguish! For this round we have " + std::string(player->GetName()) + " versus the hulking jormungar, Yg... Yggd? Yggdoze? Who comes up with these names?! " + std::string(player->GetName()) + " versus big worm!"); - me->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); - uiTimer = 10000; - uiPhase = 10; - } - break; - case 10: - me->SummonCreature(NPC_YGGDRAS, SpawnPosition[1], TEMPSUMMON_CORPSE_DESPAWN, 1000); - Talk(EMOTE_YGGDRAS_SPAWN); - uiPhase = 0; - break; - case 11: - if (Creature* creature = me->SummonCreature(NPC_STINKBEARD, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000)) - creature->AI()->Talk(SAY_STINKBEARD_SPAWN); - uiPhase = 0; - break; - case 12: - { - if (!player) - return; - - std::string sText = ("Prepare to make you stand, " + std::string(player->GetName()) + "! Get in the Amphitheater and stand ready! Remember, you and your opponent must stay in the arena at all times or you will be disqualified!"); - me->MonsterSay(sText.c_str(), LANG_UNIVERSAL, 0); - uiTimer = 5000; - uiPhase = 13; - } - break; - case 13: - Talk(SAY_GURGTHOCK_ELEMENTAL_SPAWN); - uiTimer = 3000; - uiPhase = 14; - break; - case 14: - uiBossRandom = urand(0, 3); - if (Creature* creature = me->SummonCreature(Boss[uiBossRandom].uiBoss, SpawnPosition[2], TEMPSUMMON_CORPSE_DESPAWN, 1000)) - creature->AI()->SetData(1, uiBossRandom); - uiPhase = 0; - break; - } - }else uiTimer -= uiDiff; - } - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - switch (quest->GetQuestId()) - { - case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON: - creature->AI()->SetData(1, quest->GetQuestId()); - break; - case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER: - creature->AI()->SetData(1, quest->GetQuestId()); - break; - case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2: - case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1: - creature->AI()->SetData(1, quest->GetQuestId()); - break; - case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR: - creature->AI()->SetData(1, quest->GetQuestId()); - break; - case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND: - creature->AI()->SetData(1, quest->GetQuestId()); - break; - } - - creature->AI()->SetGUID(player->GetGUID()); - - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_gurgthockAI(creature); - } -}; - -/*#### -## npc_orinoko_tuskbreaker -####*/ - -enum eOrinokoTuskbreaker -{ - SPELL_BATTLE_SHOUT = 32064, - SPELL_FISHY_SCENT = 55937, - SPELL_IMPALE = 55929, - SPELL_SUMMON_WHISKER = 55946, - - NPC_WHISKER = 30113, - NPC_HUNGRY_PENGUIN = 30110 -}; - -class npc_orinoko_tuskbreaker : public CreatureScript -{ -public: - npc_orinoko_tuskbreaker() : CreatureScript("npc_orinoko_tuskbreaker") { } - - struct npc_orinoko_tuskbreakerAI : public ScriptedAI - { - npc_orinoko_tuskbreakerAI(Creature* creature) : ScriptedAI(creature) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_PASSIVE); - } - - bool bSummoned; - bool bBattleShout; - bool bFishyScent; - - uint32 uiBattleShoutTimer; - uint32 uiFishyScentTimer; - - uint64 AffectedGUID; - uint64 uiWhisker; - - void Reset() - { - bSummoned = false; - bBattleShout = false; - bFishyScent = false; - uiBattleShoutTimer = 0; - uiFishyScentTimer = 20000; - uiWhisker = 0; - AffectedGUID = 0; - } - - void EnterEvadeMode() - { - if (Creature* pWhisker = me->GetCreature(*me, uiWhisker)) - pWhisker->RemoveFromWorld(); - } - - void MovementInform(uint32 type, uint32 /*pointId*/) - { - if (type != EFFECT_MOTION_TYPE) - return; - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_AGGRESSIVE); - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - uiBattleShoutTimer = 7000; - } - - void EnterCombat(Unit* who) - { - DoCast(who, SPELL_IMPALE); - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - - if (!bBattleShout && uiBattleShoutTimer <= uiDiff) - { - DoCast(me, SPELL_BATTLE_SHOUT); - bBattleShout = true; - } else uiBattleShoutTimer -= uiDiff; - - if (uiFishyScentTimer <= uiDiff) - { - if (Unit* pAffected = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - DoCast(pAffected, SPELL_FISHY_SCENT); - AffectedGUID = pAffected->GetGUID(); - } - uiFishyScentTimer = 20000; - } else uiFishyScentTimer -= uiDiff; - - if (!bSummoned && !HealthAbovePct(50)) - { - Talk(SAY_CALL_FOR_HELP); - //DoCast(me->getVictim(), SPELL_SUMMON_WHISKER); petai is not working correctly??? - - if (Creature* pWhisker = me->SummonCreature(NPC_WHISKER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0)) - uiWhisker = pWhisker->GetGUID(); - bSummoned = true; - } - - DoMeleeAttackIfReady(); - } - - void JustSummoned(Creature* summon) - { - switch (summon->GetEntry()) - { - case NPC_WHISKER: - summon->AI()->AttackStart(me->getVictim()); - break; - case NPC_HUNGRY_PENGUIN: - if (Unit* pAffected = Unit::GetUnit(*me, AffectedGUID)) - { - if (pAffected->isAlive()) - summon->AI()->AttackStart(pAffected); - } - break; - } - } - - void JustDied(Unit* killer) - { - if (uiWhisker) - if (Creature* pWhisker = me->GetCreature(*me, uiWhisker)) - pWhisker->RemoveFromWorld(); - - if (killer->GetTypeId() == TYPEID_PLAYER) - killer->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON, killer); - - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_orinoko_tuskbreakerAI(creature); - } -}; - -/*#### -## npc_korrak_bloodrager -####*/ - -enum eKorrakBloodrager -{ - SPELL_GROW = 55948, - SPELL_CHARGE = 24193, - SPELL_UPPERCUT = 30471, - SPELL_ENRAGE = 42745 -}; - -class npc_korrak_bloodrager : public CreatureScript -{ -public: - npc_korrak_bloodrager() : CreatureScript("npc_korrak_bloodrager") { } - - struct npc_korrak_bloodragerAI : public npc_escortAI - { - npc_korrak_bloodragerAI(Creature* creature) : npc_escortAI(creature) - { - Start(true, true, 0, NULL); - SetDespawnAtEnd(false); - } - - uint32 uiChargeTimer; - uint32 uiUppercutTimer; - - bool bEnrage; - - void Reset() - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_PASSIVE); - uiChargeTimer = 15000; - uiUppercutTimer = 12000; - bEnrage = false; - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 6: - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_AGGRESSIVE); - break; - } - } - - void EnterCombat(Unit* /*who*/) - { - DoCast(me, SPELL_GROW); - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - if (uiUppercutTimer <= uiDiff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0)) - DoCast(target, SPELL_UPPERCUT); - uiUppercutTimer = 12000; - } else uiUppercutTimer -= uiDiff; - - if (uiChargeTimer <= uiDiff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0)) - DoCast(target, SPELL_CHARGE); - uiChargeTimer = 15000; - } else uiChargeTimer -= uiDiff; - - if (!bEnrage && !HealthAbovePct(20)) - { - DoCast(me, SPELL_ENRAGE); - bEnrage = true; - } - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) - player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER, killer); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_korrak_bloodragerAI(creature); - } -}; - -/*#### -## npc_yggdras -####*/ - -enum eYggdras -{ - SPELL_CLEAVE = 40504, - SPELL_CORRODE_FLESH = 57076, - SPELL_JORMUNGAR_SPAWN = 55859 -}; - -class npc_yggdras : public CreatureScript -{ -public: - npc_yggdras() : CreatureScript("npc_yggdras") { } - - struct npc_yggdrasAI : public ScriptedAI - { - npc_yggdrasAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 uiCleaveTimer; - uint32 uiCorrodeFleshTimer; - - void Reset() - { - uiCleaveTimer = 9000; - uiCorrodeFleshTimer = 6000; - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - - if (me->getVictim()->GetPositionZ() >= 286.276f) - { - std::list t_list = me->getThreatManager().getThreatList(); - for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) - { - if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) - { - if (unit->GetPositionZ() <= 286.276f) - { - me->getThreatManager().resetAllAggro(); - me->AddThreat(unit, 5.0f); - break; - } - EnterEvadeMode(); - } - } - } - - if (uiCleaveTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_CLEAVE); - uiCleaveTimer = 9000; - } else uiCleaveTimer -= uiDiff; - - if (uiCorrodeFleshTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_CORRODE_FLESH); - uiCorrodeFleshTimer = 6000; - } else uiCorrodeFleshTimer -= uiDiff; - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - { - std::string sText = (std::string(killer->GetName()) + " has defeated Yg.. Yggg-really big worm!"); - summoner->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); - } - - if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) - { - player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1, killer); - player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2, killer); - } - - for (uint8 i = 0; i < 3; ++i) - DoCast(killer, SPELL_JORMUNGAR_SPAWN, true); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_yggdrasAI(creature); - } -}; - -/*#### -## npc_stinkbeard -####*/ - -enum eStinkbeard -{ - SPELL_ENRAGE_STINKBEARD = 50420, - SPELL_KNOCK_AWAY = 31389, - SPELL_STINKY_BEARD = 55867, - SPELL_THUNDERBLADE = 55866, - SPELL_THUNDERCLAP = 15588 -}; - -class npc_stinkbeard : public CreatureScript -{ -public: - npc_stinkbeard() : CreatureScript("npc_stinkbeard") { } - - struct npc_stinkbeardAI : public npc_escortAI - { - npc_stinkbeardAI(Creature* creature) : npc_escortAI(creature) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_PASSIVE); - Start(true, true, 0, NULL); - SetDespawnAtEnd(false); - } - - uint32 uiKnockAwayTimer; - uint32 uiStinkyBeardTimer; - - bool bEnrage; - bool bThunderClap; - - void Reset() - { - me->AddAura(SPELL_THUNDERBLADE, me); - uiKnockAwayTimer = 10000; - uiStinkyBeardTimer = 15000; - bEnrage = false; - bThunderClap = false; - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 7: - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - me->SetReactState(REACT_AGGRESSIVE); - me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); - break; - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - if (Unit* victim = me->getVictim()) - { - if (victim->GetPositionZ() >= 286.276f) - { - std::list t_list = me->getThreatManager().getThreatList(); - for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) - { - if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) - { - if (unit->GetPositionZ() <= 286.276f) - { - me->getThreatManager().resetAllAggro(); - me->AddThreat(unit, 5.0f); - break; - } - EnterEvadeMode(); - } - } - } - } - - if (bThunderClap && !HealthAbovePct(10)) - { - DoCastAOE(SPELL_THUNDERCLAP); - bThunderClap = true; - } - - if (uiKnockAwayTimer <= uiDiff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (target && target->isAlive()) - DoCast(target, SPELL_KNOCK_AWAY); - } - uiKnockAwayTimer = 10000; - } else uiKnockAwayTimer -= uiDiff; - - if (uiStinkyBeardTimer <= uiDiff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (target && target->isAlive()) - DoCast(target, SPELL_STINKY_BEARD); - } - uiStinkyBeardTimer = 15000; - } else uiStinkyBeardTimer -= uiDiff; - - if (!bEnrage && !HealthAbovePct(20)) - { - DoCast(me, SPELL_ENRAGE_STINKBEARD); - bEnrage = true; - } - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) - player->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR, killer); - - std::string sText = ("And with AUTHORITY, " + std::string(killer->GetName()) + " dominates the magnataur lord! Stinkbeard's clan is gonna miss him back home in the Dragonblight!"); - me->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_stinkbeardAI(creature); - } -}; - -/*#### -## npc_elemental_lord -####*/ - -class npc_elemental_lord : public CreatureScript -{ -public: - npc_elemental_lord() : CreatureScript("npc_elemental_lord") { } - - struct npc_elemental_lordAI : public ScriptedAI - { - npc_elemental_lordAI(Creature* creature) : ScriptedAI(creature) {} - - std::list SummonList; - - uint32 uiElementalSpellTimer; - - uint8 uiBossRandom; - uint32 uiSpellInfo; - - bool bAddAttack; - - void Reset() - { - uiBossRandom = 0; - uiSpellInfo = 0; - uiElementalSpellTimer = urand(5000, 8000); - - bAddAttack = false; - } - - void SetData(uint32 uiData, uint32 uiValue) - { - if (uiData == 1) - { - uiBossRandom = uiValue; - SummonAdds(); - } - } - - void SummonAdds() - { - if (!Boss[uiBossRandom].uiAdd) - return; - - SummonList.clear(); - - for (uint8 uiI = 0; uiI < 16; uiI++) - { - if (Creature* summon = me->SummonCreature(Boss[uiBossRandom].uiAdd, AddSpawnPosition[uiI])) - { - summon->AI()->SetData(1, uiBossRandom); - SummonList.push_back(summon->GetGUID()); - } - } - - } - - void EnterCombat(Unit* unit) - { - if (!SummonList.empty()) - for (std::list::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) - { - if (Creature* temp = Unit::GetCreature(*me, *itr)) - { - temp->m_CombatDistance = 100.0f; // ugly hack? we are not in a instance sorry. :( - temp->AI()->AttackStart(unit); - } - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - - if (me->getVictim()->GetPositionZ() >= 286.276f) - { - std::list t_list = me->getThreatManager().getThreatList(); - for (std::list::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) - { - if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) - { - if (unit->GetPositionZ() <= 286.276f) - { - me->getThreatManager().resetAllAggro(); - me->AddThreat(unit, 5.0f); - break; - } - EnterEvadeMode(); - } - } - } - - if (uiElementalSpellTimer <= uiDiff) - { - DoCastVictim(Boss[uiBossRandom].uiSpell); - - uiElementalSpellTimer = urand(5000, 8000); - } else uiElementalSpellTimer -= uiDiff; - - if (!bAddAttack && !HealthAbovePct(20)) - { - if (!SummonList.empty()) - for (std::list::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) - { - if (Creature* temp = Unit::GetCreature(*me, *itr)) - { - if (temp->GetPositionZ() >= 287.00f) - continue; - - if (temp->getVictim()) - temp->GetMotionMaster()->MoveChase(temp->getVictim()); - } - } - - bAddAttack = true; - } - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - if (!SummonList.empty()) - for (std::list::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr) - if (Creature* temp = Unit::GetCreature(*me, *itr)) - temp->DespawnOrUnsummon(); - - if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself()) - player->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND, killer); - - std::string sText = (std::string(killer->GetName()) + " is victorious once more!"); - - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - summoner->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_elemental_lordAI(creature); - } -}; - -/*#### -## npc_fiend_elemental -####*/ - -class npc_fiend_elemental : public CreatureScript -{ -public: - npc_fiend_elemental() : CreatureScript("npc_fiend_elemental") { } - - struct npc_fiend_elementalAI : public ScriptedAI - { - npc_fiend_elementalAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 uiMissleTimer; - uint32 uiSpell; - - void Reset() - { - if (me->GetPositionZ() >= 287.0f) - me->GetMotionMaster()->MoveIdle(); - - uiSpell = 0; - uiMissleTimer = urand(2000, 7000); - } - - void AttackStart(Unit* who) - { - if (!who) - return; - - AttackStartNoMove(who); - } - - void SetData(uint32 uiData, uint32 uiValue) - { - if (uiData == 1) - uiSpell = Boss[uiValue].uiAddSpell; - - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - - if (me->GetPositionZ() >= 287.0f) - { - if (uiMissleTimer <= uiDiff) - { - if (uiSpell) // Sometimes it is 0, why? - DoCast(me, uiSpell); // this spell (what spell) is not supported ... YET! - uiMissleTimer = urand(2000, 7000); - } else uiMissleTimer -= uiDiff; - } - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_fiend_elementalAI(creature); - } -}; - -/*#### -## npc_released_offspring_harkoa -####*/ - -class npc_released_offspring_harkoa : public CreatureScript -{ -public: - npc_released_offspring_harkoa() : CreatureScript("npc_released_offspring_harkoa") { } - - struct npc_released_offspring_harkoaAI : public ScriptedAI - { - npc_released_offspring_harkoaAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - float x, y, z; - me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 25.0f); - me->GetMotionMaster()->MovePoint(0, x, y, z); - } - - void MovementInform(uint32 uiType, uint32 /*uiId*/) - { - if (uiType != POINT_MOTION_TYPE) - return; - me->DisappearAndDie(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_released_offspring_harkoaAI(creature); - } -}; - -/*###### -## npc_crusade_recruit -######*/ - -enum eCrusade_recruit -{ - SPELL_QUEST_CREDIT = 50633, - - QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE = 12509, - - GOSSIP_CRUSADE_TEXT = 13069 -}; - -#define GOSSIP_ITEM_1 "Get out there and make those Scourge wish they were never reborn!" - -class npc_crusade_recruit : public CreatureScript -{ -public: - npc_crusade_recruit() : CreatureScript("npc_crusade_recruit") { } - - struct npc_crusade_recruitAI : public ScriptedAI - { - npc_crusade_recruitAI(Creature* creature) : ScriptedAI(creature) {} - - uint8 m_uiPhase; //The current phase we are in - uint32 m_uiTimer; //Timer until phase transition - float m_heading; //Store creature heading - - void Reset() - { - m_uiTimer = 0; - m_uiPhase = 0; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); - m_heading = me->GetOrientation(); - } - - void UpdateAI(const uint32 uiDiff) - { - if (m_uiPhase) - { - if (m_uiTimer <= uiDiff) - { - switch (m_uiPhase) - { - case 1: - // say random text - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - Talk(SAY_RECRUIT); - m_uiTimer = 3000; - m_uiPhase = 2; - break; - case 2: - // walk forward - me->SetWalk(true); - me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + (cos(m_heading) * 10), me->GetPositionY() + (sin(m_heading) * 10), me->GetPositionZ()); - m_uiTimer = 5000; - m_uiPhase = 3; - break; - case 3: - // despawn - me->DisappearAndDie(); - m_uiTimer = 0; - m_uiPhase = 0; - break; - } - } - else - m_uiTimer -= uiDiff; - } - ScriptedAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_crusade_recruitAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - player->SEND_GOSSIP_MENU(GOSSIP_CRUSADE_TEXT, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF +1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_QUEST_CREDIT, true); - CAST_AI(npc_crusade_recruit::npc_crusade_recruitAI, (creature->AI()))->m_uiPhase = 1; - creature->SetInFront(player); - creature->SendMovementFlagUpdate(); - } - - return true; - } -}; - -/*###### -## Quest 12916: Our Only Hope! -## go_scourge_enclosure -######*/ - -enum eScourgeEnclosure -{ - QUEST_OUR_ONLY_HOPE = 12916, - NPC_GYMER_DUMMY = 29928 //from quest template -}; - -class go_scourge_enclosure : public GameObjectScript -{ -public: - go_scourge_enclosure() : GameObjectScript("go_scourge_enclosure") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - if (player->GetQuestStatus(QUEST_OUR_ONLY_HOPE) == QUEST_STATUS_INCOMPLETE) - { - Creature* pGymerDummy = go->FindNearestCreature(NPC_GYMER_DUMMY, 20.0f); - if (pGymerDummy) - { - player->KilledMonsterCredit(pGymerDummy->GetEntry(), pGymerDummy->GetGUID()); - pGymerDummy->CastSpell(pGymerDummy, 55529, true); - pGymerDummy->DisappearAndDie(); - } - } - return true; - } -}; - -void AddSC_zuldrak() -{ - new npc_drakuru_shackles; - new npc_captured_rageclaw; - new npc_gymer; - new npc_gurgthock; - new npc_orinoko_tuskbreaker; - new npc_korrak_bloodrager; - new npc_yggdras; - new npc_stinkbeard; - new npc_released_offspring_harkoa; - new npc_crusade_recruit; - new npc_elemental_lord; - new npc_fiend_elemental; - new go_scourge_enclosure; -} diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index b7f4736e91b..f038af07634 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -10,7 +10,7 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} - Outland/nagrand.cpp + Outland/zone_nagrand.cpp Outland/HellfireCitadel/MagtheridonsLair/magtheridons_lair.h Outland/HellfireCitadel/MagtheridonsLair/instance_magtheridons_lair.cpp Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -44,7 +44,7 @@ set(scripts_STAT_SRCS Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp Outland/CoilfangReservoir/underbog/boss_hungarfen.cpp Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp - Outland/shattrath_city.cpp + Outland/zone_shattrath_city.cpp Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp @@ -85,8 +85,8 @@ set(scripts_STAT_SRCS Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp Outland/boss_doomwalker.cpp - Outland/terokkar_forest.cpp - Outland/hellfire_peninsula.cpp + Outland/zone_terokkar_forest.cpp + Outland/zone_hellfire_peninsula.cpp Outland/boss_doomlord_kazzak.cpp Outland/BlackTemple/boss_teron_gorefiend.cpp Outland/BlackTemple/black_temple.h @@ -100,14 +100,14 @@ set(scripts_STAT_SRCS Outland/BlackTemple/boss_warlord_najentus.cpp Outland/BlackTemple/boss_bloodboil.cpp Outland/BlackTemple/boss_illidan.cpp - Outland/shadowmoon_valley.cpp - Outland/blades_edge_mountains.cpp + Outland/zone_shadowmoon_valley.cpp + Outland/zone_blades_edge_mountains.cpp Outland/GruulsLair/boss_high_king_maulgar.cpp Outland/GruulsLair/boss_gruul.cpp Outland/GruulsLair/gruuls_lair.h Outland/GruulsLair/instance_gruuls_lair.cpp - Outland/netherstorm.cpp - Outland/zangarmarsh.cpp + Outland/zone_netherstorm.cpp + Outland/zone_zangarmarsh.cpp ) message(" -> Prepared: Outland") diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp deleted file mode 100644 index d03abc82b9c..00000000000 --- a/src/server/scripts/Outland/blades_edge_mountains.cpp +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Blades_Edge_Mountains -SD%Complete: 90 -SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete) -SDCategory: Blade's Edge Mountains -EndScriptData */ - -/* ContentData -mobs_bladespire_ogre -mobs_nether_drake -npc_daranelle -npc_overseer_nuaar -npc_saikkal_the_elder -go_legion_obelisk -go_thunderspike -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "Cell.h" -#include "CellImpl.h" - -//Support for quest: You're Fired! (10821) -bool obelisk_one, obelisk_two, obelisk_three, obelisk_four, obelisk_five; - -#define LEGION_OBELISK_ONE 185193 -#define LEGION_OBELISK_TWO 185195 -#define LEGION_OBELISK_THREE 185196 -#define LEGION_OBELISK_FOUR 185197 -#define LEGION_OBELISK_FIVE 185198 - -/*###### -## mobs_bladespire_ogre -######*/ - -//TODO: add support for quest 10512 + Creature abilities -class mobs_bladespire_ogre : public CreatureScript -{ -public: - mobs_bladespire_ogre() : CreatureScript("mobs_bladespire_ogre") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mobs_bladespire_ogreAI (creature); - } - - struct mobs_bladespire_ogreAI : public ScriptedAI - { - mobs_bladespire_ogreAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() { } - - void UpdateAI(const uint32 /*uiDiff*/) - { - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## mobs_nether_drake -######*/ - -enum eNetherdrake -{ - //Used by 20021, 21817, 21820, 21821, 21823 but not existing in database - SAY_NIHIL_1 = 0, - SAY_NIHIL_2 = 1, - SAY_NIHIL_3 = 2, - SAY_NIHIL_4 = 3, - SAY_NIHIL_INTERRUPT = 4, - - ENTRY_WHELP = 20021, - ENTRY_PROTO = 21821, - ENTRY_ADOLE = 21817, - ENTRY_MATUR = 21820, - ENTRY_NIHIL = 21823, - - SPELL_T_PHASE_MODULATOR = 37573, - - SPELL_ARCANE_BLAST = 38881, - SPELL_MANA_BURN = 38884, - SPELL_INTANGIBLE_PRESENCE = 36513 -}; - -class mobs_nether_drake : public CreatureScript -{ -public: - mobs_nether_drake() : CreatureScript("mobs_nether_drake") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mobs_nether_drakeAI (creature); - } - - struct mobs_nether_drakeAI : public ScriptedAI - { - mobs_nether_drakeAI(Creature* creature) : ScriptedAI(creature) {} - - bool IsNihil; - uint32 NihilSpeech_Timer; - uint32 NihilSpeech_Phase; - - uint32 ArcaneBlast_Timer; - uint32 ManaBurn_Timer; - uint32 IntangiblePresence_Timer; - - void Reset() - { - IsNihil = false; - NihilSpeech_Timer = 3000; - NihilSpeech_Phase = 0; - - ArcaneBlast_Timer = 7500; - ManaBurn_Timer = 10000; - IntangiblePresence_Timer = 15000; - } - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* who) - { - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - return; - - ScriptedAI::MoveInLineOfSight(who); - } - - //in case Creature was not summoned (not expected) - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id == 0) - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - me->SetHealth(0); - } - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TYPEID_PLAYER) - { - const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL}; - int cid = rand()%(4-1); - - if (entry_list[cid] == me->GetEntry()) - ++cid; - - //we are nihil, so say before transform - if (me->GetEntry() == ENTRY_NIHIL) - { - Talk(SAY_NIHIL_INTERRUPT); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - IsNihil = false; - } - - if (me->UpdateEntry(entry_list[cid])) - { - if (entry_list[cid] == ENTRY_NIHIL) - { - EnterEvadeMode(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - IsNihil = true; - }else - AttackStart(caster); - } - } - } - - void UpdateAI(const uint32 diff) - { - if (IsNihil) - { - if (NihilSpeech_Timer <= diff) - { - switch (NihilSpeech_Phase) - { - case 0: - Talk(SAY_NIHIL_1); - ++NihilSpeech_Phase; - break; - case 1: - Talk(SAY_NIHIL_2); - ++NihilSpeech_Phase; - break; - case 2: - Talk(SAY_NIHIL_3); - ++NihilSpeech_Phase; - break; - case 3: - Talk(SAY_NIHIL_4); - ++NihilSpeech_Phase; - break; - case 4: - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - //take off to location above - me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+50.0f, me->GetPositionY(), me->GetPositionZ()+50.0f); - ++NihilSpeech_Phase; - break; - } - NihilSpeech_Timer = 5000; - } else NihilSpeech_Timer -=diff; - - //anything below here is not interesting for Nihil, so skip it - return; - } - - if (!UpdateVictim()) - return; - - if (IntangiblePresence_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_INTANGIBLE_PRESENCE); - IntangiblePresence_Timer = 15000+rand()%15000; - } else IntangiblePresence_Timer -= diff; - - if (ManaBurn_Timer <= diff) - { - Unit* target = me->getVictim(); - if (target && target->getPowerType() == POWER_MANA) - DoCast(target, SPELL_MANA_BURN); - ManaBurn_Timer = 8000+rand()%8000; - } else ManaBurn_Timer -= diff; - - if (ArcaneBlast_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_ARCANE_BLAST); - ArcaneBlast_Timer = 2500+rand()%5000; - } else ArcaneBlast_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_daranelle -######*/ - -enum eDaranelle -{ - SAY_SPELL_INFLUENCE = 0, - SPELL_LASHHAN_CHANNEL = 36904 -}; - -class npc_daranelle : public CreatureScript -{ -public: - npc_daranelle() : CreatureScript("npc_daranelle") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_daranelleAI (creature); - } - - struct npc_daranelleAI : public ScriptedAI - { - npc_daranelleAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() { } - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* who) - { - if (who->GetTypeId() == TYPEID_PLAYER) - { - if (who->HasAura(SPELL_LASHHAN_CHANNEL) && me->IsWithinDistInMap(who, 10.0f)) - { - Talk(SAY_SPELL_INFLUENCE, who->GetGUID()); - //TODO: Move the below to updateAI and run if this statement == true - DoCast(who, 37028, true); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - }; -}; - -/*###### -## npc_overseer_nuaar -######*/ - -#define GOSSIP_HELLO_ON "Overseer, I am here to negotiate on behalf of the Cenarion Expedition." - -class npc_overseer_nuaar : public CreatureScript -{ -public: - npc_overseer_nuaar() : CreatureScript("npc_overseer_nuaar") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->SEND_GOSSIP_MENU(10533, creature->GetGUID()); - player->AreaExploredOrEventHappens(10682); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(10682) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_ON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(10532, creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_saikkal_the_elder -######*/ - -#define GOSSIP_HELLO_STE "Yes... yes, it's me." -#define GOSSIP_SELECT_STE "Yes elder. Tell me more of the book." - -class npc_saikkal_the_elder : public CreatureScript -{ -public: - npc_saikkal_the_elder() : CreatureScript("npc_saikkal_the_elder") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_STE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(10795, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - player->SEND_GOSSIP_MENU(10796, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(10980) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_STE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(10794, creature->GetGUID()); - - return true; - } -}; - -/*###### -## go_legion_obelisk -######*/ - -class go_legion_obelisk : public GameObjectScript -{ -public: - go_legion_obelisk() : GameObjectScript("go_legion_obelisk") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE) - { - switch (go->GetEntry()) - { - case LEGION_OBELISK_ONE: - obelisk_one = true; - break; - case LEGION_OBELISK_TWO: - obelisk_two = true; - break; - case LEGION_OBELISK_THREE: - obelisk_three = true; - break; - case LEGION_OBELISK_FOUR: - obelisk_four = true; - break; - case LEGION_OBELISK_FIVE: - obelisk_five = true; - break; - } - - if (obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true) - { - go->SummonCreature(19963, 2943.40f, 4778.20f, 284.49f, 0.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - //reset global var - obelisk_one = false; - obelisk_two = false; - obelisk_three = false; - obelisk_four = false; - obelisk_five = false; - } - } - - return true; - } -}; - -/*###### -## npc_bloodmaul_brutebane -######*/ - -enum eBloodmaul -{ - NPC_OGRE_BRUTE = 19995, - NPC_QUEST_CREDIT = 21241, - GO_KEG = 184315, - QUEST_GETTING_THE_BLADESPIRE_TANKED = 10512, - QUEST_BLADESPIRE_KEGGER = 10545, -}; - -class npc_bloodmaul_brutebane : public CreatureScript -{ -public: - npc_bloodmaul_brutebane() : CreatureScript("npc_bloodmaul_brutebane") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_bloodmaul_brutebaneAI(creature); - } - - struct npc_bloodmaul_brutebaneAI : public ScriptedAI - { - npc_bloodmaul_brutebaneAI(Creature* creature) : ScriptedAI(creature) - { - if (Creature* Ogre = me->FindNearestCreature(NPC_OGRE_BRUTE, 50, true)) - { - Ogre->SetReactState(REACT_DEFENSIVE); - Ogre->GetMotionMaster()->MovePoint(1, me->GetPositionX()-1, me->GetPositionY()+1, me->GetPositionZ()); - } - } - - uint64 OgreGUID; - - void Reset() - { - OgreGUID = 0; - } - - void UpdateAI(const uint32 /*uiDiff*/) {} - }; -}; - -/*###### -## npc_ogre_brute -######*/ - -class npc_ogre_brute : public CreatureScript -{ -public: - npc_ogre_brute() : CreatureScript("npc_ogre_brute") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ogre_bruteAI(creature); - } - - struct npc_ogre_bruteAI : public ScriptedAI - { - npc_ogre_bruteAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - - void Reset() - { - PlayerGUID = 0; - } - - void MoveInLineOfSight(Unit* who) - { - if (!who || (!who->isAlive())) - return; - - if (me->IsWithinDistInMap(who, 50.0f)) - { - if (who->GetTypeId() == TYPEID_PLAYER) - if (who->ToPlayer()->GetQuestStatus(QUEST_GETTING_THE_BLADESPIRE_TANKED) == QUEST_STATUS_INCOMPLETE - || who->ToPlayer()->GetQuestStatus(QUEST_BLADESPIRE_KEGGER) == QUEST_STATUS_INCOMPLETE) - PlayerGUID = who->GetGUID(); - } - } - - void MovementInform(uint32 /*type*/, uint32 id) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (id == 1) - { - GameObject* Keg = me->FindNearestGameObject(GO_KEG, 20); - if (Keg) - Keg->Delete(); - me->HandleEmoteCommand(7); - me->SetReactState(REACT_AGGRESSIVE); - me->GetMotionMaster()->MoveTargetedHome(); - Creature* Credit = me->FindNearestCreature(NPC_QUEST_CREDIT, 50, true); - if (player && Credit) - player->KilledMonster(Credit->GetCreatureTemplate(), Credit->GetGUID()); - } - } - - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## go_thunderspike -######*/ - -enum TheThunderspike -{ - NPC_GOR_GRIMGUT = 21319, - QUEST_THUNDERSPIKE = 10526, -}; - -class go_thunderspike : public GameObjectScript -{ - public: - go_thunderspike() : GameObjectScript("go_thunderspike") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (player->GetQuestStatus(QUEST_THUNDERSPIKE) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_GOR_GRIMGUT, 25.0f, true)) - if (Creature* gorGrimgut = go->SummonCreature(NPC_GOR_GRIMGUT, -2413.4f, 6914.48f, 25.01f, 3.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000)) - gorGrimgut->AI()->AttackStart(player); - - return true; - } -}; - -enum SimonGame -{ - NPC_SIMON_BUNNY = 22923, - NPC_APEXIS_GUARDIAN = 22275, - - GO_APEXIS_RELIC = 185890, - GO_APEXIS_MONUMENT = 185944, - GO_AURA_BLUE = 185872, - GO_AURA_GREEN = 185873, - GO_AURA_RED = 185874, - GO_AURA_YELLOW = 185875, - - GO_BLUE_CLUSTER_DISPLAY = 7369, - GO_GREEN_CLUSTER_DISPLAY = 7371, - GO_RED_CLUSTER_DISPLAY = 7373, - GO_YELLOW_CLUSTER_DISPLAY = 7375, - GO_BLUE_CLUSTER_DISPLAY_LARGE = 7364, - GO_GREEN_CLUSTER_DISPLAY_LARGE = 7365, - GO_RED_CLUSTER_DISPLAY_LARGE = 7366, - GO_YELLOW_CLUSTER_DISPLAY_LARGE = 7367, - - SPELL_PRE_GAME_BLUE = 40176, - SPELL_PRE_GAME_GREEN = 40177, - SPELL_PRE_GAME_RED = 40178, - SPELL_PRE_GAME_YELLOW = 40179, - SPELL_VISUAL_BLUE = 40244, - SPELL_VISUAL_GREEN = 40245, - SPELL_VISUAL_RED = 40246, - SPELL_VISUAL_YELLOW = 40247, - - SOUND_BLUE = 11588, - SOUND_GREEN = 11589, - SOUND_RED = 11590, - SOUND_YELLOW = 11591, - SOUND_DISABLE_NODE = 11758, - - SPELL_AUDIBLE_GAME_TICK = 40391, - SPELL_VISUAL_START_PLAYER_LEVEL = 40436, - SPELL_VISUAL_START_AI_LEVEL = 40387, - - SPELL_BAD_PRESS_TRIGGER = 41241, - SPELL_BAD_PRESS_DAMAGE = 40065, - SPELL_REWARD_BUFF_1 = 40310, - SPELL_REWARD_BUFF_2 = 40311, - SPELL_REWARD_BUFF_3 = 40312, -}; - -enum SimonEvents -{ - EVENT_SIMON_SETUP_PRE_GAME = 1, - EVENT_SIMON_PLAY_SEQUENCE = 2, - EVENT_SIMON_RESET_CLUSTERS = 3, - EVENT_SIMON_PERIODIC_PLAYER_CHECK = 4, - EVENT_SIMON_TOO_LONG_TIME = 5, - EVENT_SIMON_GAME_TICK = 6, - EVENT_SIMON_ROUND_FINISHED = 7, - - ACTION_SIMON_CORRECT_FULL_SEQUENCE = 8, - ACTION_SIMON_WRONG_SEQUENCE = 9, - ACTION_SIMON_ROUND_FINISHED = 10, -}; - -enum SimonColors -{ - SIMON_BLUE = 0, - SIMON_RED = 1, - SIMON_GREEN = 2, - SIMON_YELLOW = 3, - SIMON_MAX_COLORS = 4, -}; - -class npc_simon_bunny : public CreatureScript -{ - public: - npc_simon_bunny() : CreatureScript("npc_simon_bunny") { } - - struct npc_simon_bunnyAI : public ScriptedAI - { - npc_simon_bunnyAI(Creature* creature) : ScriptedAI(creature) { } - - bool large; - bool listening; - uint8 gameLevel; - uint8 fails; - uint8 gameTicks; - uint64 playerGUID; - uint32 clusterIds[SIMON_MAX_COLORS]; - float zCoordCorrection; - float searchDistance; - EventMap _events; - std::list colorSequence, playableSequence, playerSequence; - - void UpdateAI(const uint32 diff) - { - _events.Update(diff); - - switch (_events.ExecuteEvent()) - { - case EVENT_SIMON_PERIODIC_PLAYER_CHECK: - if (!CheckPlayer()) - ResetNode(); - else - _events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000); - break; - case EVENT_SIMON_SETUP_PRE_GAME: - SetUpPreGame(); - _events.CancelEvent(EVENT_SIMON_GAME_TICK); - _events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1000); - break; - case EVENT_SIMON_PLAY_SEQUENCE: - if (!playableSequence.empty()) - { - PlayNextColor(); - _events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1500); - } - else - { - listening = true; - DoCast(SPELL_VISUAL_START_PLAYER_LEVEL); - playerSequence.clear(); - PrepareClusters(); - gameTicks = 0; - _events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000); - } - break; - case EVENT_SIMON_GAME_TICK: - DoCast(SPELL_AUDIBLE_GAME_TICK); - - if (gameTicks > gameLevel) - _events.ScheduleEvent(EVENT_SIMON_TOO_LONG_TIME, 500); - else - _events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000); - gameTicks++; - break; - case EVENT_SIMON_RESET_CLUSTERS: - PrepareClusters(true); - break; - case EVENT_SIMON_TOO_LONG_TIME: - DoAction(ACTION_SIMON_WRONG_SEQUENCE); - break; - case EVENT_SIMON_ROUND_FINISHED: - DoAction(ACTION_SIMON_ROUND_FINISHED); - break; - } - } - - void DoAction(const int32 action) - { - switch (action) - { - case ACTION_SIMON_ROUND_FINISHED: - listening = false; - DoCast(SPELL_VISUAL_START_AI_LEVEL); - GiveRewardForLevel(gameLevel); - _events.CancelEventGroup(0); - if (gameLevel == 10) - ResetNode(); - else - _events.ScheduleEvent(EVENT_SIMON_SETUP_PRE_GAME, 1000); - break; - case ACTION_SIMON_CORRECT_FULL_SEQUENCE: - gameLevel++; - DoAction(ACTION_SIMON_ROUND_FINISHED); - break; - case ACTION_SIMON_WRONG_SEQUENCE: - GivePunishment(); - DoAction(ACTION_SIMON_ROUND_FINISHED); - break; - } - } - - // Called by color clusters script (go_simon_cluster) and used for knowing the button pressed by player - void SetData(uint32 type, uint32 /*data*/) - { - if (!listening) - return; - - uint8 pressedColor = SIMON_MAX_COLORS; - - if (type == clusterIds[SIMON_RED]) - pressedColor = SIMON_RED; - else if (type == clusterIds[SIMON_BLUE]) - pressedColor = SIMON_BLUE; - else if (type == clusterIds[SIMON_GREEN]) - pressedColor = SIMON_GREEN; - else if (type == clusterIds[SIMON_YELLOW]) - pressedColor = SIMON_YELLOW; - - PlayColor(pressedColor); - playerSequence.push_back(pressedColor); - _events.ScheduleEvent(EVENT_SIMON_RESET_CLUSTERS, 500); - CheckPlayerSequence(); - } - - // Used for getting involved player guid. Parameter id is used for defining if is a large(Monument) or small(Relic) node - void SetGUID(uint64 guid, int32 id) - { - me->SetCanFly(true); - - large = (bool)id; - playerGUID = guid; - StartGame(); - } - - /* - Resets all variables and also find the ids of the four closests color clusters, since every simon - node have diferent ids for clusters this is absolutely NECESSARY. - */ - void StartGame() - { - listening = false; - gameLevel = 0; - fails = 0; - gameTicks = 0; - zCoordCorrection = large ? 8.0f : 2.75f; - searchDistance = large ? 13.0f : 5.0f; - colorSequence.clear(); - playableSequence.clear(); - playerSequence.clear(); - me->SetObjectScale(large ? 2.0f : 1.0f); - - std::list ClusterList; - Trinity::AllWorldObjectsInRange objects(me, searchDistance); - Trinity::WorldObjectListSearcher searcher(me, ClusterList, objects); - me->VisitNearbyObject(searchDistance, searcher); - - for (std::list::const_iterator i = ClusterList.begin(); i != ClusterList.end(); ++i) - { - if (GameObject* go = (*i)->ToGameObject()) - { - // We are checking for displayid because all simon nodes have 4 clusters with different entries - if (large) - { - switch (go->GetGOInfo()->displayId) - { - case GO_BLUE_CLUSTER_DISPLAY_LARGE: - clusterIds[SIMON_BLUE] = go->GetEntry(); - break; - - case GO_RED_CLUSTER_DISPLAY_LARGE: - clusterIds[SIMON_RED] = go->GetEntry(); - break; - - case GO_GREEN_CLUSTER_DISPLAY_LARGE: - clusterIds[SIMON_GREEN] = go->GetEntry(); - break; - - case GO_YELLOW_CLUSTER_DISPLAY_LARGE: - clusterIds[SIMON_YELLOW] = go->GetEntry(); - break; - } - } - else - { - switch (go->GetGOInfo()->displayId) - { - case GO_BLUE_CLUSTER_DISPLAY: - clusterIds[SIMON_BLUE] = go->GetEntry(); - break; - - case GO_RED_CLUSTER_DISPLAY: - clusterIds[SIMON_RED] = go->GetEntry(); - break; - - case GO_GREEN_CLUSTER_DISPLAY: - clusterIds[SIMON_GREEN] = go->GetEntry(); - break; - - case GO_YELLOW_CLUSTER_DISPLAY: - clusterIds[SIMON_YELLOW] = go->GetEntry(); - break; - } - } - } - } - - _events.Reset(); - _events.ScheduleEvent(EVENT_SIMON_ROUND_FINISHED, 1000); - _events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000); - - if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) - relic->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - } - - // Called when despawning the bunny. Sets all the node GOs to their default states. - void ResetNode() - { - DoPlaySoundToSet(me, SOUND_DISABLE_NODE); - - for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++) - if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance)) - cluster->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++) - if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance)) - auraGo->RemoveFromWorld(); - - if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) - relic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - me->DespawnOrUnsummon(1000); - } - - /* - Called on every button click of player. Adds the clicked color to the player created sequence and - checks if it corresponds to the AI created sequence. If so, incremente gameLevel and start a new - round, if not, give punishment and restart current level. - */ - void CheckPlayerSequence() - { - bool correct = true; - if (playerSequence.size() <= colorSequence.size()) - for (std::list::const_iterator i = playerSequence.begin(), j = colorSequence.begin(); i != playerSequence.end(); ++i, ++j) - if ((*i) != (*j)) - correct = false; - - if (correct && (playerSequence.size() == colorSequence.size())) - DoAction(ACTION_SIMON_CORRECT_FULL_SEQUENCE); - else if (!correct) - DoAction(ACTION_SIMON_WRONG_SEQUENCE); - } - - /* - Generates a random sequence of colors depending on the gameLevel. We also copy this sequence to - the playableSequence wich will be used when playing the sequence to the player. - */ - void GenerateColorSequence() - { - colorSequence.clear(); - for (uint8 i = 0; i <= gameLevel; i++) - colorSequence.push_back(RAND(SIMON_BLUE, SIMON_RED, SIMON_GREEN, SIMON_YELLOW)); - - for (std::list::const_iterator i = colorSequence.begin(); i != colorSequence.end(); ++i) - playableSequence.push_back(*i); - } - - - // Remove any existant glowing auras over clusters and set clusters ready for interating with them. - void PrepareClusters(bool clustersOnly = false) - { - for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++) - if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance)) - cluster->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - if (clustersOnly) - return; - - for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++) - if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance)) - auraGo->RemoveFromWorld(); - } - - /* - Called when AI is playing the sequence for player. We cast the visual spell and then remove the - casted color from the casting sequence. - */ - void PlayNextColor() - { - PlayColor(*playableSequence.begin()); - playableSequence.erase(playableSequence.begin()); - } - - // Casts a spell and plays a sound depending on parameter color. - void PlayColor(uint8 color) - { - switch (color) - { - case SIMON_BLUE: - DoCast(SPELL_VISUAL_BLUE); - DoPlaySoundToSet(me, SOUND_BLUE); - break; - case SIMON_GREEN: - DoCast(SPELL_VISUAL_GREEN); - DoPlaySoundToSet(me, SOUND_GREEN); - break; - case SIMON_RED: - DoCast(SPELL_VISUAL_RED); - DoPlaySoundToSet(me, SOUND_RED); - break; - case SIMON_YELLOW: - DoCast(SPELL_VISUAL_YELLOW); - DoPlaySoundToSet(me, SOUND_YELLOW); - break; - } - } - - /* - Creates the transparent glowing auras on every cluster of this node. - After calling this function bunny is teleported to the center of the node. - */ - void SetUpPreGame() - { - for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++) - { - if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], 2.0f*searchDistance)) - { - cluster->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - // break since we don't need glowing auras for large clusters - if (large) - break; - - float x, y, z, o; - cluster->GetPosition(x, y, z, o); - me->NearTeleportTo(x, y, z, o); - - uint32 preGameSpellId; - if (cluster->GetEntry() == clusterIds[SIMON_RED]) - preGameSpellId = SPELL_PRE_GAME_RED; - else if (cluster->GetEntry() == clusterIds[SIMON_BLUE]) - preGameSpellId = SPELL_PRE_GAME_BLUE; - else if (cluster->GetEntry() == clusterIds[SIMON_GREEN]) - preGameSpellId = SPELL_PRE_GAME_GREEN; - else if (cluster->GetEntry() == clusterIds[SIMON_YELLOW]) - preGameSpellId = SPELL_PRE_GAME_YELLOW; - else break; - - me->CastSpell(cluster, preGameSpellId, true); - } - } - - if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) - { - float x, y, z, o; - relic->GetPosition(x, y, z, o); - me->NearTeleportTo(x, y, z + zCoordCorrection, o); - } - - GenerateColorSequence(); - } - - // Handles the spell rewards. The spells also have the QuestCompleteEffect, so quests credits are working. - void GiveRewardForLevel(uint8 level) - { - uint32 rewSpell = 0; - switch (level) - { - case 6: - if (large) - GivePunishment(); - else - rewSpell = SPELL_REWARD_BUFF_1; - break; - case 8: - rewSpell = SPELL_REWARD_BUFF_2; - break; - case 10: - rewSpell = SPELL_REWARD_BUFF_3; - break; - } - - if (rewSpell) - if (Player* player = me->GetPlayer(*me, playerGUID)) - DoCast(player, rewSpell, true); - } - - /* - Depending on the number of failed pushes for player the damage of the spell scales, so we first - cast the spell on the target that hits for 50 and shows the visual and then forces the player - to cast the damaging spell on it self with the modified basepoints. - 4 fails = death. - On large nodes punishment and reward are the same, summoning the Apexis Guardian. - */ - void GivePunishment() - { - if (large) - { - if (Player* player = me->GetPlayer(*me, playerGUID)) - if (Creature* guardian = me->SummonCreature(NPC_APEXIS_GUARDIAN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() - zCoordCorrection, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000)) - guardian->AI()->AttackStart(player); - - ResetNode(); - } - else - { - fails++; - - if (Player* player = me->GetPlayer(*me, playerGUID)) - DoCast(player, SPELL_BAD_PRESS_TRIGGER, true); - - if (fails >= 4) - ResetNode(); - } - } - - void SpellHitTarget(Unit* target, const SpellInfo* spell) - { - // Cast SPELL_BAD_PRESS_DAMAGE with scaled basepoints when the visual hits the target. - // Need Fix: When SPELL_BAD_PRESS_TRIGGER hits target it triggers spell SPELL_BAD_PRESS_DAMAGE by itself - // so player gets damage equal to calculated damage dbc basepoints for SPELL_BAD_PRESS_DAMAGE (~50) - if (spell->Id == SPELL_BAD_PRESS_TRIGGER) - { - int32 bp = (int32)((float)(fails)*0.33f*target->GetMaxHealth()); - target->CastCustomSpell(target, SPELL_BAD_PRESS_DAMAGE, &bp, NULL, NULL, true); - } - } - - // Checks if player has already die or has get too far from the current node - bool CheckPlayer() - { - if (Player* player = me->GetPlayer(*me, playerGUID)) - { - if (player->isDead()) - return false; - if (player->GetDistance2d(me) >= 2.0f*searchDistance) - { - GivePunishment(); - return false; - } - } - else - return false; - - return true; - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_simon_bunnyAI(creature); - } -}; - -class go_simon_cluster : public GameObjectScript -{ - public: - go_simon_cluster() : GameObjectScript("go_simon_cluster") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (Creature* bunny = go->FindNearestCreature(NPC_SIMON_BUNNY, 12.0f, true)) - bunny->AI()->SetData(go->GetEntry(), 0); - - player->CastSpell(player, go->GetGOInfo()->goober.spellId, true); - go->AddUse(); - return true; - } -}; - -enum ApexisRelic -{ - QUEST_CRYSTALS = 11025, - GOSSIP_TEXT_ID = 10948, - - ITEM_APEXIS_SHARD = 32569, - SPELL_TAKE_REAGENTS_SOLO = 41145, - SPELL_TAKE_REAGENTS_GROUP = 41146, -}; - -class go_apexis_relic : public GameObjectScript -{ - public: - go_apexis_relic() : GameObjectScript("go_apexis_relic") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - player->PrepareGossipMenu(go, go->GetGOInfo()->questgiver.gossipID); - player->SendPreparedGossip(go); - return true; - } - - bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) - { - player->CLOSE_GOSSIP_MENU(); - - bool large = (go->GetEntry() == GO_APEXIS_MONUMENT); - if (player->HasItemCount(ITEM_APEXIS_SHARD, large ? 35 : 1)) - { - player->CastSpell(player, large ? SPELL_TAKE_REAGENTS_GROUP : SPELL_TAKE_REAGENTS_SOLO, false); - - if (Creature* bunny = player->SummonCreature(NPC_SIMON_BUNNY, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ())) - bunny->AI()->SetGUID(player->GetGUID(), large); - } - - return true; - } -}; - -void AddSC_blades_edge_mountains() -{ - new mobs_bladespire_ogre(); - new mobs_nether_drake(); - new npc_daranelle(); - new npc_overseer_nuaar(); - new npc_saikkal_the_elder(); - new go_legion_obelisk(); - new npc_bloodmaul_brutebane(); - new npc_ogre_brute(); - new go_thunderspike(); - new npc_simon_bunny(); - new go_simon_cluster(); - new go_apexis_relic(); -} diff --git a/src/server/scripts/Outland/hellfire_peninsula.cpp b/src/server/scripts/Outland/hellfire_peninsula.cpp deleted file mode 100644 index 64b484268df..00000000000 --- a/src/server/scripts/Outland/hellfire_peninsula.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Hellfire_Peninsula -SD%Complete: 100 -SDComment: Quest support: 9375, 9410, 9418, 10129, 10146, 10162, 10163, 10340, 10346, 10347, 10382 (Special flight paths) -SDCategory: Hellfire Peninsula -EndScriptData */ - -/* ContentData -npc_aeranas -npc_ancestral_wolf -go_haaleshi_altar -npc_naladu -npc_tracy_proudwell -npc_trollbane -npc_wounded_blood_elf -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_aeranas -######*/ - -enum eAeranas -{ - SAY_SUMMON = 0, - SAY_FREE = 1, - - FACTION_HOSTILE = 16, - FACTION_FRIENDLY = 35, - - SPELL_ENVELOPING_WINDS = 15535, - SPELL_SHOCK = 12553 -}; - -class npc_aeranas : public CreatureScript -{ -public: - npc_aeranas() : CreatureScript("npc_aeranas") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_aeranasAI (creature); - } - - struct npc_aeranasAI : public ScriptedAI - { - npc_aeranasAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 Faction_Timer; - uint32 EnvelopingWinds_Timer; - uint32 Shock_Timer; - - void Reset() - { - Faction_Timer = 8000; - EnvelopingWinds_Timer = 9000; - Shock_Timer = 5000; - - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - me->setFaction(FACTION_FRIENDLY); - - Talk(SAY_SUMMON); - } - - void UpdateAI(const uint32 diff) - { - if (Faction_Timer) - { - if (Faction_Timer <= diff) - { - me->setFaction(FACTION_HOSTILE); - Faction_Timer = 0; - } else Faction_Timer -= diff; - } - - if (!UpdateVictim()) - return; - - if (HealthBelowPct(30)) - { - me->setFaction(FACTION_FRIENDLY); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(true); - Talk(SAY_FREE); - return; - } - - if (Shock_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SHOCK); - Shock_Timer = 10000; - } else Shock_Timer -= diff; - - if (EnvelopingWinds_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_ENVELOPING_WINDS); - EnvelopingWinds_Timer = 25000; - } else EnvelopingWinds_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_ancestral_wolf -######*/ - -enum eAncestralWolf -{ - EMOTE_WOLF_LIFT_HEAD = 0, - EMOTE_WOLF_HOWL = 1, - SAY_WOLF_WELCOME = 2, - - SPELL_ANCESTRAL_WOLF_BUFF = 29981, - - NPC_RYGA = 17123 -}; - -class npc_ancestral_wolf : public CreatureScript -{ -public: - npc_ancestral_wolf() : CreatureScript("npc_ancestral_wolf") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_ancestral_wolfAI(creature); - } - - struct npc_ancestral_wolfAI : public npc_escortAI - { - npc_ancestral_wolfAI(Creature* creature) : npc_escortAI(creature) - { - if (creature->GetOwner() && creature->GetOwner()->GetTypeId() == TYPEID_PLAYER) - Start(false, false, creature->GetOwner()->GetGUID()); - else - sLog->outError(LOG_FILTER_TSCR, "TRINITY: npc_ancestral_wolf can not obtain owner or owner is not a player."); - - creature->SetSpeed(MOVE_WALK, 1.5f); - Reset(); - } - - Creature* pRyga; - - void Reset() - { - pRyga = NULL; - DoCast(me, SPELL_ANCESTRAL_WOLF_BUFF, true); - } - - void MoveInLineOfSight(Unit* who) - { - if (!pRyga && who->GetEntry() == NPC_RYGA && me->IsWithinDistInMap(who, 15.0f)) - if (Creature* temp = who->ToCreature()) - pRyga = temp; - - npc_escortAI::MoveInLineOfSight(who); - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 0: - Talk(EMOTE_WOLF_LIFT_HEAD); - break; - case 2: - Talk(EMOTE_WOLF_HOWL); - break; - case 50: - if (pRyga && pRyga->isAlive() && !pRyga->isInCombat()) - pRyga->AI()->Talk(SAY_WOLF_WELCOME); - break; - } - } - }; -}; - -/*###### -## npc_naladu -######*/ - -#define GOSSIP_NALADU_ITEM1 "Why don't you escape?" - -enum eNaladu -{ - GOSSIP_TEXTID_NALADU1 = 9788 -}; - -class npc_naladu : public CreatureScript -{ -public: - npc_naladu() : CreatureScript("npc_naladu") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_NALADU1, creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_NALADU_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_tracy_proudwell -######*/ - -#define GOSSIP_TEXT_REDEEM_MARKS "I have marks to redeem!" -#define GOSSIP_TRACY_PROUDWELL_ITEM1 "I heard that your dog Fei Fei took Klatu's prayer beads..." -#define GOSSIP_TRACY_PROUDWELL_ITEM2 "" - -enum eTracy -{ - GOSSIP_TEXTID_TRACY_PROUDWELL1 = 10689, - QUEST_DIGGING_FOR_PRAYER_BEADS = 10916 -}; - -class npc_tracy_proudwell : public CreatureScript -{ -public: - npc_tracy_proudwell() : CreatureScript("npc_tracy_proudwell") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TRACY_PROUDWELL_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TRACY_PROUDWELL1, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(creature->GetGUID()); - break; - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_REDEEM_MARKS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - if (player->GetQuestStatus(QUEST_DIGGING_FOR_PRAYER_BEADS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TRACY_PROUDWELL_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_trollbane -######*/ - -#define GOSSIP_TROLLBANE_ITEM1 "Tell me of the Sons of Lothar." -#define GOSSIP_TROLLBANE_ITEM2 "" -#define GOSSIP_TROLLBANE_ITEM3 "Tell me of your homeland." - -enum eTrollbane -{ - GOSSIP_TEXTID_TROLLBANE1 = 9932, - GOSSIP_TEXTID_TROLLBANE2 = 9933, - GOSSIP_TEXTID_TROLLBANE3 = 8772 -}; - -class npc_trollbane : public CreatureScript -{ -public: - npc_trollbane() : CreatureScript("npc_trollbane") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TROLLBANE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TROLLBANE1, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TROLLBANE2, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TROLLBANE3, creature->GetGUID()); - break; - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TROLLBANE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TROLLBANE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_wounded_blood_elf -######*/ - -enum eWoundedBloodElf -{ - SAY_ELF_START = 0, - SAY_ELF_SUMMON1 = 1, - SAY_ELF_RESTING = 2, - SAY_ELF_SUMMON2 = 3, - SAY_ELF_COMPLETE = 4, - SAY_ELF_AGGRO = 5, - - QUEST_ROAD_TO_FALCON_WATCH = 9375 -}; - -class npc_wounded_blood_elf : public CreatureScript -{ -public: - npc_wounded_blood_elf() : CreatureScript("npc_wounded_blood_elf") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ROAD_TO_FALCON_WATCH) - { - if (npc_escortAI* pEscortAI = CAST_AI(npc_wounded_blood_elf::npc_wounded_blood_elfAI, creature->AI())) - pEscortAI->Start(true, false, player->GetGUID()); - - // Change faction so mobs attack - creature->setFaction(775); - } - - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_wounded_blood_elfAI(creature); - } - - struct npc_wounded_blood_elfAI : public npc_escortAI - { - npc_wounded_blood_elfAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 0: - Talk(SAY_ELF_START, player->GetGUID()); - break; - case 9: - Talk(SAY_ELF_SUMMON1, player->GetGUID()); - // Spawn two Haal'eshi Talonguard - DoSpawnCreature(16967, -15, -15, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - DoSpawnCreature(16967, -17, -17, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - break; - case 13: - Talk(SAY_ELF_RESTING, player->GetGUID()); - break; - case 14: - Talk(SAY_ELF_SUMMON2, player->GetGUID()); - // Spawn two Haal'eshi Windwalker - DoSpawnCreature(16966, -15, -15, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - DoSpawnCreature(16966, -17, -17, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); - break; - case 27: - Talk(SAY_ELF_COMPLETE, player->GetGUID()); - // Award quest credit - player->GroupEventHappens(QUEST_ROAD_TO_FALCON_WATCH, me); - break; - } - } - - void Reset() { } - - void EnterCombat(Unit* /*who*/) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - Talk(SAY_ELF_AGGRO); - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - }; -}; - -/*###### -## npc_fel_guard_hound -######*/ - -enum eFelGuard -{ - SPELL_SUMMON_POO = 37688, - - NPC_DERANGED_HELBOAR = 16863 -}; - -class npc_fel_guard_hound : public CreatureScript -{ -public: - npc_fel_guard_hound() : CreatureScript("npc_fel_guard_hound") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_fel_guard_houndAI(creature); - } - - struct npc_fel_guard_houndAI : public ScriptedAI - { - npc_fel_guard_houndAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 uiCheckTimer; - uint64 uiHelboarGUID; - - void Reset() - { - uiCheckTimer = 5000; //check for creature every 5 sec - uiHelboarGUID = 0; - } - - void MovementInform(uint32 uiType, uint32 uiId) - { - if (uiType != POINT_MOTION_TYPE || uiId != 1) - return; - - if (Creature* pHelboar = me->GetCreature(*me, uiHelboarGUID)) - { - pHelboar->RemoveCorpse(); - DoCast(SPELL_SUMMON_POO); - - if (Player* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself()) - me->GetMotionMaster()->MoveFollow(owner, 0.0f, 0.0f); - } - } - - void UpdateAI(const uint32 uiDiff) - { - if (uiCheckTimer <= uiDiff) - { - if (Creature* pHelboar = me->FindNearestCreature(NPC_DERANGED_HELBOAR, 10.0f, false)) - { - if (pHelboar->GetGUID() != uiHelboarGUID && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && !me->FindCurrentSpellBySpellId(SPELL_SUMMON_POO)) - { - uiHelboarGUID = pHelboar->GetGUID(); - me->GetMotionMaster()->MovePoint(1, pHelboar->GetPositionX(), pHelboar->GetPositionY(), pHelboar->GetPositionZ()); - } - } - uiCheckTimer = 5000; - }else uiCheckTimer -= uiDiff; - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; - -void AddSC_hellfire_peninsula() -{ - new npc_aeranas(); - new npc_ancestral_wolf(); - new npc_naladu(); - new npc_tracy_proudwell(); - new npc_trollbane(); - new npc_wounded_blood_elf(); - new npc_fel_guard_hound(); -} diff --git a/src/server/scripts/Outland/nagrand.cpp b/src/server/scripts/Outland/nagrand.cpp deleted file mode 100644 index 0a92b985c95..00000000000 --- a/src/server/scripts/Outland/nagrand.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Nagrand -SD%Complete: 90 -SDComment: Quest support: 9868, 9874, 10044, 10172, 10085. TextId's unknown for altruis_the_sufferer and greatmother_geyah (npc_text) -SDCategory: Nagrand -EndScriptData */ - -/* ContentData -npc_greatmother_geyah -npc_maghar_captive -npc_creditmarker_visit_with_ancestors -EndContentData */ -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "SpellInfo.h" - -/*###### -## npc_greatmother_geyah -######*/ - -#define GOSSIP_HGG1 "Hello, Greatmother. Garrosh told me that you wanted to speak with me." -#define GOSSIP_HGG2 "Garrosh is beyond redemption, Greatmother. I fear that in helping the Mag'har, I have convinced Garrosh that he is unfit to lead." - -#define GOSSIP_SGG1 "You raised all of the orcs here, Greatmother?" -#define GOSSIP_SGG2 "Do you believe that?" -#define GOSSIP_SGG3 "What can be done? I have tried many different things. I have done my best to help the people of Nagrand. Each time I have approached Garrosh, he has dismissed me." -#define GOSSIP_SGG4 "Left? How can you choose to leave?" -#define GOSSIP_SGG5 "What is this duty?" -#define GOSSIP_SGG6 "Is there anything I can do for you, Greatmother?" -#define GOSSIP_SGG7 "I have done all that I could, Greatmother. I thank you for your kind words." -#define GOSSIP_SGG8 "Greatmother, you are the mother of Durotan?" -#define GOSSIP_SGG9 "Greatmother, I never had the honor. Durotan died long before my time, but his heroics are known to all on my world. The orcs of Azeroth reside in a place known as Durotar, named after your son. And ... (You take a moment to breathe and think through what you are about to tell the Greatmother.)" -#define GOSSIP_SGG10 "It is my Warchief, Greatmother. The leader of my people. From my world. He ... He is the son of Durotan. He is your grandchild." -#define GOSSIP_SGG11 "I will return to Azeroth at once, Greatmother." - -//all the textId's for the below is unknown, but i do believe the gossip item texts are proper. -class npc_greatmother_geyah : public CreatureScript -{ -public: - npc_greatmother_geyah() : CreatureScript("npc_greatmother_geyah") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 7: - player->AreaExploredOrEventHappens(10044); - player->CLOSE_GOSSIP_MENU(); - break; - case GOSSIP_ACTION_INFO_DEF + 10: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 11: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 12: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 13: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 14: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 15: - player->AreaExploredOrEventHappens(10172); - player->CLOSE_GOSSIP_MENU(); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(10044) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HGG1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - } - else if (player->GetQuestStatus(10172) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HGG2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*##### -## npc_maghar_captive -#####*/ - -enum eMagharCaptive -{ - SAY_MAG_START = 0, - SAY_MAG_NO_ESCAPE = 0, - SAY_MAG_MORE = 1, - SAY_MAG_MORE_REPLY = 0, - SAY_MAG_LIGHTNING = 2, - SAY_MAG_SHOCK = 3, - SAY_MAG_COMPLETE = 4, - - SPELL_CHAIN_LIGHTNING = 16006, - SPELL_EARTHBIND_TOTEM = 15786, - SPELL_FROST_SHOCK = 12548, - SPELL_HEALING_WAVE = 12491, - - QUEST_TOTEM_KARDASH_H = 9868, - - NPC_MURK_RAIDER = 18203, - NPC_MURK_BRUTE = 18211, - NPC_MURK_SCAVENGER = 18207, - NPC_MURK_PUTRIFIER = 18202 -}; - -static float m_afAmbushA[]= {-1568.805786f, 8533.873047f, 1.958f}; -static float m_afAmbushB[]= {-1491.554321f, 8506.483398f, 1.248f}; - -class npc_maghar_captive : public CreatureScript -{ -public: - npc_maghar_captive() : CreatureScript("npc_maghar_captive") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_H) - { - if (npc_maghar_captiveAI* pEscortAI = dynamic_cast(creature->AI())) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->setFaction(232); - - pEscortAI->Start(true, false, player->GetGUID(), quest); - - creature->AI()->Talk(SAY_MAG_START); - - creature->SummonCreature(NPC_MURK_RAIDER, m_afAmbushA[0]+2.5f, m_afAmbushA[1]-2.5f, m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - creature->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushA[0]-2.5f, m_afAmbushA[1]+2.5f, m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - creature->SummonCreature(NPC_MURK_BRUTE, m_afAmbushA[0], m_afAmbushA[1], m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - } - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_maghar_captiveAI(creature); - } - - struct npc_maghar_captiveAI : public npc_escortAI - { - npc_maghar_captiveAI(Creature* creature) : npc_escortAI(creature) { Reset(); } - - uint32 m_uiChainLightningTimer; - uint32 m_uiHealTimer; - uint32 m_uiFrostShockTimer; - - void Reset() - { - m_uiChainLightningTimer = 1000; - m_uiHealTimer = 0; - m_uiFrostShockTimer = 6000; - } - - void EnterCombat(Unit* /*who*/) - { - DoCast(me, SPELL_EARTHBIND_TOTEM, false); - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 7: - Talk(SAY_MAG_MORE); - - if (Creature* temp = me->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushB[0], m_afAmbushB[1], m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000)) - temp->AI()->Talk(SAY_MAG_MORE_REPLY); - - me->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushB[0]-2.5f, m_afAmbushB[1]-2.5f, m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_MURK_SCAVENGER, m_afAmbushB[0]+2.5f, m_afAmbushB[1]+2.5f, m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_MURK_SCAVENGER, m_afAmbushB[0]+2.5f, m_afAmbushB[1]-2.5f, m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 16: - Talk(SAY_MAG_COMPLETE); - - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_TOTEM_KARDASH_H, me); - - SetRun(); - break; - } - } - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == NPC_MURK_BRUTE) - summoned->AI()->Talk(SAY_MAG_NO_ESCAPE); - - if (summoned->isTotem()) - return; - - summoned->SetWalk(false); - summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - summoned->AI()->AttackStart(me); - - } - - void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell) - { - if (pSpell->Id == SPELL_CHAIN_LIGHTNING) - { - if (rand()%10) - return; - - Talk(SAY_MAG_LIGHTNING); - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - if (!me->getVictim()) - return; - - if (m_uiChainLightningTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_CHAIN_LIGHTNING); - m_uiChainLightningTimer = urand(7000, 14000); - } - else - m_uiChainLightningTimer -= uiDiff; - - if (HealthBelowPct(30)) - { - if (m_uiHealTimer <= uiDiff) - { - DoCast(me, SPELL_HEALING_WAVE); - m_uiHealTimer = 5000; - } - else - m_uiHealTimer -= uiDiff; - } - - if (m_uiFrostShockTimer <= uiDiff) - { - DoCast(me->getVictim(), SPELL_FROST_SHOCK); - m_uiFrostShockTimer = urand(7500, 15000); - } - else - m_uiFrostShockTimer -= uiDiff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_creditmarker_visist_with_ancestors -######*/ - -class npc_creditmarker_visit_with_ancestors : public CreatureScript -{ -public: - npc_creditmarker_visit_with_ancestors() : CreatureScript("npc_creditmarker_visit_with_ancestors") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_creditmarker_visit_with_ancestorsAI (creature); - } - - struct npc_creditmarker_visit_with_ancestorsAI : public ScriptedAI - { - npc_creditmarker_visit_with_ancestorsAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* who) - { - if (!who) - return; - - if (who->GetTypeId() == TYPEID_PLAYER) - { - if (CAST_PLR(who)->GetQuestStatus(10085) == QUEST_STATUS_INCOMPLETE) - { - uint32 creditMarkerId = me->GetEntry(); - if ((creditMarkerId >= 18840) && (creditMarkerId <= 18843)) - { - // 18840: Sunspring, 18841: Laughing, 18842: Garadar, 18843: Bleeding - if (!CAST_PLR(who)->GetReqKillOrCastCurrentCount(10085, creditMarkerId)) - CAST_PLR(who)->KilledMonsterCredit(creditMarkerId, me->GetGUID()); - } - } - } - } - }; -}; - -/*###### -## go_corkis_prison and npc_corki -######*/ - -enum CorkiData -{ - // first quest - QUEST_HELP = 9923, - NPC_CORKI = 18445, - NPC_CORKI_CREDIT_1 = 18369, - GO_CORKIS_PRISON = 182349, - CORKI_SAY_THANKS = 0, - // 2nd quest - QUEST_CORKIS_GONE_MISSING_AGAIN = 9924, - NPC_CORKI_2 = 20812, - GO_CORKIS_PRISON_2 = 182350, - CORKI_SAY_PROMISE = 0, - // 3rd quest - QUEST_CHOWAR_THE_PILLAGER = 9955, - NPC_CORKI_3 = 18369, - NPC_CORKI_CREDIT_3 = 18444, - GO_CORKIS_PRISON_3 = 182521, - CORKI_SAY_LAST = 0 -}; - -class go_corkis_prison : public GameObjectScript -{ -public: - go_corkis_prison() : GameObjectScript("go_corkis_prison") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->SetGoState(GO_STATE_READY); - if (go->GetEntry() == GO_CORKIS_PRISON) - { - if (Creature* corki = go->FindNearestCreature(NPC_CORKI, 25, true)) - { - corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()+5, go->GetPositionY(), go->GetPositionZ()); - if (player) - player->KilledMonsterCredit(NPC_CORKI_CREDIT_1, 0); - } - } - - if (go->GetEntry() == GO_CORKIS_PRISON_2) - { - if (Creature* corki = go->FindNearestCreature(NPC_CORKI_2, 25, true)) - { - corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()-5, go->GetPositionY(), go->GetPositionZ()); - if (player) - player->KilledMonsterCredit(NPC_CORKI_2, 0); - } - } - - if (go->GetEntry() == GO_CORKIS_PRISON_3) - { - if (Creature* corki = go->FindNearestCreature(NPC_CORKI_3, 25, true)) - { - corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()+4, go->GetPositionY(), go->GetPositionZ()); - if (player) - player->KilledMonsterCredit(NPC_CORKI_CREDIT_3, 0); - } - } - return true; - } -}; - -class npc_corki : public CreatureScript -{ -public: - npc_corki() : CreatureScript("npc_corki") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_corkiAI(creature); - } - - struct npc_corkiAI : public ScriptedAI - { - npc_corkiAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 Say_Timer; - bool ReleasedFromCage; - - void Reset() - { - Say_Timer = 5000; - ReleasedFromCage = false; - } - - void UpdateAI(uint32 const diff) - { - if (ReleasedFromCage) - { - if (Say_Timer <= diff) - { - me->DespawnOrUnsummon(); - ReleasedFromCage = false; - } - else - Say_Timer -= diff; - } - } - - void MovementInform(uint32 type, uint32 id) - { - if (type == POINT_MOTION_TYPE && id == 1) - { - Say_Timer = 5000; - ReleasedFromCage = true; - if (me->GetEntry() == NPC_CORKI) - Talk(CORKI_SAY_THANKS); - if (me->GetEntry() == NPC_CORKI_2) - Talk(CORKI_SAY_PROMISE); - if (me->GetEntry() == NPC_CORKI_3) - Talk(CORKI_SAY_LAST); - } - }; - }; -}; - -/*##### -## npc_kurenai_captive -#####*/ - -enum KurenaiCaptive -{ - SAY_KUR_START = 0, - SAY_KUR_NO_ESCAPE = 1, - SAY_KUR_MORE = 2, - SAY_KUR_MORE_TWO = 3, - SAY_KUR_LIGHTNING = 4, - SAY_KUR_SHOCK = 5, - SAY_KUR_COMPLETE = 6, - - SPELL_KUR_CHAIN_LIGHTNING = 16006, - SPELL_KUR_EARTHBIND_TOTEM = 15786, - SPELL_KUR_FROST_SHOCK = 12548, - SPELL_KUR_HEALING_WAVE = 12491, - - QUEST_TOTEM_KARDASH_A = 9879, - - NPC_KUR_MURK_RAIDER = 18203, - NPC_KUR_MURK_BRUTE = 18211, - NPC_KUR_MURK_SCAVENGER = 18207, - NPC_KUR_MURK_PUTRIFIER = 18202, -}; - -static float kurenaiAmbushA[]= {-1568.805786f, 8533.873047f, 1.958f}; -static float kurenaiAmbushB[]= {-1491.554321f, 8506.483398f, 1.248f}; - -class npc_kurenai_captive : public CreatureScript -{ -public: - npc_kurenai_captive() : CreatureScript("npc_kurenai_captive") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_A) - { - if (npc_kurenai_captiveAI* EscortAI = dynamic_cast(creature->AI())) - { - creature->SetStandState(UNIT_STAND_STATE_STAND); - EscortAI->Start(true, false, player->GetGUID(), quest); - creature->AI()->Talk(SAY_KUR_START); - - creature->SummonCreature(NPC_KUR_MURK_RAIDER, kurenaiAmbushA[0]+2.5f, kurenaiAmbushA[1]-2.5f, kurenaiAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - creature->SummonCreature(NPC_KUR_MURK_BRUTE, kurenaiAmbushA[0]-2.5f, kurenaiAmbushA[1]+2.5f, kurenaiAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - creature->SummonCreature(NPC_KUR_MURK_SCAVENGER, kurenaiAmbushA[0], kurenaiAmbushA[1], kurenaiAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - } - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kurenai_captiveAI(creature); - } - - struct npc_kurenai_captiveAI : public npc_escortAI - { - npc_kurenai_captiveAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 ChainLightningTimer; - uint32 HealTimer; - uint32 FrostShockTimer; - - void Reset() - { - ChainLightningTimer = 1000; - HealTimer = 0; - FrostShockTimer = 6000; - } - - void EnterCombat(Unit* /*who*/) - { - DoCast(me, SPELL_KUR_EARTHBIND_TOTEM, false); - } - - void JustDied(Unit* /*killer*/) - { - if (!HasEscortState(STATE_ESCORT_ESCORTING)) - return; - - if (Player* player = GetPlayerForEscort()) - { - if (player->GetQuestStatus(QUEST_TOTEM_KARDASH_A) != QUEST_STATUS_COMPLETE) - player->FailQuest(QUEST_TOTEM_KARDASH_A); - } - } - - void WaypointReached(uint32 waypointId) - { - switch (waypointId) - { - case 3: - { - Talk(SAY_KUR_MORE); - - if (me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0], kurenaiAmbushB[1], kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000)) - Talk(SAY_KUR_MORE_TWO); - - me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0]-2.5f, kurenaiAmbushB[1]-2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_KUR_MURK_SCAVENGER, kurenaiAmbushB[0]+2.5f, kurenaiAmbushB[1]+2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_KUR_MURK_SCAVENGER, kurenaiAmbushB[0]+2.5f, kurenaiAmbushB[1]-2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - } - case 7: - { - Talk(SAY_KUR_COMPLETE); - - if (Player* player = GetPlayerForEscort()) - player->GroupEventHappens(QUEST_TOTEM_KARDASH_A, me); - - SetRun(); - break; - } - } - } - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == NPC_KUR_MURK_BRUTE) - Talk(SAY_KUR_NO_ESCAPE); - - // This function is for when we summoned enemies to fight - so that does NOT mean we should make our totem count in this! - if (summoned->isTotem()) - return; - - summoned->SetWalk(false); - summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - summoned->AI()->AttackStart(me); - } - - void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell) - { - if (spell->Id == SPELL_KUR_CHAIN_LIGHTNING) - { - if (rand()%30) - return; - - Talk(SAY_KUR_LIGHTNING); - } - - if (spell->Id == SPELL_KUR_FROST_SHOCK) - { - if (rand()%30) - return; - - Talk(SAY_KUR_SHOCK); - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - if (ChainLightningTimer <= diff) - { - DoCast(me->getVictim(), SPELL_KUR_CHAIN_LIGHTNING); - ChainLightningTimer = urand(7000,14000); - } else ChainLightningTimer -= diff; - - if (HealthBelowPct(30)) - { - if (HealTimer <= diff) - { - DoCast(me, SPELL_KUR_HEALING_WAVE); - HealTimer = 5000; - } else HealTimer -= diff; - } - - if (FrostShockTimer <= diff) - { - DoCast(me->getVictim(), SPELL_KUR_FROST_SHOCK); - FrostShockTimer = urand(7500,15000); - } else FrostShockTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## go_warmaul_prison -######*/ - -enum FindingTheSurvivorsData -{ - QUEST_FINDING_THE_SURVIVORS = 9948, - NPC_MAGHAR_PRISONER = 18428, - - SAY_FREE = 0, -}; - -class go_warmaul_prison : public GameObjectScript -{ - public: - go_warmaul_prison() : GameObjectScript("go_warmaul_prison") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - if (player->GetQuestStatus(QUEST_FINDING_THE_SURVIVORS) != QUEST_STATUS_INCOMPLETE) - return false; - - if (Creature* prisoner = go->FindNearestCreature(NPC_MAGHAR_PRISONER, 5.0f)) - { - player->KilledMonsterCredit(NPC_MAGHAR_PRISONER, 0); - - prisoner->AI()->Talk(SAY_FREE, player->GetGUID()); - prisoner->DespawnOrUnsummon(6000); - } - return true; - } -}; - -void AddSC_nagrand() -{ - new npc_greatmother_geyah(); - new npc_maghar_captive(); - new npc_creditmarker_visit_with_ancestors(); - new npc_corki(); - new go_corkis_prison(); - new npc_kurenai_captive(); - new go_warmaul_prison(); -} diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp deleted file mode 100644 index 769ee7dc68d..00000000000 --- a/src/server/scripts/Outland/netherstorm.cpp +++ /dev/null @@ -1,1077 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Netherstorm -SD%Complete: 80 -SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10299, 10321, 10322, 10323, 10329, 10330, 10338, 10365(Shutting Down Manaforge), 10198, 10191 -SDCategory: Netherstorm -EndScriptData */ - -/* ContentData -npc_manaforge_control_console -go_manaforge_control_console -npc_commander_dawnforge -npc_bessy -npc_maxx_a_million -go_captain_tyralius_prison -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" - -/*###### -## npc_manaforge_control_console -######*/ - -//used by 20209, 20417, 20418, 20440, signed for 20209 -enum eManaforgeConsoleData -{ - EMOTE_START = 0, - EMOTE_60 = 1, - EMOTE_30 = 2, - EMOTE_10 = 3, - EMOTE_COMPLETE = 4, - EMOTE_ABORT = 5, - - ENTRY_BNAAR_C_CONSOLE = 20209, - ENTRY_CORUU_C_CONSOLE = 20417, - ENTRY_DURO_C_CONSOLE = 20418, - ENTRY_ARA_C_CONSOLE = 20440, - - ENTRY_SUNFURY_TECH = 20218, - ENTRY_SUNFURY_PROT = 20436, - - ENTRY_ARA_TECH = 20438, - ENTRY_ARA_ENGI = 20439, - ENTRY_ARA_GORKLONN = 20460, - - SPELL_DISABLE_VISUAL = 35031, - SPELL_INTERRUPT_1 = 35016, //ACID mobs should cast this - SPELL_INTERRUPT_2 = 35176, //ACID mobs should cast this (Manaforge Ara-version) -}; - -class npc_manaforge_control_console : public CreatureScript -{ -public: - npc_manaforge_control_console() : CreatureScript("npc_manaforge_control_console") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_manaforge_control_consoleAI (creature); - } - - struct npc_manaforge_control_consoleAI : public ScriptedAI - { - npc_manaforge_control_consoleAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 Event_Timer; - uint32 Wave_Timer; - uint32 Phase; - bool Wave; - uint64 someplayer; - uint64 goConsole; - Creature* add; - - void Reset() - { - Event_Timer = 3000; - Wave_Timer = 0; - Phase = 1; - Wave = false; - someplayer = 0; - goConsole = 0; - add = NULL; - } - - void EnterCombat(Unit* /*who*/) {} - - /*void SpellHit(Unit* caster, const SpellInfo* spell) - { - //we have no way of telling the Creature was hit by spell -> got aura applied after 10-12 seconds - //then no way for the mobs to actually stop the shutdown as intended. - if (spell->Id == SPELL_INTERRUPT_1) - DoSay("Silence! I kill you!", LANG_UNIVERSAL, NULL); - }*/ - - void JustDied(Unit* /*killer*/) - { - Talk(EMOTE_ABORT); - - if (someplayer) - { - Unit* p = Unit::GetUnit(*me, someplayer); - if (p && p->GetTypeId() == TYPEID_PLAYER) - { - switch (me->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - CAST_PLR(p)->FailQuest(10299); - CAST_PLR(p)->FailQuest(10329); - break; - case ENTRY_CORUU_C_CONSOLE: - CAST_PLR(p)->FailQuest(10321); - CAST_PLR(p)->FailQuest(10330); - break; - case ENTRY_DURO_C_CONSOLE: - CAST_PLR(p)->FailQuest(10322); - CAST_PLR(p)->FailQuest(10338); - break; - case ENTRY_ARA_C_CONSOLE: - CAST_PLR(p)->FailQuest(10323); - CAST_PLR(p)->FailQuest(10365); - break; - } - } - } - - if (goConsole) - { - if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - } - - void DoWaveSpawnForCreature(Creature* creature) - { - switch (creature->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - if (rand()%2) - { - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2933.68f, 4162.55f, 164.00f, 1.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2927.36f, 4212.97f, 164.00f); - } - else - { - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2927.36f, 4212.97f, 164.00f, 4.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2933.68f, 4162.55f, 164.00f); - } - Wave_Timer = 30000; - break; - case ENTRY_CORUU_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2445.21f, 2765.26f, 134.49f, 3.93f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2424.21f, 2740.15f, 133.81f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2429.86f, 2731.85f, 134.53f, 1.31f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2435.37f, 2766.04f, 133.81f); - Wave_Timer = 20000; - break; - case ENTRY_DURO_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2986.80f, 2205.36f, 165.37f, 3.74f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2985.15f, 2197.32f, 164.79f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2952.91f, 2191.20f, 165.32f, 0.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2060.01f, 2185.27f, 164.67f); - Wave_Timer = 15000; - break; - case ENTRY_ARA_C_CONSOLE: - if (rand()%2) - { - add = me->SummonCreature(ENTRY_ARA_TECH, 4035.11f, 4038.97f, 194.27f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - add = me->SummonCreature(ENTRY_ARA_TECH, 4033.66f, 4036.79f, 194.28f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - add = me->SummonCreature(ENTRY_ARA_TECH, 4037.13f, 4037.30f, 194.23f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); - } - else - { - add = me->SummonCreature(ENTRY_ARA_TECH, 3099.59f, 4049.30f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - add = me->SummonCreature(ENTRY_ARA_TECH, 3999.72f, 4046.75f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - add = me->SummonCreature(ENTRY_ARA_TECH, 3996.81f, 4048.26f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); - } - Wave_Timer = 15000; - break; - } - } - void DoFinalSpawnForCreature(Creature* creature) - { - switch (creature->GetEntry()) - { - case ENTRY_BNAAR_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2946.52f, 4201.42f, 163.47f, 3.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2927.49f, 4192.81f, 163.00f); - break; - case ENTRY_CORUU_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2453.88f, 2737.85f, 133.27f, 2.59f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2441.62f, 2735.32f, 134.49f, 1.97f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2450.73f, 2754.50f, 134.49f, 3.29f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); - break; - case ENTRY_DURO_C_CONSOLE: - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2956.18f, 2202.85f, 165.32f, 5.45f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2975.30f, 2211.50f, 165.32f, 4.55f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - add = me->SummonCreature(ENTRY_SUNFURY_PROT, 2965.02f, 2217.45f, 164.16f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); - break; - case ENTRY_ARA_C_CONSOLE: - add = me->SummonCreature(ENTRY_ARA_ENGI, 3994.51f, 4020.46f, 192.18f, 0.91f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4008.35f, 4035.04f, 192.70f); - add = me->SummonCreature(ENTRY_ARA_GORKLONN, 4021.56f, 4059.35f, 193.59f, 4.44f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); - if (add) add->GetMotionMaster()->MovePoint(0, 4016.62f, 4039.89f, 193.46f); - break; - } - } - - void UpdateAI(const uint32 diff) - { - if (Event_Timer <= diff) - { - switch (Phase) - { - case 1: - if (someplayer) - { - Unit* u = Unit::GetUnit(*me, someplayer); - if (u && u->GetTypeId() == TYPEID_PLAYER) - Talk(EMOTE_START, u->GetGUID()); - } - Event_Timer = 60000; - Wave = true; - ++Phase; - break; - case 2: - Talk(EMOTE_60); - Event_Timer = 30000; - ++Phase; - break; - case 3: - Talk(EMOTE_30); - Event_Timer = 20000; - DoFinalSpawnForCreature(me); - ++Phase; - break; - case 4: - Talk(EMOTE_10); - Event_Timer = 10000; - Wave = false; - ++Phase; - break; - case 5: - Talk(EMOTE_COMPLETE); - if (someplayer) - { - Unit* u = Unit::GetUnit(*me, someplayer); - if (u && u->GetTypeId() == TYPEID_PLAYER) - CAST_PLR(u)->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); - DoCast(me, SPELL_DISABLE_VISUAL); - } - if (goConsole) - { - if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - ++Phase; - break; - } - } else Event_Timer -= diff; - - if (Wave) - { - if (Wave_Timer <= diff) - { - DoWaveSpawnForCreature(me); - } else Wave_Timer -= diff; - } - } - }; -}; - -/*###### -## go_manaforge_control_console -######*/ - -//TODO: clean up this workaround when Trinity adds support to do it properly (with gossip selections instead of instant summon) -class go_manaforge_control_console : public GameObjectScript -{ -public: - go_manaforge_control_console() : GameObjectScript("go_manaforge_control_console") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) - { - player->PrepareQuestMenu(go->GetGUID()); - player->SendPreparedQuest(go->GetGUID()); - } - - Creature* manaforge = NULL; - - switch (go->GetAreaId()) - { - case 3726: //b'naar - if ((player->GetQuestStatus(10299) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10329) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29366)) - manaforge = player->SummonCreature(ENTRY_BNAAR_C_CONSOLE, 2918.95f, 4189.98f, 161.88f, 0.34f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3730: //coruu - if ((player->GetQuestStatus(10321) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10330) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29396)) - manaforge = player->SummonCreature(ENTRY_CORUU_C_CONSOLE, 2426.77f, 2750.38f, 133.24f, 2.14f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3734: //duro - if ((player->GetQuestStatus(10322) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10338) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29397)) - manaforge = player->SummonCreature(ENTRY_DURO_C_CONSOLE, 2976.48f, 2183.29f, 163.20f, 1.85f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - case 3722: //ara - if ((player->GetQuestStatus(10323) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10365) == QUEST_STATUS_INCOMPLETE) && - player->HasItemCount(29411)) - manaforge = player->SummonCreature(ENTRY_ARA_C_CONSOLE, 4013.71f, 4028.76f, 192.10f, 1.25f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); - break; - } - - if (manaforge) - { - CAST_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->someplayer = player->GetGUID(); - CAST_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->goConsole = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - } - return true; - } -}; - -/*###### -## npc_commander_dawnforge -######*/ - -// The Speech of Dawnforge, Ardonis & Pathaleon -enum eCommanderDawnforgeData -{ - SAY_COMMANDER_DAWNFORGE_1 = 0, - SAY_COMMANDER_DAWNFORGE_2 = 1, - SAY_COMMANDER_DAWNFORGE_3 = 2, - SAY_COMMANDER_DAWNFORGE_4 = 3, - SAY_COMMANDER_DAWNFORGE_5 = 4, - - SAY_ARCANIST_ARDONIS_1 = 0, - SAY_ARCANIST_ARDONIS_2 = 1, - - SAY_PATHALEON_CULATOR_IMAGE_1 = 0, - SAY_PATHALEON_CULATOR_IMAGE_2 = 1, - SAY_PATHALEON_CULATOR_IMAGE_2_1 = 2, - SAY_PATHALEON_CULATOR_IMAGE_2_2 = 3, - - QUEST_INFO_GATHERING = 10198, - SPELL_SUNFURY_DISGUISE = 34603, -}; - -// Entries of Arcanist Ardonis, Commander Dawnforge, Pathaleon the Curators Image -const uint32 CreatureEntry[3] = -{ - 19830, // Ardonis - 19831, // Dawnforge - 21504 // Pathaleon -}; - -class npc_commander_dawnforge : public CreatureScript -{ -public: - npc_commander_dawnforge() : CreatureScript("npc_commander_dawnforge") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_commander_dawnforgeAI(creature); - } - - struct npc_commander_dawnforgeAI : public ScriptedAI - { - npc_commander_dawnforgeAI(Creature* creature) : ScriptedAI(creature) { Reset(); } - - uint64 PlayerGUID; - uint64 ardonisGUID; - uint64 pathaleonGUID; - - uint32 Phase; - uint32 PhaseSubphase; - uint32 Phase_Timer; - bool isEvent; - - float angle_dawnforge; - float angle_ardonis; - - void Reset() - { - PlayerGUID = 0; - ardonisGUID = 0; - pathaleonGUID = 0; - - Phase = 1; - PhaseSubphase = 0; - Phase_Timer = 4000; - isEvent = false; - } - - void EnterCombat(Unit* /*who*/) { } - - void JustSummoned(Creature* summoned) - { - pathaleonGUID = summoned->GetGUID(); - } - - // Emote Ardonis and Pathaleon - void Turn_to_Pathaleons_Image() - { - Creature* ardonis = Unit::GetCreature(*me, ardonisGUID); - Creature* pathaleon = Unit::GetCreature(*me, pathaleonGUID); - Player* player = Unit::GetPlayer(*me, PlayerGUID); - - if (!ardonis || !pathaleon || !player) - return; - - //Calculate the angle to Pathaleon - angle_dawnforge = me->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY()); - angle_ardonis = ardonis->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY()); - - //Turn Dawnforge and update - me->SetOrientation(angle_dawnforge); - me->SendUpdateToPlayer(player); - //Turn Ardonis and update - ardonis->SetOrientation(angle_ardonis); - ardonis->SendUpdateToPlayer(player); - - //Set them to kneel - me->SetStandState(UNIT_STAND_STATE_KNEEL); - ardonis->SetStandState(UNIT_STAND_STATE_KNEEL); - } - - //Set them back to each other - void Turn_to_eachother() - { - if (Unit* ardonis = Unit::GetUnit(*me, ardonisGUID)) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - - if (!player) - return; - - angle_dawnforge = me->GetAngle(ardonis->GetPositionX(), ardonis->GetPositionY()); - angle_ardonis = ardonis->GetAngle(me->GetPositionX(), me->GetPositionY()); - - //Turn Dawnforge and update - me->SetOrientation(angle_dawnforge); - me->SendUpdateToPlayer(player); - //Turn Ardonis and update - ardonis->SetOrientation(angle_ardonis); - ardonis->SendUpdateToPlayer(player); - - //Set state - me->SetStandState(UNIT_STAND_STATE_STAND); - ardonis->SetStandState(UNIT_STAND_STATE_STAND); - } - } - - bool CanStartEvent(Player* player) - { - if (!isEvent) - { - Creature* ardonis = me->FindNearestCreature(CreatureEntry[0], 10.0f); - if (!ardonis) - return false; - - ardonisGUID = ardonis->GetGUID(); - PlayerGUID = player->GetGUID(); - - isEvent = true; - - Turn_to_eachother(); - return true; - } - - sLog->outDebug(LOG_FILTER_TSCR, "npc_commander_dawnforge event already in progress, need to wait."); - return false; - } - - void UpdateAI(const uint32 diff) - { - //Is event even running? - if (!isEvent) - return; - - //Phase timing - if (Phase_Timer >= diff) - { - Phase_Timer -= diff; - return; - } - - Creature* ardonis = Creature::GetCreature(*me, ardonisGUID); - Creature* pathaleon = Creature::GetCreature(*me, pathaleonGUID); - Player* player = Unit::GetPlayer(*me, PlayerGUID); - - if (!ardonis || !player) - { - Reset(); - return; - } - - if (Phase > 4 && !pathaleon) - { - Reset(); - return; - } - - //Phase 1 Dawnforge say - switch (Phase) - { - case 1: - Talk(SAY_COMMANDER_DAWNFORGE_1); - ++Phase; - Phase_Timer = 16000; - break; - //Phase 2 Ardonis say - case 2: - ardonis->AI()->Talk(SAY_ARCANIST_ARDONIS_1); - ++Phase; - Phase_Timer = 16000; - break; - //Phase 3 Dawnforge say - case 3: - Talk(SAY_COMMANDER_DAWNFORGE_2); - ++Phase; - Phase_Timer = 16000; - break; - //Phase 4 Pathaleon spawns up to phase 9 - case 4: - //spawn pathaleon's image - me->SummonCreature(CreatureEntry[2], 2325.851563f, 2799.534668f, 133.084229f, 6.038996f, TEMPSUMMON_TIMED_DESPAWN, 90000); - ++Phase; - Phase_Timer = 500; - break; - //Phase 5 Pathaleon say - case 5: - pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_1); - ++Phase; - Phase_Timer = 6000; - break; - //Phase 6 - case 6: - switch (PhaseSubphase) - { - //Subphase 1: Turn Dawnforge and Ardonis - case 0: - Turn_to_Pathaleons_Image(); - ++PhaseSubphase; - Phase_Timer = 8000; - break; - //Subphase 2 Dawnforge say - case 1: - Talk(SAY_COMMANDER_DAWNFORGE_3); - PhaseSubphase = 0; - ++Phase; - Phase_Timer = 8000; - break; - } - break; - //Phase 7 Pathaleons say 3 Sentence, every sentence need a subphase - case 7: - switch (PhaseSubphase) - { - //Subphase 1 - case 0: - pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_2); - ++PhaseSubphase; - Phase_Timer = 12000; - break; - //Subphase 2 - case 1: - pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_2_1); - ++PhaseSubphase; - Phase_Timer = 16000; - break; - //Subphase 3 - case 2: - pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_2_2); - PhaseSubphase = 0; - ++Phase; - Phase_Timer = 10000; - break; - } - break; - //Phase 8 Dawnforge & Ardonis say - case 8: - Talk(SAY_COMMANDER_DAWNFORGE_4); - ardonis->AI()->Talk(SAY_ARCANIST_ARDONIS_2); - ++Phase; - Phase_Timer = 4000; - break; - //Phase 9 Pathaleons Despawn, Reset Dawnforge & Ardonis angle - case 9: - Turn_to_eachother(); - //hide pathaleon, unit will despawn shortly - pathaleon->SetVisible(false); - PhaseSubphase = 0; - ++Phase; - Phase_Timer = 3000; - break; - //Phase 10 Dawnforge say - case 10: - Talk(SAY_COMMANDER_DAWNFORGE_5); - player->AreaExploredOrEventHappens(QUEST_INFO_GATHERING); - Reset(); - break; - } - } - }; -}; - -class at_commander_dawnforge : public AreaTriggerScript -{ -public: - at_commander_dawnforge() : AreaTriggerScript("at_commander_dawnforge") { } - - bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) - { - //if player lost aura or not have at all, we should not try start event. - if (!player->HasAura(SPELL_SUNFURY_DISGUISE)) - return false; - - if (player->isAlive() && player->GetQuestStatus(QUEST_INFO_GATHERING) == QUEST_STATUS_INCOMPLETE) - { - Creature* Dawnforge = player->FindNearestCreature(CreatureEntry[1], 30.0f); - if (!Dawnforge) - return false; - - if (CAST_AI(npc_commander_dawnforge::npc_commander_dawnforgeAI, Dawnforge->AI())->CanStartEvent(player)) - return true; - } - return false; - } -}; - -/*###### -## npc_professor_dabiri -######*/ -enum eProfessorDabiriData -{ - SPELL_PHASE_DISTRUPTOR = 35780, - - //WHISPER_DABIRI = 0, not existing in database - - QUEST_DIMENSIUS = 10439, - QUEST_ON_NETHERY_WINGS = 10438, -}; - -#define GOSSIP_ITEM "I need a new phase distruptor, Professor" - -class npc_professor_dabiri : public CreatureScript -{ -public: - npc_professor_dabiri() : CreatureScript("npc_professor_dabiri") { } - - //OnQuestAccept: - //if (quest->GetQuestId() == QUEST_DIMENSIUS) - //creature->AI()->Talk(WHISPER_DABIRI, player->GetGUID()); - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - creature->CastSpell(player, SPELL_PHASE_DISTRUPTOR, false); - player->CLOSE_GOSSIP_MENU(); - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_ON_NETHERY_WINGS) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(29778)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## mob_phase_hunter -######*/ - -enum ePhaseHunterData -{ - QUEST_RECHARGING_THE_BATTERIES = 10190, - - NPC_PHASE_HUNTER_ENTRY = 18879, - NPC_DRAINED_PHASE_HUNTER_ENTRY = 19595, - - EMOTE_WEAK = 0, - - // Spells - SPELL_RECHARGING_BATTERY = 34219, - SPELL_PHASE_SLIP = 36574, - SPELL_MANA_BURN = 13321, - SPELL_MATERIALIZE = 34804, - SPELL_DE_MATERIALIZE = 34814, -}; - -class mob_phase_hunter : public CreatureScript -{ -public: - mob_phase_hunter() : CreatureScript("mob_phase_hunter") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_phase_hunterAI (creature); - } - - struct mob_phase_hunterAI : public ScriptedAI - { - mob_phase_hunterAI(Creature* creature) : ScriptedAI(creature) {} - - bool Weak; - bool Materialize; - bool Drained; - uint8 WeakPercent; - - Player* player; - uint64 PlayerGUID; - - uint32 ManaBurnTimer; - - void Reset() - { - Weak = false; - Materialize = false; - Drained = false; - WeakPercent = 25 + (rand() % 16); // 25-40 - - PlayerGUID = 0; - - ManaBurnTimer = 5000 + (rand() % 3 * 1000); // 5-8 sec cd - - if (me->GetEntry() == NPC_DRAINED_PHASE_HUNTER_ENTRY) - me->UpdateEntry(NPC_PHASE_HUNTER_ENTRY); - } - - void EnterCombat(Unit* who) - { - if (who->GetTypeId() == TYPEID_PLAYER) - PlayerGUID = who->GetGUID(); - } - - //void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/) - //{ - // DoCast(me, SPELL_DE_MATERIALIZE); - //} - - void UpdateAI(const uint32 diff) - { - if (!Materialize) - { - DoCast(me, SPELL_MATERIALIZE); - Materialize = true; - } - - if (me->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || me->HasUnitState(UNIT_STATE_ROOT)) // if the mob is rooted/slowed by spells eg.: Entangling Roots, Frost Nova, Hamstring, Crippling Poison, etc. => remove it - DoCast(me, SPELL_PHASE_SLIP); - - if (!UpdateVictim()) - return; - - // some code to cast spell Mana Burn on random target which has mana - if (ManaBurnTimer <= diff) - { - std::list AggroList = me->getThreatManager().getThreatList(); - std::list UnitsWithMana; - - for (std::list::const_iterator itr = AggroList.begin(); itr != AggroList.end(); ++itr) - { - if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) - { - if (unit->GetCreateMana() > 0) - UnitsWithMana.push_back(unit); - } - } - if (!UnitsWithMana.empty()) - { - DoCast(Trinity::Containers::SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN); - ManaBurnTimer = 8000 + (rand() % 10 * 1000); // 8-18 sec cd - } - else - ManaBurnTimer = 3500; - } else ManaBurnTimer -= diff; - - if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) // start: support for quest 10190 - { - if (!Weak && HealthBelowPct(WeakPercent) - && player->GetQuestStatus(QUEST_RECHARGING_THE_BATTERIES) == QUEST_STATUS_INCOMPLETE) - { - Talk(EMOTE_WEAK); - Weak = true; - } - if (Weak && !Drained && me->HasAura(SPELL_RECHARGING_BATTERY)) - { - Drained = true; - int32 uHpPct = int32(me->GetHealthPct()); - - me->UpdateEntry(NPC_DRAINED_PHASE_HUNTER_ENTRY); - - me->SetHealth(me->CountPctFromMaxHealth(uHpPct)); - me->LowerPlayerDamageReq(me->GetMaxHealth() - me->GetHealth()); - me->SetInCombatWith(player); - } - } // end: support for quest 10190 - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_bessy -######*/ -enum eBessyData -{ - Q_ALMABTRIEB = 10337, - N_THADELL = 20464, - SPAWN_FIRST = 20512, - SPAWN_SECOND = 19881, - SAY_THADELL_1 = 0, - SAY_THADELL_2 = 1, -}; - -class npc_bessy : public CreatureScript -{ -public: - npc_bessy() : CreatureScript("npc_bessy") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == Q_ALMABTRIEB) - { - creature->setFaction(113); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_bessyAI(creature); - } - - struct npc_bessyAI : public npc_escortAI - { - npc_bessyAI(Creature* creature) : npc_escortAI(creature) {} - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(Q_ALMABTRIEB); - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 3: //first spawn - me->SummonCreature(SPAWN_FIRST, 2449.67f, 2183.11f, 96.85f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_FIRST, 2449.53f, 2184.43f, 96.36f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_FIRST, 2449.85f, 2186.34f, 97.57f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 7: - me->SummonCreature(SPAWN_SECOND, 2309.64f, 2186.24f, 92.25f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(SPAWN_SECOND, 2309.25f, 2183.46f, 91.75f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 12: - player->GroupEventHappens(Q_ALMABTRIEB, me); - if (me->FindNearestCreature(N_THADELL, 30)) - Talk(SAY_THADELL_1); - break; - case 13: - if (me->FindNearestCreature(N_THADELL, 30)) - Talk(SAY_THADELL_2, player->GetGUID()); - break; - } - } - - void JustSummoned(Creature* summoned) - { - summoned->AI()->AttackStart(me); - } - - void Reset() - { - me->RestoreFaction(); - } - }; -}; - -/*###### -## npc_maxx_a_million -######*/ - -enum -{ - QUEST_MARK_V_IS_ALIVE = 10191, - GO_DRAENEI_MACHINE = 183771 -}; - -class npc_maxx_a_million_escort : public CreatureScript -{ -public: - npc_maxx_a_million_escort() : CreatureScript("npc_maxx_a_million_escort") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_maxx_a_million_escortAI(creature); - } - - struct npc_maxx_a_million_escortAI : public npc_escortAI - { - npc_maxx_a_million_escortAI(Creature* creature) : npc_escortAI(creature) {} - - bool bTake; - uint32 uiTakeTimer; - - void Reset() - { - bTake=false; - uiTakeTimer=3000; - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 7: - case 17: - case 29: - //Find Object and "work" - if (GetClosestGameObjectWithEntry(me, GO_DRAENEI_MACHINE, INTERACTION_DISTANCE)) - { - // take the GO -> animation - me->HandleEmoteCommand(EMOTE_STATE_LOOT); - SetEscortPaused(true); - bTake=true; - } - break; - case 36: //return and quest_complete - player->CompleteQuest(QUEST_MARK_V_IS_ALIVE); - break; - } - } - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - player->FailQuest(QUEST_MARK_V_IS_ALIVE); - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (bTake) - { - if (uiTakeTimer < uiDiff) - { - me->HandleEmoteCommand(EMOTE_STATE_NONE); - if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_DRAENEI_MACHINE, INTERACTION_DISTANCE)) - { - SetEscortPaused(false); - bTake=false; - uiTakeTimer = 3000; - go->Delete(); - } - } - else - uiTakeTimer -= uiDiff; - } - DoMeleeAttackIfReady(); - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_MARK_V_IS_ALIVE) - { - if (npc_maxx_a_million_escortAI* pEscortAI = CAST_AI(npc_maxx_a_million_escort::npc_maxx_a_million_escortAI, creature->AI())) - { - creature->setFaction(113); - pEscortAI->Start(false, false, player->GetGUID()); - } - } - return true; - } -}; - -/*###### -## go_captain_tyralius_prison -######*/ - -enum CaptainTyralius -{ - NPC_CAPTAIN_TYRALIUS = 20787, - SAY_FREE = 0, -}; - -class go_captain_tyralius_prison : public GameObjectScript -{ - public: - go_captain_tyralius_prison() : GameObjectScript("go_captain_tyralius_prison") { } - - bool OnGossipHello(Player* player, GameObject* go) - { - go->UseDoorOrButton(); - if (Creature* tyralius = go->FindNearestCreature(NPC_CAPTAIN_TYRALIUS, 1.0f)) - { - player->KilledMonsterCredit(NPC_CAPTAIN_TYRALIUS, 0); - tyralius->AI()->Talk(SAY_FREE); - tyralius->DespawnOrUnsummon(8000); - } - return true; - } -}; - -void AddSC_netherstorm() -{ - new go_manaforge_control_console(); - new npc_manaforge_control_console(); - new npc_commander_dawnforge(); - new at_commander_dawnforge(); - new npc_professor_dabiri(); - new mob_phase_hunter(); - new npc_bessy(); - new npc_maxx_a_million_escort(); - new go_captain_tyralius_prison(); -} diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp deleted file mode 100644 index 0a016f0923c..00000000000 --- a/src/server/scripts/Outland/shadowmoon_valley.cpp +++ /dev/null @@ -1,1998 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Shadowmoon_Valley -SD%Complete: 100 -SDComment: Quest support: 10519, 10583, 10601, 10804, 10854, 10458, 10481, 10480, 11082, 10781, 10451. Vendor Drake Dealer Hurlunk. -SDCategory: Shadowmoon Valley -EndScriptData */ - -/* ContentData -mob_mature_netherwing_drake -mob_enslaved_netherwing_drake -npc_drake_dealer_hurlunk -npcs_flanis_swiftwing_and_kagrosh -npc_murkblood_overseer -npc_karynaku -npc_oronok_tornheart -npc_overlord_morghor -npc_earthmender_wilda -mob_torloth_the_magnificent -mob_illidari_spawn -npc_lord_illidan_stormrage -go_crystal_prison -npc_enraged_spirit -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Group.h" -#include "SpellScript.h" -#include "Player.h" -#include "WorldSession.h" - -/*##### -# mob_mature_netherwing_drake -#####*/ - -enum eMatureNetherwing -{ - SAY_JUST_EATEN = 0, - - SPELL_PLACE_CARCASS = 38439, - SPELL_JUST_EATEN = 38502, - SPELL_NETHER_BREATH = 38467, - POINT_ID = 1, - - GO_CARCASS = 185155, - - QUEST_KINDNESS = 10804, - NPC_EVENT_PINGER = 22131 -}; - -class mob_mature_netherwing_drake : public CreatureScript -{ -public: - mob_mature_netherwing_drake() : CreatureScript("mob_mature_netherwing_drake") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_mature_netherwing_drakeAI(creature); - } - - struct mob_mature_netherwing_drakeAI : public ScriptedAI - { - mob_mature_netherwing_drakeAI(Creature* creature) : ScriptedAI(creature) { } - - uint64 uiPlayerGUID; - - bool bCanEat; - bool bIsEating; - - uint32 EatTimer; - uint32 CastTimer; - - void Reset() - { - uiPlayerGUID = 0; - - bCanEat = false; - bIsEating = false; - - EatTimer = 5000; - CastTimer = 5000; - } - - void SpellHit(Unit* pCaster, SpellInfo const* spell) - { - if (bCanEat || bIsEating) - return; - - if (pCaster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_PLACE_CARCASS && !me->HasAura(SPELL_JUST_EATEN)) - { - uiPlayerGUID = pCaster->GetGUID(); - bCanEat = true; - } - } - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id == POINT_ID) - { - bIsEating = true; - EatTimer = 7000; - me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK_UNARMED); - } - } - - void UpdateAI(const uint32 diff) - { - if (bCanEat || bIsEating) - { - if (EatTimer <= diff) - { - if (bCanEat && !bIsEating) - { - if (Unit* unit = Unit::GetUnit(*me, uiPlayerGUID)) - { - if (GameObject* go = unit->FindNearestGameObject(GO_CARCASS, 10)) - { - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - me->GetMotionMaster()->MovementExpired(); - - me->GetMotionMaster()->MoveIdle(); - me->StopMoving(); - - me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()); - } - } - bCanEat = false; - } - else if (bIsEating) - { - DoCast(me, SPELL_JUST_EATEN); - Talk(SAY_JUST_EATEN); - - if (Player* pPlr = Unit::GetPlayer(*me, uiPlayerGUID)) - { - pPlr->KilledMonsterCredit(NPC_EVENT_PINGER, 0); - - if (GameObject* go = pPlr->FindNearestGameObject(GO_CARCASS, 10)) - go->Delete(); - } - - Reset(); - me->GetMotionMaster()->Clear(); - } - } - else - EatTimer -= diff; - - return; - } - - if (!UpdateVictim()) - return; - - if (CastTimer <= diff) - { - DoCast(me->getVictim(), SPELL_NETHER_BREATH); - CastTimer = 5000; - } else CastTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*### -# mob_enslaved_netherwing_drake -####*/ - -#define FACTION_DEFAULT 62 -#define FACTION_FRIENDLY 1840 // Not sure if this is correct, it was taken off of Mordenai. - -#define SPELL_HIT_FORCE_OF_NELTHARAKU 38762 -#define SPELL_FORCE_OF_NELTHARAKU 38775 - -#define CREATURE_DRAGONMAW_SUBJUGATOR 21718 -#define CREATURE_ESCAPE_DUMMY 22317 - -class mob_enslaved_netherwing_drake : public CreatureScript -{ -public: - mob_enslaved_netherwing_drake() : CreatureScript("mob_enslaved_netherwing_drake") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_enslaved_netherwing_drakeAI(creature); - } - - struct mob_enslaved_netherwing_drakeAI : public ScriptedAI - { - mob_enslaved_netherwing_drakeAI(Creature* creature) : ScriptedAI(creature) - { - PlayerGUID = 0; - Tapped = false; - Reset(); - } - - uint64 PlayerGUID; - uint32 FlyTimer; - bool Tapped; - - void Reset() - { - if (!Tapped) - me->setFaction(FACTION_DEFAULT); - - FlyTimer = 10000; - me->SetDisableGravity(false); - me->SetVisible(true); - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (!caster) - return; - - if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_HIT_FORCE_OF_NELTHARAKU && !Tapped) - { - Tapped = true; - PlayerGUID = caster->GetGUID(); - - me->setFaction(FACTION_FRIENDLY); - DoCast(caster, SPELL_FORCE_OF_NELTHARAKU, true); - - Unit* Dragonmaw = me->FindNearestCreature(CREATURE_DRAGONMAW_SUBJUGATOR, 50); - if (Dragonmaw) - { - me->AddThreat(Dragonmaw, 100000.0f); - AttackStart(Dragonmaw); - } - - HostileReference* ref = me->getThreatManager().getOnlineContainer().getReferenceByTarget(caster); - if (ref) - ref->removeReference(); - } - } - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id == 1) - { - if (PlayerGUID) - { - Unit* player = Unit::GetUnit(*me, PlayerGUID); - if (player) - DoCast(player, SPELL_FORCE_OF_NELTHARAKU, true); - - PlayerGUID = 0; - } - me->SetVisible(false); - me->SetDisableGravity(false); - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - me->RemoveCorpse(); - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - { - if (Tapped) - { - if (FlyTimer <= diff) - { - Tapped = false; - if (PlayerGUID) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player && player->GetQuestStatus(10854) == QUEST_STATUS_INCOMPLETE) - { - DoCast(player, SPELL_FORCE_OF_NELTHARAKU, true); - /* - float x, y, z; - me->GetPosition(x, y, z); - - float dx, dy, dz; - me->GetRandomPoint(x, y, z, 20, dx, dy, dz); - dz += 20; // so it's in the air, not ground*/ - - Position pos; - if (Unit* EscapeDummy = me->FindNearestCreature(CREATURE_ESCAPE_DUMMY, 30)) - EscapeDummy->GetPosition(&pos); - else - { - me->GetRandomNearPosition(pos, 20); - pos.m_positionZ += 25; - } - - me->SetDisableGravity(true); - me->GetMotionMaster()->MovePoint(1, pos); - } - } - } else FlyTimer -= diff; - } - return; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -/*##### -# mob_dragonmaw_peon -#####*/ - -class mob_dragonmaw_peon : public CreatureScript -{ -public: - mob_dragonmaw_peon() : CreatureScript("mob_dragonmaw_peon") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_dragonmaw_peonAI(creature); - } - - struct mob_dragonmaw_peonAI : public ScriptedAI - { - mob_dragonmaw_peonAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - bool Tapped; - uint32 PoisonTimer; - - void Reset() - { - PlayerGUID = 0; - Tapped = false; - PoisonTimer = 0; - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (!caster) - return; - - if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == 40468 && !Tapped) - { - PlayerGUID = caster->GetGUID(); - - Tapped = true; - float x, y, z; - caster->GetClosePoint(x, y, z, me->GetObjectSize()); - - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(1, x, y, z); - } - } - - void MovementInform(uint32 type, uint32 id) - { - if (type != POINT_MOTION_TYPE) - return; - - if (id) - { - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_EAT); - PoisonTimer = 15000; - } - } - - void UpdateAI(const uint32 diff) - { - if (PoisonTimer) - { - if (PoisonTimer <= diff) - { - if (PlayerGUID) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player && player->GetQuestStatus(11020) == QUEST_STATUS_INCOMPLETE) - player->KilledMonsterCredit(23209, 0); - } - PoisonTimer = 0; - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } else PoisonTimer -= diff; - } - } - }; -}; - -/*###### -## npc_drake_dealer_hurlunk -######*/ - -class npc_drake_dealer_hurlunk : public CreatureScript -{ -public: - npc_drake_dealer_hurlunk() : CreatureScript("npc_drake_dealer_hurlunk") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isVendor() && player->GetReputationRank(1015) == REP_EXALTED) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_flanis_swiftwing_and_kagrosh -######*/ - -#define GOSSIP_HSK1 "Take Flanis's Pack" -#define GOSSIP_HSK2 "Take Kagrosh's Pack" - -class npcs_flanis_swiftwing_and_kagrosh : public CreatureScript -{ -public: - npcs_flanis_swiftwing_and_kagrosh() : CreatureScript("npcs_flanis_swiftwing_and_kagrosh") { } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 30658, 1, NULL); - if (msg == EQUIP_ERR_OK) - { - player->StoreNewItem(dest, 30658, 1, true); - player->PlayerTalkClass->ClearMenus(); - } - } - if (action == GOSSIP_ACTION_INFO_DEF+2) - { - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 30659, 1, NULL); - if (msg == EQUIP_ERR_OK) - { - player->StoreNewItem(dest, 30659, 1, true); - player->PlayerTalkClass->ClearMenus(); - } - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(10583) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(30658, 1, true)) - player->ADD_GOSSIP_ITEM(0, GOSSIP_HSK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - if (player->GetQuestStatus(10601) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(30659, 1, true)) - player->ADD_GOSSIP_ITEM(0, GOSSIP_HSK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -## npc_murkblood_overseer -######*/ - -#define QUEST_11082 11082 - -#define GOSSIP_HMO "I am here for you, overseer." -#define GOSSIP_SMO1 "How dare you question an overseer of the Dragonmaw!" -#define GOSSIP_SMO2 "Who speaks of me? What are you talking about, broken?" -#define GOSSIP_SMO3 "Continue please." -#define GOSSIP_SMO4 "Who are these bidders?" -#define GOSSIP_SMO5 "Well... yes." - -class npc_murkblood_overseer : public CreatureScript -{ -public: - npc_murkblood_overseer() : CreatureScript("npc_murkblood_overseer") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - //correct id not known - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - //correct id not known - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - //correct id not known - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - //correct id not known - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - //correct id not known - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - //correct id not known - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - creature->CastSpell(player, 41121, false); - player->AreaExploredOrEventHappens(QUEST_11082); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_11082) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(0, GOSSIP_HMO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_oronok -######*/ - -#define GOSSIP_ORONOK1 "I am ready to hear your story, Oronok." -#define GOSSIP_ORONOK2 "How do I find the cipher?" -#define GOSSIP_ORONOK3 "How do you know all of this?" -#define GOSSIP_ORONOK4 "Yet what? What is it, Oronok?" -#define GOSSIP_ORONOK5 "Continue, please." -#define GOSSIP_ORONOK6 "So what of the cipher now? And your boys?" -#define GOSSIP_ORONOK7 "I will find your boys and the cipher, Oronok." - -class npc_oronok_tornheart : public CreatureScript -{ -public: - npc_oronok_tornheart() : CreatureScript("npc_oronok_tornheart") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(10313, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(10314, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(10315, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(10316, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(10317, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(10318, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->CLOSE_GOSSIP_MENU(); - player->AreaExploredOrEventHappens(10519); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - if (creature->isVendor()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - if (player->GetQuestStatus(10519) == QUEST_STATUS_INCOMPLETE) - { - player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(10312, creature->GetGUID()); - }else - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*#### -# npc_karynaku -####*/ - -enum Karynaku -{ - QUEST_ALLY_OF_NETHER = 10870, - QUEST_ZUHULED_THE_WACK = 10866, - - NPC_ZUHULED_THE_WACKED = 11980, - - TAXI_PATH_ID = 649, -}; - -class npc_karynaku : public CreatureScript -{ - public: - npc_karynaku() : CreatureScript("npc_karynaku") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER) - player->ActivateTaxiPathTo(TAXI_PATH_ID); - - if (quest->GetQuestId() == QUEST_ZUHULED_THE_WACK) - creature->SummonCreature(NPC_ZUHULED_THE_WACKED, -4204.94f, 316.397f, 122.508f, 1.309f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); - - return true; - } -}; - -/*#### -# npc_overlord_morghor -####*/ -enum eOverlordData -{ - QUEST_LORD_ILLIDAN_STORMRAGE = 11108, - - C_ILLIDAN = 22083, - C_YARZILL = 23141, - - SPELL_ONE = 39990, // Red Lightning Bolt - SPELL_TWO = 41528, // Mark of Stormrage - SPELL_THREE = 40216, // Dragonaw Faction - SPELL_FOUR = 42016, // Dragonaw Trasform - - OVERLORD_SAY_1 = 0, - OVERLORD_SAY_2 = 1, - //OVERLORD_SAY_3 = 2, - OVERLORD_SAY_4 = 3, - OVERLORD_SAY_5 = 4, - OVERLORD_SAY_6 = 5, - - OVERLORD_YELL_1 = 6, - OVERLORD_YELL_2 = 7, - - LORD_ILLIDAN_SAY_1 = 0, - LORD_ILLIDAN_SAY_2 = 1, - LORD_ILLIDAN_SAY_3 = 2, - LORD_ILLIDAN_SAY_4 = 3, - LORD_ILLIDAN_SAY_5 = 4, - LORD_ILLIDAN_SAY_6 = 5, - LORD_ILLIDAN_SAY_7 = 6, - - YARZILL_THE_MERC_SAY = 0 -}; - -class npc_overlord_morghor : public CreatureScript -{ -public: - npc_overlord_morghor() : CreatureScript("npc_overlord_morghor") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest *_Quest) - { - if (_Quest->GetQuestId() == QUEST_LORD_ILLIDAN_STORMRAGE) - { - CAST_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->StartEvent(); - return true; - } - return false; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_overlord_morghorAI(creature); - } - - struct npc_overlord_morghorAI : public ScriptedAI - { - npc_overlord_morghorAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - uint64 IllidanGUID; - - uint32 ConversationTimer; - uint32 Step; - - bool Event; - - void Reset() - { - PlayerGUID = 0; - IllidanGUID = 0; - - ConversationTimer = 0; - Step = 0; - - Event = false; - me->SetUInt32Value(UNIT_NPC_FLAGS, 2); - } - - void StartEvent() - { - me->SetUInt32Value(UNIT_NPC_FLAGS, 0); - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - Unit* Illidan = me->SummonCreature(C_ILLIDAN, -5107.83f, 602.584f, 85.2393f, 4.92598f, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (Illidan) - { - IllidanGUID = Illidan->GetGUID(); - Illidan->SetVisible(false); - } - if (PlayerGUID) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player) - Talk(OVERLORD_SAY_1, player->GetGUID()); - } - ConversationTimer = 4200; - Step = 0; - Event = true; - } - - uint32 NextStep(uint32 Step) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - Creature* Illi = Creature::GetCreature(*me, IllidanGUID); - - if (!player || !Illi) - { - EnterEvadeMode(); - return 0; - } - - switch (Step) - { - case 0: - return 0; - break; - case 1: - me->GetMotionMaster()->MovePoint(0, -5104.41f, 595.297f, 85.6838f); - return 9000; - break; - case 2: - Talk(OVERLORD_YELL_1, player->GetGUID()); - return 4500; - break; - case 3: - me->SetInFront(player); - return 3200; - break; - case 4: - Talk(OVERLORD_SAY_2, player->GetGUID()); - return 2000; - break; - case 5: - Illi->SetVisible(true); - Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - return 350; - break; - case 6: - Illi->CastSpell(Illi, SPELL_ONE, true); - Illi->SetTarget(me->GetGUID()); - me->SetTarget(IllidanGUID); - return 2000; - break; - case 7: - Talk(OVERLORD_YELL_2); - return 4500; - break; - case 8: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); - return 9000; - break; - case 10: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); - return 5000; - break; - case 11: - Talk(OVERLORD_SAY_4, player->GetGUID()); - return 6000; - break; - case 12: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); - return 5500; - break; - case 13: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); - return 4000; - break; - case 14: - Illi->SetTarget(PlayerGUID); - return 1500; - break; - case 15: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); - return 1500; - break; - case 16: - Illi->CastSpell(player, SPELL_TWO, true); - player->RemoveAurasDueToSpell(SPELL_THREE); - player->RemoveAurasDueToSpell(SPELL_FOUR); - return 5000; - break; - case 17: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); - return 5000; - break; - case 18: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); - return 5000; - break; - case 19: - Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); - return 5000; - break; - case 20: - Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - Illi->SetDisableGravity(true); - return 500; - break; - case 21: - Talk(OVERLORD_SAY_5); - return 500; - break; - case 22: - Illi->SetVisible(false); - Illi->setDeathState(JUST_DIED); - return 1000; - break; - case 23: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - return 2000; - break; - case 24: - me->SetTarget(PlayerGUID); - return 5000; - break; - case 25: - Talk(OVERLORD_SAY_6); - return 2000; - break; - case 26: - player->GroupEventHappens(QUEST_LORD_ILLIDAN_STORMRAGE, me); - return 6000; - break; - case 27: - { - Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); - if (Yarzill) - Yarzill->SetTarget(PlayerGUID); - return 500; - } - break; - case 28: - player->RemoveAurasDueToSpell(SPELL_TWO); - player->RemoveAurasDueToSpell(41519); - player->CastSpell(player, SPELL_THREE, true); - player->CastSpell(player, SPELL_FOUR, true); - return 1000; - break; - case 29: - { - if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) - Yarzill->AI()->Talk(YARZILL_THE_MERC_SAY, player->GetGUID()); - return 5000; - } - break; - case 30: - { - if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) - Yarzill->SetTarget(0); - return 5000; - } - break; - case 31: - { - if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) - Yarzill->CastSpell(player, 41540, true); - return 1000; - } - break; - case 32: - me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); return 5000; - break; - case 33: - Reset(); - return 100; - break; - default : - return 0; - break; - } - } - - void UpdateAI(const uint32 diff) - { - if (!ConversationTimer) - return; - - if (ConversationTimer <= diff) - { - if (Event && IllidanGUID && PlayerGUID) - ConversationTimer = NextStep(++Step); - } else ConversationTimer -= diff; - } - }; -}; - -/*#### -# npc_earthmender_wilda -####*/ - -enum eEarthmender -{ - SAY_WIL_START = 0, - SAY_WIL_AGGRO = 1, - SAY_WIL_PROGRESS1 = 2, - SAY_WIL_PROGRESS2 = 3, - SAY_WIL_FIND_EXIT = 4, - SAY_WIL_JUST_AHEAD = 5, - SAY_WIL_END = 6, - - SPELL_CHAIN_LIGHTNING = 16006, - SPELL_EARTHBING_TOTEM = 15786, - SPELL_FROST_SHOCK = 12548, - SPELL_HEALING_WAVE = 12491, - - QUEST_ESCAPE_COILSCAR = 10451, - NPC_COILSKAR_ASSASSIN = 21044, - FACTION_EARTHEN = 1726 //guessed -}; - -class npc_earthmender_wilda : public CreatureScript -{ -public: - npc_earthmender_wilda() : CreatureScript("npc_earthmender_wilda") { } - - bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPE_COILSCAR) - { - creature->AI()->Talk(SAY_WIL_START, player->GetGUID()); - creature->setFaction(FACTION_EARTHEN); - - if (npc_earthmender_wildaAI* pEscortAI = CAST_AI(npc_earthmender_wilda::npc_earthmender_wildaAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID(), quest); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_earthmender_wildaAI(creature); - } - - struct npc_earthmender_wildaAI : public npc_escortAI - { - npc_earthmender_wildaAI(Creature* creature) : npc_escortAI(creature) { } - - uint32 m_uiHealingTimer; - - void Reset() - { - m_uiHealingTimer = 0; - } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 13: - Talk(SAY_WIL_PROGRESS1, player->GetGUID()); - DoSpawnAssassin(); - break; - case 14: - DoSpawnAssassin(); - break; - case 15: - Talk(SAY_WIL_FIND_EXIT, player->GetGUID()); - break; - case 19: - DoRandomSay(); - break; - case 20: - DoSpawnAssassin(); - break; - case 26: - DoRandomSay(); - break; - case 27: - DoSpawnAssassin(); - break; - case 33: - DoRandomSay(); - break; - case 34: - DoSpawnAssassin(); - break; - case 37: - DoRandomSay(); - break; - case 38: - DoSpawnAssassin(); - break; - case 39: - Talk(SAY_WIL_JUST_AHEAD, player->GetGUID()); - break; - case 43: - DoRandomSay(); - break; - case 44: - DoSpawnAssassin(); - break; - case 50: - Talk(SAY_WIL_END, player->GetGUID()); - player->GroupEventHappens(QUEST_ESCAPE_COILSCAR, me); - break; - } - } - - void JustSummoned(Creature* summoned) - { - if (summoned->GetEntry() == NPC_COILSKAR_ASSASSIN) - summoned->AI()->AttackStart(me); - } - - //this is very unclear, random say without no real relevance to script/event - void DoRandomSay() - { - Talk(SAY_WIL_PROGRESS2); - } - - void DoSpawnAssassin() - { - //unknown where they actually appear - DoSummon(NPC_COILSKAR_ASSASSIN, me, 15.0f, 5000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT); - } - - void EnterCombat(Unit* who) - { - //don't always use - if (rand()%5) - return; - - //only aggro text if not player - if (who->GetTypeId() != TYPEID_PLAYER) - { - //appears to be random - if (urand(0, 1)) - Talk(SAY_WIL_AGGRO); - } - } - - void UpdateAI(const uint32 uiDiff) - { - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - //TODO: add more abilities - if (!HealthAbovePct(30)) - { - if (m_uiHealingTimer <= uiDiff) - { - DoCast(me, SPELL_HEALING_WAVE); - m_uiHealingTimer = 15000; - } - else - m_uiHealingTimer -= uiDiff; - } - } - }; -}; - -/*##### -# Quest: Battle of the crimson watch -#####*/ - -/* ContentData -Battle of the crimson watch - creatures, gameobjects and defines -mob_illidari_spawn : Adds that are summoned in the Crimson Watch battle. -mob_torloth_the_magnificent : Final Creature that players have to face before quest is completed -npc_lord_illidan_stormrage : Creature that controls the event. -go_crystal_prison : GameObject that begins the event and hands out quest -EndContentData */ - -#define QUEST_BATTLE_OF_THE_CRIMSON_WATCH 10781 -#define EVENT_AREA_RADIUS 65 //65yds -#define EVENT_COOLDOWN 30000 //in ms. appear after event completed or failed (should be = Adds despawn time) - -struct TorlothCinematic -{ - uint32 creature, Timer; -}; - -// Creature 0 - Torloth, 1 - Illidan -static TorlothCinematic TorlothAnim[]= -{ - {0, 2000}, - {1, 7000}, - {0, 3000}, - {0, 2000}, // Torloth stand - {0, 1000}, - {0, 3000}, - {0, 0} -}; - -struct Location -{ - float x, y, z, o; -}; - -//Cordinates for Spawns -static Location SpawnLocation[]= -{ - //Cords used for: - {-4615.8556f, 1342.2532f, 139.9f, 1.612f}, //Illidari Soldier - {-4598.9365f, 1377.3182f, 139.9f, 3.917f}, //Illidari Soldier - {-4598.4697f, 1360.8999f, 139.9f, 2.427f}, //Illidari Soldier - {-4589.3599f, 1369.1061f, 139.9f, 3.165f}, //Illidari Soldier - {-4608.3477f, 1386.0076f, 139.9f, 4.108f}, //Illidari Soldier - {-4633.1889f, 1359.8033f, 139.9f, 0.949f}, //Illidari Soldier - {-4623.5791f, 1351.4574f, 139.9f, 0.971f}, //Illidari Soldier - {-4607.2988f, 1351.6099f, 139.9f, 2.416f}, //Illidari Soldier - {-4633.7764f, 1376.0417f, 139.9f, 5.608f}, //Illidari Soldier - {-4600.2461f, 1369.1240f, 139.9f, 3.056f}, //Illidari Mind Breaker - {-4631.7808f, 1367.9459f, 139.9f, 0.020f}, //Illidari Mind Breaker - {-4600.2461f, 1369.1240f, 139.9f, 3.056f}, //Illidari Highlord - {-4631.7808f, 1367.9459f, 139.9f, 0.020f}, //Illidari Highlord - {-4615.5586f, 1353.0031f, 139.9f, 1.540f}, //Illidari Highlord - {-4616.4736f, 1384.2170f, 139.9f, 4.971f}, //Illidari Highlord - {-4627.1240f, 1378.8752f, 139.9f, 2.544f} //Torloth The Magnificent -}; - -struct WaveData -{ - uint8 SpawnCount, UsedSpawnPoint; - uint32 CreatureId, SpawnTimer, YellTimer; -}; - -static WaveData WavesInfo[]= -{ - {9, 0, 22075, 10000, 7000}, //Illidari Soldier - {2, 9, 22074, 10000, 7000}, //Illidari Mind Breaker - {4, 11, 19797, 10000, 7000}, //Illidari Highlord - {1, 15, 22076, 10000, 7000} //Torloth The Magnificent -}; - -struct SpawnSpells -{ - uint32 Timer1, Timer2, SpellId; -}; - -static SpawnSpells SpawnCast[]= -{ - {10000, 15000, 35871}, // Illidari Soldier Cast - Spellbreaker - {10000, 10000, 38985}, // Illidari Mind Breake Cast - Focused Bursts - {35000, 35000, 22884}, // Illidari Mind Breake Cast - Psychic Scream - {20000, 20000, 17194}, // Illidari Mind Breake Cast - Mind Blast - {8000, 15000, 38010}, // Illidari Highlord Cast - Curse of Flames - {12000, 20000, 16102}, // Illidari Highlord Cast - Flamestrike - {10000, 15000, 15284}, // Torloth the Magnificent Cast - Cleave - {18000, 20000, 39082}, // Torloth the Magnificent Cast - Shadowfury - {25000, 28000, 33961} // Torloth the Magnificent Cast - Spell Reflection -}; - -/*###### -# mob_torloth_the_magnificent -#####*/ - -class mob_torloth_the_magnificent : public CreatureScript -{ -public: - mob_torloth_the_magnificent() : CreatureScript("mob_torloth_the_magnificent") { } - - CreatureAI* GetAI(Creature* c) const - { - return new mob_torloth_the_magnificentAI(c); - } - - struct mob_torloth_the_magnificentAI : public ScriptedAI - { - mob_torloth_the_magnificentAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 AnimationTimer, SpellTimer1, SpellTimer2, SpellTimer3; - - uint8 AnimationCount; - - uint64 LordIllidanGUID; - uint64 AggroTargetGUID; - - bool Timers; - - void Reset() - { - AnimationTimer = 4000; - AnimationCount = 0; - LordIllidanGUID = 0; - AggroTargetGUID = 0; - Timers = false; - - me->AddUnitState(UNIT_STATE_ROOT); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetTarget(0); - } - - void EnterCombat(Unit* /*who*/){} - - void HandleAnimation() - { - Creature* creature = me; - - if (TorlothAnim[AnimationCount].creature == 1) - { - creature = (Unit::GetCreature(*me, LordIllidanGUID)); - - if (!creature) - return; - } - - AnimationTimer = TorlothAnim[AnimationCount].Timer; - - switch (AnimationCount) - { - case 0: - me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); - break; - case 3: - me->RemoveFlag(UNIT_FIELD_BYTES_1, 8); - break; - case 5: - if (Player* AggroTarget = (Unit::GetPlayer(*me, AggroTargetGUID))) - { - me->SetTarget(AggroTarget->GetGUID()); - me->AddThreat(AggroTarget, 1); - me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); - } - break; - case 6: - if (Player* AggroTarget = (Unit::GetPlayer(*me, AggroTargetGUID))) - { - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->ClearUnitState(UNIT_STATE_ROOT); - - float x, y, z; - AggroTarget->GetPosition(x, y, z); - me->GetMotionMaster()->MovePoint(0, x, y, z); - } - break; - } - ++AnimationCount; - } - - void UpdateAI(const uint32 diff) - { - if (AnimationTimer) - { - if (AnimationTimer <= diff) - { - HandleAnimation(); - } else AnimationTimer -= diff; - } - - if (AnimationCount < 6) - { - me->CombatStop(); - } else if (!Timers) - { - SpellTimer1 = SpawnCast[6].Timer1; - SpellTimer2 = SpawnCast[7].Timer1; - SpellTimer3 = SpawnCast[8].Timer1; - Timers = true; - } - - if (Timers) - { - if (SpellTimer1 <= diff) - { - DoCast(me->getVictim(), SpawnCast[6].SpellId);//Cleave - SpellTimer1 = SpawnCast[6].Timer2 + (rand()%10 * 1000); - } else SpellTimer1 -= diff; - - if (SpellTimer2 <= diff) - { - DoCast(me->getVictim(), SpawnCast[7].SpellId);//Shadowfury - SpellTimer2 = SpawnCast[7].Timer2 + (rand()%5 * 1000); - } else SpellTimer2 -= diff; - - if (SpellTimer3 <= diff) - { - DoCast(me, SpawnCast[8].SpellId); - SpellTimer3 = SpawnCast[8].Timer2 + (rand()%7 * 1000);//Spell Reflection - } else SpellTimer3 -= diff; - } - - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* killer) - { - switch (killer->GetTypeId()) - { - case TYPEID_UNIT: - if (Unit* owner = killer->GetOwner()) - if (owner->GetTypeId() == TYPEID_PLAYER) - CAST_PLR(owner)->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, me); - break; - case TYPEID_PLAYER: - CAST_PLR(killer)->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, me); - break; - default: - break; - } - - if (Creature* LordIllidan = (Unit::GetCreature(*me, LordIllidanGUID))) - { - LordIllidan->AI()->EnterEvadeMode(); - } - } - }; -}; - -/*##### -# npc_lord_illidan_stormrage -#####*/ - -class npc_lord_illidan_stormrage : public CreatureScript -{ -public: - npc_lord_illidan_stormrage() : CreatureScript("npc_lord_illidan_stormrage") { } - - CreatureAI* GetAI(Creature* c) const - { - return new npc_lord_illidan_stormrageAI(c); - } - - struct npc_lord_illidan_stormrageAI : public ScriptedAI - { - npc_lord_illidan_stormrageAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 PlayerGUID; - - uint32 WaveTimer; - uint32 AnnounceTimer; - - int8 LiveCount; - uint8 WaveCount; - - bool EventStarted; - bool Announced; - bool Failed; - - void Reset() - { - PlayerGUID = 0; - - WaveTimer = 10000; - AnnounceTimer = 7000; - LiveCount = 0; - WaveCount = 0; - - EventStarted = false; - Announced = false; - Failed = false; - - me->SetVisible(false); - } - - void EnterCombat(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - void AttackStart(Unit* /*who*/) {} - - void SummonNextWave(); - - void CheckEventFail() - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - - if (!player) - return; - - if (Group* EventGroup = player->GetGroup()) - { - Player* GroupMember; - - uint8 GroupMemberCount = 0; - uint8 DeadMemberCount = 0; - uint8 FailedMemberCount = 0; - - const Group::MemberSlotList members = EventGroup->GetMemberSlots(); - - for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) - { - GroupMember = (Unit::GetPlayer(*me, itr->guid)); - if (!GroupMember) - continue; - if (!GroupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && GroupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE) - { - GroupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH); - ++FailedMemberCount; - } - ++GroupMemberCount; - - if (GroupMember->isDead()) - { - ++DeadMemberCount; - } - } - - if (GroupMemberCount == FailedMemberCount) - { - Failed = true; - } - - if (GroupMemberCount == DeadMemberCount) - { - for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) - { - GroupMember = Unit::GetPlayer(*me, itr->guid); - - if (GroupMember && GroupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE) - { - GroupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH); - } - } - Failed = true; - } - } else if (player->isDead() || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS)) - { - player->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH); - Failed = true; - } - } - - void LiveCounter() - { - --LiveCount; - if (!LiveCount) - Announced = false; - } - - void UpdateAI(const uint32 diff) - { - if (!PlayerGUID || !EventStarted) - return; - - if (!LiveCount && WaveCount < 4) - { - if (!Announced && AnnounceTimer <= diff) - { - Announced = true; - } - else - AnnounceTimer -= diff; - - if (WaveTimer <= diff) - { - SummonNextWave(); - } - else - WaveTimer -= diff; - } - CheckEventFail(); - - if (Failed) - EnterEvadeMode(); - } - }; -}; - -/*###### -# mob_illidari_spawn -######*/ - -class mob_illidari_spawn : public CreatureScript -{ -public: - mob_illidari_spawn() : CreatureScript("mob_illidari_spawn") { } - - CreatureAI* GetAI(Creature* c) const - { - return new mob_illidari_spawnAI(c); - } - - struct mob_illidari_spawnAI : public ScriptedAI - { - mob_illidari_spawnAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 LordIllidanGUID; - uint32 SpellTimer1, SpellTimer2, SpellTimer3; - bool Timers; - - void Reset() - { - LordIllidanGUID = 0; - Timers = false; - } - - void EnterCombat(Unit* /*who*/) {} - - void JustDied(Unit* /*killer*/) - { - me->RemoveCorpse(); - if (Creature* LordIllidan = (Unit::GetCreature(*me, LordIllidanGUID))) - if (LordIllidan) - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, LordIllidan->AI())->LiveCounter(); - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (!Timers) - { - if (me->GetEntry() == 22075)//Illidari Soldier - { - SpellTimer1 = SpawnCast[0].Timer1 + (rand()%4 * 1000); - } - if (me->GetEntry() == 22074)//Illidari Mind Breaker - { - SpellTimer1 = SpawnCast[1].Timer1 + (rand()%10 * 1000); - SpellTimer2 = SpawnCast[2].Timer1 + (rand()%4 * 1000); - SpellTimer3 = SpawnCast[3].Timer1 + (rand()%4 * 1000); - } - if (me->GetEntry() == 19797)// Illidari Highlord - { - SpellTimer1 = SpawnCast[4].Timer1 + (rand()%4 * 1000); - SpellTimer2 = SpawnCast[5].Timer1 + (rand()%4 * 1000); - } - Timers = true; - } - //Illidari Soldier - if (me->GetEntry() == 22075) - { - if (SpellTimer1 <= diff) - { - DoCast(me->getVictim(), SpawnCast[0].SpellId);//Spellbreaker - SpellTimer1 = SpawnCast[0].Timer2 + (rand()%5 * 1000); - } else SpellTimer1 -= diff; - } - //Illidari Mind Breaker - if (me->GetEntry() == 22074) - { - if (SpellTimer1 <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (target->GetTypeId() == TYPEID_PLAYER) - { - DoCast(target, SpawnCast[1].SpellId); //Focused Bursts - SpellTimer1 = SpawnCast[1].Timer2 + (rand()%5 * 1000); - } else SpellTimer1 = 2000; - } - } else SpellTimer1 -= diff; - - if (SpellTimer2 <= diff) - { - DoCast(me->getVictim(), SpawnCast[2].SpellId);//Psychic Scream - SpellTimer2 = SpawnCast[2].Timer2 + (rand()%13 * 1000); - } else SpellTimer2 -= diff; - - if (SpellTimer3 <= diff) - { - DoCast(me->getVictim(), SpawnCast[3].SpellId);//Mind Blast - SpellTimer3 = SpawnCast[3].Timer2 + (rand()%8 * 1000); - } else SpellTimer3 -= diff; - } - //Illidari Highlord - if (me->GetEntry() == 19797) - { - if (SpellTimer1 <= diff) - { - DoCast(me->getVictim(), SpawnCast[4].SpellId);//Curse Of Flames - SpellTimer1 = SpawnCast[4].Timer2 + (rand()%10 * 1000); - } else SpellTimer1 -= diff; - - if (SpellTimer2 <= diff) - { - DoCast(me->getVictim(), SpawnCast[5].SpellId);//Flamestrike - SpellTimer2 = SpawnCast[5].Timer2 + (rand()%7 * 13000); - } else SpellTimer2 -= diff; - } - - DoMeleeAttackIfReady(); - } - }; -}; - -void npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI::SummonNextWave() -{ - uint8 count = WavesInfo[WaveCount].SpawnCount; - uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; - uint8 FelguardCount = 0; - uint8 DreadlordCount = 0; - - for (uint8 i = 0; i < count; ++i) - { - Creature* Spawn = NULL; - float X = SpawnLocation[locIndex + i].x; - float Y = SpawnLocation[locIndex + i].y; - float Z = SpawnLocation[locIndex + i].z; - float O = SpawnLocation[locIndex + i].o; - Spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, X, Y, Z, O, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); - ++LiveCount; - - if (Spawn) - { - Spawn->LoadCreaturesAddon(); - - if (WaveCount == 0)//1 Wave - { - if (rand()%3 == 1 && FelguardCount<2) - { - Spawn->SetDisplayId(18654); - ++FelguardCount; - } - else if (DreadlordCount < 3) - { - Spawn->SetDisplayId(19991); - ++DreadlordCount; - } - else if (FelguardCount<2) - { - Spawn->SetDisplayId(18654); - ++FelguardCount; - } - } - - if (WaveCount < 3)//1-3 Wave - { - if (PlayerGUID) - { - if (Player* target = Unit::GetPlayer(*me, PlayerGUID)) - { - float x, y, z; - target->GetPosition(x, y, z); - Spawn->GetMotionMaster()->MovePoint(0, x, y, z); - } - } - CAST_AI(mob_illidari_spawn::mob_illidari_spawnAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); - } - - if (WavesInfo[WaveCount].CreatureId == 22076) // Torloth - { - CAST_AI(mob_torloth_the_magnificent::mob_torloth_the_magnificentAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); - if (PlayerGUID) - CAST_AI(mob_torloth_the_magnificent::mob_torloth_the_magnificentAI, Spawn->AI())->AggroTargetGUID = PlayerGUID; - } - } - } - ++WaveCount; - WaveTimer = WavesInfo[WaveCount].SpawnTimer; - AnnounceTimer = WavesInfo[WaveCount].YellTimer; -} - -/*##### -# go_crystal_prison -######*/ - -class go_crystal_prison : public GameObjectScript -{ -public: - go_crystal_prison() : GameObjectScript("go_crystal_prison") { } - - bool OnQuestAccept(Player* player, GameObject* /*go*/, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_BATTLE_OF_THE_CRIMSON_WATCH) - { - Creature* Illidan = player->FindNearestCreature(22083, 50); - - if (Illidan && !CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted) - { - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->PlayerGUID = player->GetGUID(); - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->LiveCount = 0; - CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted=true; - } - } - return true; - } -}; - -/*#### -# npc_enraged_spirits -####*/ - -/* QUESTS */ -#define QUEST_ENRAGED_SPIRITS_FIRE_EARTH 10458 -#define QUEST_ENRAGED_SPIRITS_AIR 10481 -#define QUEST_ENRAGED_SPIRITS_WATER 10480 - -/* Totem */ -#define ENTRY_TOTEM_OF_SPIRITS 21071 -#define RADIUS_TOTEM_OF_SPIRITS 15 - -/* SPIRITS */ -#define ENTRY_ENRAGED_EARTH_SPIRIT 21050 -#define ENTRY_ENRAGED_FIRE_SPIRIT 21061 -#define ENTRY_ENRAGED_AIR_SPIRIT 21060 -#define ENTRY_ENRAGED_WATER_SPIRIT 21059 - -/* SOULS */ -#define ENTRY_EARTHEN_SOUL 21073 -#define ENTRY_FIERY_SOUL 21097 -#define ENTRY_ENRAGED_AIRY_SOUL 21116 -#define ENTRY_ENRAGED_WATERY_SOUL 21109 // wrong model - -/* SPELL KILLCREDIT - not working!?! - using KilledMonsterCredit */ -#define SPELL_EARTHEN_SOUL_CAPTURED_CREDIT 36108 -#define SPELL_FIERY_SOUL_CAPTURED_CREDIT 36117 -#define SPELL_AIRY_SOUL_CAPTURED_CREDIT 36182 -#define SPELL_WATERY_SOUL_CAPTURED_CREDIT 36171 - -/* KilledMonsterCredit Workaround */ -#define CREDIT_FIRE 21094 -#define CREDIT_WATER 21095 -#define CREDIT_AIR 21096 -#define CREDIT_EARTH 21092 - -/* Captured Spell/Buff */ -#define SPELL_SOUL_CAPTURED 36115 - -/* Factions */ -#define ENRAGED_SOUL_FRIENDLY 35 -#define ENRAGED_SOUL_HOSTILE 14 - -class npc_enraged_spirit : public CreatureScript -{ -public: - npc_enraged_spirit() : CreatureScript("npc_enraged_spirit") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_enraged_spiritAI(creature); - } - - struct npc_enraged_spiritAI : public ScriptedAI - { - npc_enraged_spiritAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() { } - - void EnterCombat(Unit* /*who*/){} - - void JustDied(Unit* /*killer*/) - { - // always spawn spirit on death - // if totem around - // move spirit to totem and cast kill count - uint32 entry = 0; - uint32 credit = 0; - - switch (me->GetEntry()) - { - case ENTRY_ENRAGED_FIRE_SPIRIT: - entry = ENTRY_FIERY_SOUL; - //credit = SPELL_FIERY_SOUL_CAPTURED_CREDIT; - credit = CREDIT_FIRE; - break; - case ENTRY_ENRAGED_EARTH_SPIRIT: - entry = ENTRY_EARTHEN_SOUL; - //credit = SPELL_EARTHEN_SOUL_CAPTURED_CREDIT; - credit = CREDIT_EARTH; - break; - case ENTRY_ENRAGED_AIR_SPIRIT: - entry = ENTRY_ENRAGED_AIRY_SOUL; - //credit = SPELL_AIRY_SOUL_CAPTURED_CREDIT; - credit = CREDIT_AIR; - break; - case ENTRY_ENRAGED_WATER_SPIRIT: - entry = ENTRY_ENRAGED_WATERY_SOUL; - //credit = SPELL_WATERY_SOUL_CAPTURED_CREDIT; - credit = CREDIT_WATER; - break; - } - - // Spawn Soul on Kill ALWAYS! - Creature* Summoned = NULL; - Unit* totemOspirits = NULL; - - if (entry != 0) - Summoned = DoSpawnCreature(entry, 0, 0, 1, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); - - // FIND TOTEM, PROCESS QUEST - if (Summoned) - { - totemOspirits = me->FindNearestCreature(ENTRY_TOTEM_OF_SPIRITS, RADIUS_TOTEM_OF_SPIRITS); - if (totemOspirits) - { - Summoned->setFaction(ENRAGED_SOUL_FRIENDLY); - Summoned->GetMotionMaster()->MovePoint(0, totemOspirits->GetPositionX(), totemOspirits->GetPositionY(), Summoned->GetPositionZ()); - - Unit* Owner = totemOspirits->GetOwner(); - if (Owner && Owner->GetTypeId() == TYPEID_PLAYER) - // DoCast(Owner, credit); -- not working! - CAST_PLR(Owner)->KilledMonsterCredit(credit, 0); - DoCast(totemOspirits, SPELL_SOUL_CAPTURED); - } - } - } - }; -}; - -enum ZuluhedChains -{ - QUEST_ZULUHED = 10866, - NPC_KARYNAKU = 22112, -}; - -class spell_unlocking_zuluheds_chains : public SpellScriptLoader -{ - public: - spell_unlocking_zuluheds_chains() : SpellScriptLoader("spell_unlocking_zuluheds_chains") { } - - class spell_unlocking_zuluheds_chains_SpellScript : public SpellScript - { - PrepareSpellScript(spell_unlocking_zuluheds_chains_SpellScript); - - bool Load() - { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; - } - - void HandleAfterHit() - { - Player* caster = GetCaster()->ToPlayer(); - if (caster->GetQuestStatus(QUEST_ZULUHED) == QUEST_STATUS_INCOMPLETE) - caster->KilledMonsterCredit(NPC_KARYNAKU, 0); - } - - void Register() - { - AfterHit += SpellHitFn(spell_unlocking_zuluheds_chains_SpellScript::HandleAfterHit); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_unlocking_zuluheds_chains_SpellScript(); - } -}; - -enum ShadowMoonTuberEnum -{ - SPELL_WHISTLE = 36652, - SPELL_SHADOWMOON_TUBER = 36462, - - NPC_BOAR_ENTRY = 21195, - GO_SHADOWMOON_TUBER_MOUND = 184701, - - POINT_TUBER = 1, - TYPE_BOAR = 1, - DATA_BOAR = 1 -}; - -class npc_shadowmoon_tuber_node : public CreatureScript -{ -public: - npc_shadowmoon_tuber_node() : CreatureScript("npc_shadowmoon_tuber_node") {} - - struct npc_shadowmoon_tuber_nodeAI : public ScriptedAI - { - npc_shadowmoon_tuber_nodeAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() - { - tapped = false; - tuberGUID = 0; - resetTimer = 60000; - } - - void SetData(uint32 id, uint32 data) - { - if (id == TYPE_BOAR && data == DATA_BOAR) - { - // Spawn chest GO - DoCast(SPELL_SHADOWMOON_TUBER); - - // Despawn the tuber - if (GameObject* tuber = me->FindNearestGameObject(GO_SHADOWMOON_TUBER_MOUND, 5.0f)) - { - tuberGUID = tuber->GetGUID(); - // @Workaround: find how to properly despawn the GO - tuber->SetPhaseMask(2, true); - } - } - } - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) - { - if (!tapped && spell->Id == SPELL_WHISTLE) - { - if (Creature* boar = me->FindNearestCreature(NPC_BOAR_ENTRY, 30.0f)) - { - // Disable trigger and force nearest boar to walk to him - tapped = true; - boar->SetWalk(false); - boar->GetMotionMaster()->MovePoint(POINT_TUBER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); - } - } - } - - void UpdateAI(const uint32 diff) - { - if (tapped) - { - if (resetTimer <= diff) - { - // Respawn the tuber - if (tuberGUID) - if (GameObject* tuber = GameObject::GetGameObject(*me, tuberGUID)) - // @Workaround: find how to properly respawn the GO - tuber->SetPhaseMask(1, true); - - Reset(); - } - else - resetTimer -= diff; - } - } - private: - bool tapped; - uint64 tuberGUID; - uint32 resetTimer; - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_shadowmoon_tuber_nodeAI(creature); - } -}; - -void AddSC_shadowmoon_valley() -{ - new mob_mature_netherwing_drake(); - new mob_enslaved_netherwing_drake(); - new mob_dragonmaw_peon(); - new npc_drake_dealer_hurlunk(); - new npcs_flanis_swiftwing_and_kagrosh(); - new npc_murkblood_overseer(); - new npc_karynaku(); - new npc_oronok_tornheart(); - new npc_overlord_morghor(); - new npc_earthmender_wilda(); - new npc_lord_illidan_stormrage(); - new go_crystal_prison(); - new mob_illidari_spawn(); - new mob_torloth_the_magnificent(); - new npc_enraged_spirit(); - new spell_unlocking_zuluheds_chains(); - new npc_shadowmoon_tuber_node(); -} diff --git a/src/server/scripts/Outland/shattrath_city.cpp b/src/server/scripts/Outland/shattrath_city.cpp deleted file mode 100644 index ac26614ae69..00000000000 --- a/src/server/scripts/Outland/shattrath_city.cpp +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Shattrath_City -SD%Complete: 100 -SDComment: Quest support: 10004, 10009, 10211, 10231. Flask vendors, Teleport to Caverns of Time -SDCategory: Shattrath City -EndScriptData */ - -/* ContentData -npc_raliq_the_drunk -npc_salsalabim -npc_shattrathflaskvendors -npc_zephyr -npc_kservant -npc_dirty_larry -npc_ishanah -npc_khadgar -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npc_raliq_the_drunk -######*/ - -#define GOSSIP_RALIQ "You owe Sim'salabim money. Hand them over or die!" - -enum eRaliq -{ - SPELL_UPPERCUT = 10966, - QUEST_CRACK_SKULLS = 10009, - FACTION_HOSTILE_RD = 45 -}; - -class npc_raliq_the_drunk : public CreatureScript -{ -public: - npc_raliq_the_drunk() : CreatureScript("npc_raliq_the_drunk") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_RD); - creature->AI()->AttackStart(player); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_RALIQ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(9440, creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_raliq_the_drunkAI (creature); - } - - struct npc_raliq_the_drunkAI : public ScriptedAI - { - npc_raliq_the_drunkAI(Creature* creature) : ScriptedAI(creature) - { - m_uiNormFaction = creature->getFaction(); - } - - uint32 m_uiNormFaction; - uint32 Uppercut_Timer; - - void Reset() - { - Uppercut_Timer = 5000; - me->RestoreFaction(); - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (Uppercut_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_UPPERCUT); - Uppercut_Timer = 15000; - } else Uppercut_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -# npc_salsalabim -######*/ - -#define FACTION_HOSTILE_SA 90 -#define FACTION_FRIENDLY_SA 35 -#define QUEST_10004 10004 - -#define SPELL_MAGNETIC_PULL 31705 - -class npc_salsalabim : public CreatureScript -{ -public: - npc_salsalabim() : CreatureScript("npc_salsalabim") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_10004) == QUEST_STATUS_INCOMPLETE) - { - creature->setFaction(FACTION_HOSTILE_SA); - creature->AI()->AttackStart(player); - } - else - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_salsalabimAI (creature); - } - - struct npc_salsalabimAI : public ScriptedAI - { - npc_salsalabimAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 MagneticPull_Timer; - - void Reset() - { - MagneticPull_Timer = 15000; - me->RestoreFaction(); - } - - void DamageTaken(Unit* done_by, uint32 &damage) - { - if (done_by->GetTypeId() == TYPEID_PLAYER) - if (me->HealthBelowPctDamaged(20, damage)) - { - CAST_PLR(done_by)->GroupEventHappens(QUEST_10004, me); - damage = 0; - EnterEvadeMode(); - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (MagneticPull_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_MAGNETIC_PULL); - MagneticPull_Timer = 15000; - } else MagneticPull_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/* -################################################## -Shattrath City Flask Vendors provides flasks to people exalted with 3 fActions: -Haldor the Compulsive -Arcanist Xorith -Both sell special flasks for use in Outlands 25man raids only, -purchasable for one Mark of Illidari each -Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and The Sha'tar -################################################## -*/ - -class npc_shattrathflaskvendors : public CreatureScript -{ -public: - npc_shattrathflaskvendors() : CreatureScript("npc_shattrathflaskvendors") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->GetEntry() == 23484) - { - // Aldor vendor - if (creature->isVendor() && (player->GetReputationRank(932) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); - } - else - { - player->SEND_GOSSIP_MENU(11083, creature->GetGUID()); - } - } - - if (creature->GetEntry() == 23483) - { - // Scryers vendor - if (creature->isVendor() && (player->GetReputationRank(934) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); - } - else - { - player->SEND_GOSSIP_MENU(11084, creature->GetGUID()); - } - } - - return true; - } -}; - -/*###### -# npc_zephyr -######*/ - -#define GOSSIP_HZ "Take me to the Caverns of Time." - -class npc_zephyr : public CreatureScript -{ -public: - npc_zephyr() : CreatureScript("npc_zephyr") { } - - bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - player->CastSpell(player, 37778, false); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetReputationRank(989) >= REP_REVERED) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HZ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -# npc_kservant -######*/ - -enum KServant -{ - SAY1 = 0, - WHISP1 = 1, - WHISP2 = 2, - WHISP3 = 3, - WHISP4 = 4, - WHISP5 = 5, - WHISP6 = 6, - WHISP7 = 7, - WHISP8 = 8, - WHISP9 = 9, - WHISP10 = 10, - WHISP11 = 11, - WHISP12 = 12, - WHISP13 = 13, - WHISP14 = 14, - WHISP15 = 15, - WHISP16 = 16, - WHISP17 = 17, - WHISP18 = 18, - WHISP19 = 19, - WHISP20 = 20, - WHISP21 = 21 -}; - -class npc_kservant : public CreatureScript -{ -public: - npc_kservant() : CreatureScript("npc_kservant") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kservantAI(creature); - } - - struct npc_kservantAI : public npc_escortAI - { - public: - npc_kservantAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 0: - Talk(SAY1, player->GetGUID()); - break; - case 4: - Talk(WHISP1, player->GetGUID()); - break; - case 6: - Talk(WHISP2, player->GetGUID()); - break; - case 7: - Talk(WHISP3, player->GetGUID()); - break; - case 8: - Talk(WHISP4, player->GetGUID()); - break; - case 17: - Talk(WHISP5, player->GetGUID()); - break; - case 18: - Talk(WHISP6, player->GetGUID()); - break; - case 19: - Talk(WHISP7, player->GetGUID()); - break; - case 33: - Talk(WHISP8, player->GetGUID()); - break; - case 34: - Talk(WHISP9, player->GetGUID()); - break; - case 35: - Talk(WHISP10, player->GetGUID()); - break; - case 36: - Talk(WHISP11, player->GetGUID()); - break; - case 43: - Talk(WHISP12, player->GetGUID()); - break; - case 44: - Talk(WHISP13, player->GetGUID()); - break; - case 49: - Talk(WHISP14, player->GetGUID()); - break; - case 50: - Talk(WHISP15, player->GetGUID()); - break; - case 51: - Talk(WHISP16, player->GetGUID()); - break; - case 52: - Talk(WHISP17, player->GetGUID()); - break; - case 53: - Talk(WHISP18, player->GetGUID()); - break; - case 54: - Talk(WHISP19, player->GetGUID()); - break; - case 55: - Talk(WHISP20, player->GetGUID()); - break; - case 56: - Talk(WHISP21, player->GetGUID()); - player->GroupEventHappens(10211, me); - break; - } - } - - void MoveInLineOfSight(Unit* who) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - return; - - if (who->GetTypeId() == TYPEID_PLAYER) - { - if (CAST_PLR(who)->GetQuestStatus(10211) == QUEST_STATUS_INCOMPLETE) - { - float Radius = 10.0f; - if (me->IsWithinDistInMap(who, Radius)) - { - Start(false, false, who->GetGUID()); - } - } - } - } - - void Reset() {} - }; -}; - -/*###### -# npc_dirty_larry -######*/ - -#define GOSSIP_BOOK "Ezekiel said that you might have a certain book..." - -enum DirtyLarry -{ - SAY_1 = 0, - SAY_2 = 1, - SAY_3 = 2, - SAY_4 = 3, - SAY_5 = 4, - SAY_GIVEUP = 5, - - QUEST_WBI = 10231, - NPC_CREEPJACK = 19726, - NPC_MALONE = 19725 -}; - -class npc_dirty_larry : public CreatureScript -{ -public: - npc_dirty_larry() : CreatureScript("npc_dirty_larry") { } - - struct npc_dirty_larryAI : public ScriptedAI - { - npc_dirty_larryAI(Creature* creature) : ScriptedAI(creature) {} - - bool Event; - bool Attack; - bool Done; - - uint64 PlayerGUID; - - uint32 SayTimer; - uint32 Step; - - void Reset() - { - Event = false; - Attack = false; - Done = false; - - PlayerGUID = 0; - SayTimer = 0; - Step = 0; - - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->setFaction(1194); - Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); - if (Creepjack) - { - CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); - Creepjack->setFaction(1194); - Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); - if (Malone) - { - CAST_CRE(Malone)->AI()->EnterEvadeMode(); - Malone->setFaction(1194); - Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - } - - uint32 NextStep(uint32 Step) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - - switch (Step) - { - case 0:{ me->SetInFront(player); - Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); - if (Creepjack) - Creepjack->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); - if (Malone) - Malone->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }return 2000; - case 1: Talk(SAY_1, player->GetGUID()); return 3000; - case 2: Talk(SAY_2, player->GetGUID()); return 5000; - case 3: Talk(SAY_3, player->GetGUID()); return 2000; - case 4: Talk(SAY_4, player->GetGUID()); return 2000; - case 5: Talk(SAY_5, player->GetGUID()); return 2000; - case 6: Attack = true; return 2000; - default: return 0; - } - } - - void EnterCombat(Unit* /*who*/){} - - void UpdateAI(const uint32 diff) - { - if (SayTimer <= diff) - { - if (Event) - SayTimer = NextStep(++Step); - } else SayTimer -= diff; - - if (Attack) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - me->setFaction(14); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - if (player) - { - Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); - if (Creepjack) - { - Creepjack->Attack(player, true); - Creepjack->setFaction(14); - Creepjack->GetMotionMaster()->MoveChase(player); - Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); - if (Malone) - { - Malone->Attack(player, true); - Malone->setFaction(14); - Malone->GetMotionMaster()->MoveChase(player); - Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - DoStartMovement(player); - AttackStart(player); - } - Attack = false; - } - - if (HealthBelowPct(5) && !Done) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->RemoveAllAuras(); - - Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); - if (Creepjack) - { - CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); - Creepjack->setFaction(1194); - Creepjack->GetMotionMaster()->MoveTargetedHome(); - Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); - if (Malone) - { - CAST_CRE(Malone)->AI()->EnterEvadeMode(); - Malone->setFaction(1194); - Malone->GetMotionMaster()->MoveTargetedHome(); - Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - } - me->setFaction(1194); - Done = true; - Talk(SAY_GIVEUP); - me->DeleteThreatList(); - me->CombatStop(); - me->GetMotionMaster()->MoveTargetedHome(); - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player) - CAST_PLR(player)->GroupEventHappens(QUEST_WBI, me); - } - DoMeleeAttackIfReady(); - } - }; - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - CAST_AI(npc_dirty_larry::npc_dirty_larryAI, creature->AI())->Event = true; - CAST_AI(npc_dirty_larry::npc_dirty_larryAI, creature->AI())->PlayerGUID = player->GetGUID(); - player->CLOSE_GOSSIP_MENU(); - } - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_WBI) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BOOK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_dirty_larryAI (creature); - } -}; - -/*###### -# npc_ishanah -######*/ - -#define ISANAH_GOSSIP_1 "Who are the Sha'tar?" -#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" - -class npc_ishanah : public CreatureScript -{ -public: - npc_ishanah() : CreatureScript("npc_ishanah") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - player->SEND_GOSSIP_MENU(9458, creature->GetGUID()); - else if (action == GOSSIP_ACTION_INFO_DEF+2) - player->SEND_GOSSIP_MENU(9459, creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - -/*###### -# npc_khadgar -######*/ - -#define KHADGAR_GOSSIP_1 "I've heard your name spoken only in whispers, mage. Who are you?" -#define KHADGAR_GOSSIP_2 "Go on, please." -#define KHADGAR_GOSSIP_3 "I see." //6th too this -#define KHADGAR_GOSSIP_4 "What did you do then?" -#define KHADGAR_GOSSIP_5 "What happened next?" -#define KHADGAR_GOSSIP_7 "There was something else I wanted to ask you." - -class npc_khadgar : public CreatureScript -{ -public: - npc_khadgar() : CreatureScript("npc_khadgar") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - player->SEND_GOSSIP_MENU(9876, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); - player->SEND_GOSSIP_MENU(9877, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+3: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); - player->SEND_GOSSIP_MENU(9878, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+4: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); - player->SEND_GOSSIP_MENU(9879, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+5: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); - player->SEND_GOSSIP_MENU(9880, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+6: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); - player->SEND_GOSSIP_MENU(9881, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF+7: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); - break; - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (!player->hasQuest(10211)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); - - return true; - } -}; - -void AddSC_shattrath_city() -{ - new npc_raliq_the_drunk(); - new npc_salsalabim(); - new npc_shattrathflaskvendors(); - new npc_zephyr(); - new npc_kservant(); - new npc_dirty_larry(); - new npc_ishanah(); - new npc_khadgar(); -} diff --git a/src/server/scripts/Outland/terokkar_forest.cpp b/src/server/scripts/Outland/terokkar_forest.cpp deleted file mode 100644 index 2b046a7518e..00000000000 --- a/src/server/scripts/Outland/terokkar_forest.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Terokkar_Forest -SD%Complete: 85 -SDComment: Quest support: 9889, 10009, 10873, 10896, 10898, 11096, 10052, 10051. Skettis->Ogri'la Flight -SDCategory: Terokkar Forest -EndScriptData */ - -/* ContentData -mob_unkor_the_ruthless -mob_infested_root_walker -mob_rotting_forest_rager -mob_netherweb_victim -npc_floon -npc_isla_starmane -npc_slim -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Group.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## mob_unkor_the_ruthless -######*/ - -enum UnkorTheRuthless -{ - SAY_SUBMIT = 0, - - FACTION_HOSTILE = 45, - FACTION_FRIENDLY = 35, - QUEST_DONTKILLTHEFATONE = 9889, - - SPELL_PULVERIZE = 2676 -}; - -class mob_unkor_the_ruthless : public CreatureScript -{ -public: - mob_unkor_the_ruthless() : CreatureScript("mob_unkor_the_ruthless") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_unkor_the_ruthlessAI (creature); - } - - struct mob_unkor_the_ruthlessAI : public ScriptedAI - { - mob_unkor_the_ruthlessAI(Creature* creature) : ScriptedAI(creature) {} - - bool CanDoQuest; - uint32 UnkorUnfriendly_Timer; - uint32 Pulverize_Timer; - - void Reset() - { - CanDoQuest = false; - UnkorUnfriendly_Timer = 0; - Pulverize_Timer = 3000; - me->SetStandState(UNIT_STAND_STATE_STAND); - me->setFaction(FACTION_HOSTILE); - } - - void EnterCombat(Unit* /*who*/) {} - - void DoNice() - { - Talk(SAY_SUBMIT); - me->setFaction(FACTION_FRIENDLY); - me->SetStandState(UNIT_STAND_STATE_SIT); - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(true); - UnkorUnfriendly_Timer = 60000; - } - - void DamageTaken(Unit* done_by, uint32 &damage) - { - if (done_by->GetTypeId() == TYPEID_PLAYER) - if (me->HealthBelowPctDamaged(30, damage)) - { - if (Group* group = CAST_PLR(done_by)->GetGroup()) - { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* groupie = itr->getSource(); - if (groupie && - groupie->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && - groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) - { - groupie->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); - if (!CanDoQuest) - CanDoQuest = true; - } - } - } else - if (CAST_PLR(done_by)->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && - CAST_PLR(done_by)->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) - { - CAST_PLR(done_by)->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); - CanDoQuest = true; - } - } - } - - void UpdateAI(const uint32 diff) - { - if (CanDoQuest) - { - if (!UnkorUnfriendly_Timer) - { - //DoCast(me, SPELL_QUID9889); //not using spell for now - DoNice(); - } - else - { - if (UnkorUnfriendly_Timer <= diff) - { - EnterEvadeMode(); - return; - } else UnkorUnfriendly_Timer -= diff; - } - } - - if (!UpdateVictim()) - return; - - if (Pulverize_Timer <= diff) - { - DoCast(me, SPELL_PULVERIZE); - Pulverize_Timer = 9000; - } else Pulverize_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## mob_infested_root_walker -######*/ - -class mob_infested_root_walker : public CreatureScript -{ -public: - mob_infested_root_walker() : CreatureScript("mob_infested_root_walker") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_infested_root_walkerAI (creature); - } - - struct mob_infested_root_walkerAI : public ScriptedAI - { - mob_infested_root_walkerAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() { } - void EnterCombat(Unit* /*who*/) { } - - void DamageTaken(Unit* done_by, uint32 &damage) - { - if (done_by && done_by->GetTypeId() == TYPEID_PLAYER) - if (me->GetHealth() <= damage) - if (rand()%100 < 75) - //Summon Wood Mites - DoCast(me, 39130, true); - } - }; -}; - -/*###### -## mob_skywing -######*/ -class npc_skywing : public CreatureScript -{ -public: - npc_skywing() : CreatureScript("npc_skywing") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_skywingAI(creature); - } - - struct npc_skywingAI : public npc_escortAI - { - public: - npc_skywingAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 8: - player->AreaExploredOrEventHappens(10898); - break; - } - } - - void EnterCombat(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* who) - { - if (HasEscortState(STATE_ESCORT_ESCORTING)) - return; - - if (who->GetTypeId() == TYPEID_PLAYER) - { - if (CAST_PLR(who)->GetQuestStatus(10898) == QUEST_STATUS_INCOMPLETE) - { - float Radius = 10.0f; - if (me->IsWithinDistInMap(who, Radius)) - { - Start(false, false, who->GetGUID()); - } - } - } - } - - void Reset() {} - - void UpdateAI(const uint32 diff) - { - npc_escortAI::UpdateAI(diff); - } - }; -}; - -/*###### -## mob_rotting_forest_rager -######*/ - -class mob_rotting_forest_rager : public CreatureScript -{ -public: - mob_rotting_forest_rager() : CreatureScript("mob_rotting_forest_rager") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_rotting_forest_ragerAI (creature); - } - - struct mob_rotting_forest_ragerAI : public ScriptedAI - { - mob_rotting_forest_ragerAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() { } - void EnterCombat(Unit* /*who*/) { } - - void DamageTaken(Unit* done_by, uint32 &damage) - { - if (done_by->GetTypeId() == TYPEID_PLAYER) - if (me->GetHealth() <= damage) - if (rand()%100 < 75) - //Summon Lots of Wood Mights - DoCast(me, 39134, true); - } - }; -}; - -/*###### -## mob_netherweb_victim -######*/ - -#define QUEST_TARGET 22459 -//#define SPELL_FREE_WEBBED 38950 - -const uint32 netherwebVictims[6] = -{ - 18470, 16805, 21242, 18452, 22482, 21285 -}; -class mob_netherweb_victim : public CreatureScript -{ -public: - mob_netherweb_victim() : CreatureScript("mob_netherweb_victim") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_netherweb_victimAI (creature); - } - - struct mob_netherweb_victimAI : public ScriptedAI - { - mob_netherweb_victimAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() { } - void EnterCombat(Unit* /*who*/) { } - void MoveInLineOfSight(Unit* /*who*/) { } - - void JustDied(Unit* killer) - { - Player* player = killer->ToPlayer(); - if (!player) - return; - - if (player->GetQuestStatus(10873) == QUEST_STATUS_INCOMPLETE) - { - if (rand()%100 < 25) - { - me->SummonCreature(QUEST_TARGET, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - player->KilledMonsterCredit(QUEST_TARGET, 0); - } - else - me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - - if (rand()%100 < 75) - me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - - me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); - } - } - }; -}; - -/*###### -## npc_floon -######*/ - -#define GOSSIP_FLOON1 "You owe Sim'salabim money. Hand them over or die!" -#define GOSSIP_FLOON2 "Hand over the money or die...again!" - -enum eFloon -{ - SAY_FLOON_ATTACK = 0, - - SPELL_SILENCE = 6726, - SPELL_FROSTBOLT = 9672, - SPELL_FROST_NOVA = 11831, - - FACTION_HOSTILE_FL = 1738, - QUEST_CRACK_SKULLS = 10009 -}; - -class npc_floon : public CreatureScript -{ -public: - npc_floon() : CreatureScript("npc_floon") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(9443, creature->GetGUID()); - } - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_FL); - creature->AI()->Talk(SAY_FLOON_ATTACK, player->GetGUID()); - creature->AI()->AttackStart(player); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(9442, creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_floonAI (creature); - } - - struct npc_floonAI : public ScriptedAI - { - npc_floonAI(Creature* creature) : ScriptedAI(creature) - { - m_uiNormFaction = creature->getFaction(); - } - - uint32 m_uiNormFaction; - uint32 Silence_Timer; - uint32 Frostbolt_Timer; - uint32 FrostNova_Timer; - - void Reset() - { - Silence_Timer = 2000; - Frostbolt_Timer = 4000; - FrostNova_Timer = 9000; - if (me->getFaction() != m_uiNormFaction) - me->setFaction(m_uiNormFaction); - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (Silence_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_SILENCE); - Silence_Timer = 30000; - } else Silence_Timer -= diff; - - if (FrostNova_Timer <= diff) - { - DoCast(me, SPELL_FROST_NOVA); - FrostNova_Timer = 20000; - } else FrostNova_Timer -= diff; - - if (Frostbolt_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_FROSTBOLT); - Frostbolt_Timer = 5000; - } else Frostbolt_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; - -/*###### -## npc_isla_starmane -######*/ -enum eIslaStarmaneData -{ - SAY_PROGRESS_1 = 0, - SAY_PROGRESS_2 = 1, - SAY_PROGRESS_3 = 2, - SAY_PROGRESS_4 = 3, - - QUEST_EFTW_H = 10052, - QUEST_EFTW_A = 10051, - GO_CAGE = 182794, - SPELL_CAT = 32447, -}; - -class npc_isla_starmane : public CreatureScript -{ -public: - npc_isla_starmane() : CreatureScript("npc_isla_starmane") { } - - struct npc_isla_starmaneAI : public npc_escortAI - { - npc_isla_starmaneAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 0: - if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 10)) - Cage->SetGoState(GO_STATE_ACTIVE); - break; - case 2: - Talk(SAY_PROGRESS_1, player->GetGUID()); - break; - case 5: - Talk(SAY_PROGRESS_2, player->GetGUID()); - break; - case 6: - Talk(SAY_PROGRESS_3, player->GetGUID()); - break; - case 29: - Talk(SAY_PROGRESS_4, player->GetGUID()); - if (player->GetTeam() == ALLIANCE) - player->GroupEventHappens(QUEST_EFTW_A, me); - else if (player->GetTeam() == HORDE) - player->GroupEventHappens(QUEST_EFTW_H, me); - me->SetInFront(player); - break; - case 30: - me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); - break; - case 31: - DoCast(me, SPELL_CAT); - me->SetWalk(false); - break; - } - } - - void Reset() - { - me->RestoreFaction(); - } - - void JustDied(Unit* /*killer*/) - { - if (Player* player = GetPlayerForEscort()) - { - if (player->GetTeam() == ALLIANCE) - player->FailQuest(QUEST_EFTW_A); - else if (player->GetTeam() == HORDE) - player->FailQuest(QUEST_EFTW_H); - } - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A) - { - CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); - creature->setFaction(113); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_isla_starmaneAI(creature); - } -}; - -/*###### -## go_skull_pile -######*/ -#define GOSSIP_S_DARKSCREECHER_AKKARAI "Summon Darkscreecher Akkarai" -#define GOSSIP_S_KARROG "Summon Karrog" -#define GOSSIP_S_GEZZARAK_THE_HUNTRESS "Summon Gezzarak the Huntress" -#define GOSSIP_S_VAKKIZ_THE_WINDRAGER "Summon Vakkiz the Windrager" - -class go_skull_pile : public GameObjectScript -{ -public: - go_skull_pile() : GameObjectScript("go_skull_pile") { } - - bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (sender) - { - case GOSSIP_SENDER_MAIN: SendActionMenu(player, go, action); break; - } - return true; - } - - bool OnGossipHello(Player* player, GameObject* go) - { - if ((player->GetQuestStatus(11885) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(11885)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); - } - - player->SEND_GOSSIP_MENU(go->GetGOInfo()->questgiver.gossipID, go->GetGUID()); - return true; - } - - void SendActionMenu(Player* player, GameObject* /*go*/, uint32 action) - { - switch (action) - { - case GOSSIP_ACTION_INFO_DEF + 1: - player->CastSpell(player, 40642, false); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - player->CastSpell(player, 40640, false); - break; - case GOSSIP_ACTION_INFO_DEF + 3: - player->CastSpell(player, 40632, false); - break; - case GOSSIP_ACTION_INFO_DEF + 4: - player->CastSpell(player, 40644, false); - break; - } - } -}; - -/*###### -## npc_slim -######*/ - -enum eSlim -{ - FACTION_CONSORTIUM = 933 -}; - -class npc_slim : public CreatureScript -{ -public: - npc_slim() : CreatureScript("npc_slim") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isVendor() && player->GetReputationRank(FACTION_CONSORTIUM) >= REP_FRIENDLY) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(9896, creature->GetGUID()); - } - else - player->SEND_GOSSIP_MENU(9895, creature->GetGUID()); - - return true; - } -}; - -/*######## -####npc_akuno -#####*/ - -enum eAkuno -{ - QUEST_ESCAPING_THE_TOMB = 10887, - NPC_CABAL_SKRIMISHER = 21661 -}; - -class npc_akuno : public CreatureScript -{ -public: - npc_akuno() : CreatureScript("npc_akuno") { } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPING_THE_TOMB) - { - if (npc_akunoAI* pEscortAI = CAST_AI(npc_akuno::npc_akunoAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID()); - - if (player->GetTeamId() == TEAM_ALLIANCE) - creature->setFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE); - else - creature->setFaction(FACTION_ESCORT_H_NEUTRAL_PASSIVE); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_akunoAI(creature); - } - - struct npc_akunoAI : public npc_escortAI - { - npc_akunoAI(Creature* creature) : npc_escortAI(creature) {} - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 3: - me->SummonCreature(NPC_CABAL_SKRIMISHER, -2795.99f, 5420.33f, -34.53f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - me->SummonCreature(NPC_CABAL_SKRIMISHER, -2793.55f, 5412.79f, -34.53f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); - break; - case 11: - if (player->GetTypeId() == TYPEID_PLAYER) - player->GroupEventHappens(QUEST_ESCAPING_THE_TOMB, me); - break; - } - } - - void JustSummoned(Creature* summon) - { - summon->AI()->AttackStart(me); - } - }; -}; - -void AddSC_terokkar_forest() -{ - new mob_unkor_the_ruthless(); - new mob_infested_root_walker(); - new mob_rotting_forest_rager(); - new mob_netherweb_victim(); - new npc_floon(); - new npc_isla_starmane(); - new go_skull_pile(); - new npc_skywing(); - new npc_slim(); - new npc_akuno(); -} diff --git a/src/server/scripts/Outland/zangarmarsh.cpp b/src/server/scripts/Outland/zangarmarsh.cpp deleted file mode 100644 index 319da372bf8..00000000000 --- a/src/server/scripts/Outland/zangarmarsh.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore - * 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, see . - */ - -/* ScriptData -SDName: Zangarmarsh -SD%Complete: 100 -SDComment: Quest support: 9752, 9785, 9803, 10009. Mark Of ... buffs. -SDCategory: Zangarmarsh -EndScriptData */ - -/* ContentData -npcs_ashyen_and_keleth -npc_cooshcoosh -npc_elder_kuruti -npc_mortog_steamhead -npc_kayra_longmane -npc_timothy_daniels -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "ScriptedEscortAI.h" -#include "Player.h" -#include "WorldSession.h" - -/*###### -## npcs_ashyen_and_keleth -######*/ - -#define GOSSIP_ITEM_BLESS_ASH "Grant me your mark, wise ancient." -#define GOSSIP_ITEM_BLESS_KEL "Grant me your mark, mighty ancient." - -enum AshyenAndKeleth -{ - GOSSIP_REWARD_BLESS = 0, - - NPC_ASHYEN = 17900, - NPC_KELETH = 17901, - - SPELL_BLESS_ASH_EXA = 31815, - SPELL_BLESS_ASH_REV = 31811, - SPELL_BLESS_ASH_HON = 31810, - SPELL_BLESS_ASH_FRI = 31808, - - SPELL_BLESS_KEL_EXA = 31814, - SPELL_BLESS_KEL_REV = 31813, - SPELL_BLESS_KEL_HON = 31812, - SPELL_BLESS_KEL_FRI = 31807 -}; - -class npcs_ashyen_and_keleth : public CreatureScript -{ -public: - npcs_ashyen_and_keleth() : CreatureScript("npcs_ashyen_and_keleth") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetReputationRank(942) > REP_NEUTRAL) - { - if (creature->GetEntry() == NPC_ASHYEN) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BLESS_ASH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - if (creature->GetEntry() == NPC_KELETH) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BLESS_KEL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - } - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - creature->setPowerType(POWER_MANA); - creature->SetMaxPower(POWER_MANA, 200); //set a "fake" mana value, we can't depend on database doing it in this case - creature->SetPower(POWER_MANA, 200); - - if (creature->GetEntry() == NPC_ASHYEN) //check which Creature we are dealing with - { - uint32 spell = 0; - switch (player->GetReputationRank(942)) - { //mark of lore - case REP_FRIENDLY: - spell = SPELL_BLESS_ASH_FRI; - break; - case REP_HONORED: - spell = SPELL_BLESS_ASH_HON; - break; - case REP_REVERED: - spell = SPELL_BLESS_ASH_REV; - break; - case REP_EXALTED: - spell = SPELL_BLESS_ASH_EXA; - break; - default: - break; - } - - if (spell) - { - creature->CastSpell(player, spell, true); - creature->AI()->Talk(GOSSIP_REWARD_BLESS); - } - } - - if (creature->GetEntry() == NPC_KELETH) - { - uint32 spell = 0; - switch (player->GetReputationRank(942)) //mark of war - { - case REP_FRIENDLY: - spell = SPELL_BLESS_KEL_FRI; - break; - case REP_HONORED: - spell = SPELL_BLESS_KEL_HON; - break; - case REP_REVERED: - spell = SPELL_BLESS_KEL_REV; - break; - case REP_EXALTED: - spell = SPELL_BLESS_KEL_EXA; - break; - default: - break; - } - - if (spell) - { - creature->CastSpell(player, spell, true); - creature->AI()->Talk(GOSSIP_REWARD_BLESS); - } - } - player->CLOSE_GOSSIP_MENU(); - player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); - } - return true; - } -}; - -/*###### -## npc_cooshcoosh -######*/ - -#define GOSSIP_COOSH "You owe Sim'salabim money. Hand them over or die!" - -enum eCooshhooosh -{ - SPELL_LIGHTNING_BOLT = 9532, - QUEST_CRACK_SKULLS = 10009, - FACTION_HOSTILE_CO = 45 -}; - -class npc_cooshcoosh : public CreatureScript -{ -public: - npc_cooshcoosh() : CreatureScript("npc_cooshcoosh") { } - - struct npc_cooshcooshAI : public ScriptedAI - { - npc_cooshcooshAI(Creature* creature) : ScriptedAI(creature) - { - m_uiNormFaction = creature->getFaction(); - } - - uint32 m_uiNormFaction; - uint32 LightningBolt_Timer; - - void Reset() - { - LightningBolt_Timer = 2000; - if (me->getFaction() != m_uiNormFaction) - me->setFaction(m_uiNormFaction); - } - - void EnterCombat(Unit* /*who*/) {} - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (LightningBolt_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_LIGHTNING_BOLT); - LightningBolt_Timer = 5000; - } else LightningBolt_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_cooshcooshAI (creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_COOSH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(9441, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF) - { - player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_CO); - creature->AI()->AttackStart(player); - } - return true; - } -}; - -/*###### -## npc_elder_kuruti -######*/ - -#define GOSSIP_ITEM_KUR1 "Greetings, elder. It is time for your people to end their hostility towards the draenei and their allies." -#define GOSSIP_ITEM_KUR2 "I did not mean to deceive you, elder. The draenei of Telredor thought to approach you in a way that would seem familiar to you." -#define GOSSIP_ITEM_KUR3 "I will tell them. Farewell, elder." - -class npc_elder_kuruti : public CreatureScript -{ -public: - npc_elder_kuruti() : CreatureScript("npc_elder_kuruti") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (player->GetQuestStatus(9803) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - - player->SEND_GOSSIP_MENU(9226, creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(9227, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 1: - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); - player->SEND_GOSSIP_MENU(9229, creature->GetGUID()); - break; - case GOSSIP_ACTION_INFO_DEF + 2: - { - if (!player->HasItemCount(24573)) - { - ItemPosCountVec dest; - uint32 itemId = 24573; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, 1, NULL); - if (msg == EQUIP_ERR_OK) - { - player->StoreNewItem(dest, itemId, true); - } - else - player->SendEquipError(msg, NULL, NULL, itemId); - } - player->SEND_GOSSIP_MENU(9231, creature->GetGUID()); - break; - } - } - return true; - } -}; - -/*###### -## npc_mortog_steamhead -######*/ -class npc_mortog_steamhead : public CreatureScript -{ -public: - npc_mortog_steamhead() : CreatureScript("npc_mortog_steamhead") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isVendor() && player->GetReputationRank(942) == REP_EXALTED) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_TRADE) - player->GetSession()->SendListInventory(creature->GetGUID()); - return true; - } -}; - -/*###### -## npc_kayra_longmane -######*/ - -enum eKayra -{ - SAY_START = 0, - SAY_AMBUSH1 = 1, - SAY_PROGRESS = 2, - SAY_AMBUSH2 = 3, - SAY_END = 4, - - QUEST_ESCAPE_FROM = 9752, - NPC_SLAVEBINDER = 18042 -}; - -class npc_kayra_longmane : public CreatureScript -{ -public: - npc_kayra_longmane() : CreatureScript("npc_kayra_longmane") { } - - struct npc_kayra_longmaneAI : public npc_escortAI - { - npc_kayra_longmaneAI(Creature* creature) : npc_escortAI(creature) {} - - void Reset() { } - - void WaypointReached(uint32 waypointId) - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 4: - Talk(SAY_AMBUSH1, player->GetGUID()); - DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 5: - Talk(SAY_PROGRESS, player->GetGUID()); - SetRun(); - break; - case 16: - Talk(SAY_AMBUSH2, player->GetGUID()); - DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); - break; - case 17: - SetRun(false); - break; - case 25: - Talk(SAY_END, player->GetGUID()); - player->GroupEventHappens(QUEST_ESCAPE_FROM, me); - break; - } - } - }; - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ESCAPE_FROM) - { - creature->AI()->Talk(SAY_START, player->GetGUID()); - - if (npc_escortAI* pEscortAI = CAST_AI(npc_kayra_longmane::npc_kayra_longmaneAI, creature->AI())) - pEscortAI->Start(false, false, player->GetGUID()); - } - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_kayra_longmaneAI(creature); - } -}; - -/*###### -## npc_timothy_daniels -######*/ - -#define GOSSIP_TIMOTHY_DANIELS_ITEM1 "Specialist, eh? Just what kind of specialist are you, anyway?" -#define GOSSIP_TEXT_BROWSE_POISONS "Let me browse your reagents and poison supplies." - -enum eTimothy -{ - GOSSIP_TEXTID_TIMOTHY_DANIELS1 = 9239 -}; - -class npc_timothy_daniels : public CreatureScript -{ -public: - npc_timothy_daniels() : CreatureScript("npc_timothy_daniels") { } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (creature->isVendor()) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_POISONS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TIMOTHY_DANIELS_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case GOSSIP_ACTION_INFO_DEF+1: - player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TIMOTHY_DANIELS1, creature->GetGUID()); - break; - case GOSSIP_ACTION_TRADE: - player->GetSession()->SendListInventory(creature->GetGUID()); - break; - } - - return true; - } -}; - -/*###### -## AddSC -######*/ - -void AddSC_zangarmarsh() -{ - new npcs_ashyen_and_keleth(); - new npc_cooshcoosh(); - new npc_elder_kuruti(); - new npc_mortog_steamhead(); - new npc_kayra_longmane(); - new npc_timothy_daniels(); -} diff --git a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp new file mode 100644 index 00000000000..d03abc82b9c --- /dev/null +++ b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp @@ -0,0 +1,1157 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Blades_Edge_Mountains +SD%Complete: 90 +SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete) +SDCategory: Blade's Edge Mountains +EndScriptData */ + +/* ContentData +mobs_bladespire_ogre +mobs_nether_drake +npc_daranelle +npc_overseer_nuaar +npc_saikkal_the_elder +go_legion_obelisk +go_thunderspike +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "Cell.h" +#include "CellImpl.h" + +//Support for quest: You're Fired! (10821) +bool obelisk_one, obelisk_two, obelisk_three, obelisk_four, obelisk_five; + +#define LEGION_OBELISK_ONE 185193 +#define LEGION_OBELISK_TWO 185195 +#define LEGION_OBELISK_THREE 185196 +#define LEGION_OBELISK_FOUR 185197 +#define LEGION_OBELISK_FIVE 185198 + +/*###### +## mobs_bladespire_ogre +######*/ + +//TODO: add support for quest 10512 + Creature abilities +class mobs_bladespire_ogre : public CreatureScript +{ +public: + mobs_bladespire_ogre() : CreatureScript("mobs_bladespire_ogre") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mobs_bladespire_ogreAI (creature); + } + + struct mobs_bladespire_ogreAI : public ScriptedAI + { + mobs_bladespire_ogreAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { } + + void UpdateAI(const uint32 /*uiDiff*/) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## mobs_nether_drake +######*/ + +enum eNetherdrake +{ + //Used by 20021, 21817, 21820, 21821, 21823 but not existing in database + SAY_NIHIL_1 = 0, + SAY_NIHIL_2 = 1, + SAY_NIHIL_3 = 2, + SAY_NIHIL_4 = 3, + SAY_NIHIL_INTERRUPT = 4, + + ENTRY_WHELP = 20021, + ENTRY_PROTO = 21821, + ENTRY_ADOLE = 21817, + ENTRY_MATUR = 21820, + ENTRY_NIHIL = 21823, + + SPELL_T_PHASE_MODULATOR = 37573, + + SPELL_ARCANE_BLAST = 38881, + SPELL_MANA_BURN = 38884, + SPELL_INTANGIBLE_PRESENCE = 36513 +}; + +class mobs_nether_drake : public CreatureScript +{ +public: + mobs_nether_drake() : CreatureScript("mobs_nether_drake") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mobs_nether_drakeAI (creature); + } + + struct mobs_nether_drakeAI : public ScriptedAI + { + mobs_nether_drakeAI(Creature* creature) : ScriptedAI(creature) {} + + bool IsNihil; + uint32 NihilSpeech_Timer; + uint32 NihilSpeech_Phase; + + uint32 ArcaneBlast_Timer; + uint32 ManaBurn_Timer; + uint32 IntangiblePresence_Timer; + + void Reset() + { + IsNihil = false; + NihilSpeech_Timer = 3000; + NihilSpeech_Phase = 0; + + ArcaneBlast_Timer = 7500; + ManaBurn_Timer = 10000; + IntangiblePresence_Timer = 15000; + } + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* who) + { + if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; + + ScriptedAI::MoveInLineOfSight(who); + } + + //in case Creature was not summoned (not expected) + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id == 0) + { + me->setDeathState(JUST_DIED); + me->RemoveCorpse(); + me->SetHealth(0); + } + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TYPEID_PLAYER) + { + const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL}; + int cid = rand()%(4-1); + + if (entry_list[cid] == me->GetEntry()) + ++cid; + + //we are nihil, so say before transform + if (me->GetEntry() == ENTRY_NIHIL) + { + Talk(SAY_NIHIL_INTERRUPT); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + IsNihil = false; + } + + if (me->UpdateEntry(entry_list[cid])) + { + if (entry_list[cid] == ENTRY_NIHIL) + { + EnterEvadeMode(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + IsNihil = true; + }else + AttackStart(caster); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (IsNihil) + { + if (NihilSpeech_Timer <= diff) + { + switch (NihilSpeech_Phase) + { + case 0: + Talk(SAY_NIHIL_1); + ++NihilSpeech_Phase; + break; + case 1: + Talk(SAY_NIHIL_2); + ++NihilSpeech_Phase; + break; + case 2: + Talk(SAY_NIHIL_3); + ++NihilSpeech_Phase; + break; + case 3: + Talk(SAY_NIHIL_4); + ++NihilSpeech_Phase; + break; + case 4: + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + //take off to location above + me->GetMotionMaster()->MovePoint(0, me->GetPositionX()+50.0f, me->GetPositionY(), me->GetPositionZ()+50.0f); + ++NihilSpeech_Phase; + break; + } + NihilSpeech_Timer = 5000; + } else NihilSpeech_Timer -=diff; + + //anything below here is not interesting for Nihil, so skip it + return; + } + + if (!UpdateVictim()) + return; + + if (IntangiblePresence_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_INTANGIBLE_PRESENCE); + IntangiblePresence_Timer = 15000+rand()%15000; + } else IntangiblePresence_Timer -= diff; + + if (ManaBurn_Timer <= diff) + { + Unit* target = me->getVictim(); + if (target && target->getPowerType() == POWER_MANA) + DoCast(target, SPELL_MANA_BURN); + ManaBurn_Timer = 8000+rand()%8000; + } else ManaBurn_Timer -= diff; + + if (ArcaneBlast_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_ARCANE_BLAST); + ArcaneBlast_Timer = 2500+rand()%5000; + } else ArcaneBlast_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_daranelle +######*/ + +enum eDaranelle +{ + SAY_SPELL_INFLUENCE = 0, + SPELL_LASHHAN_CHANNEL = 36904 +}; + +class npc_daranelle : public CreatureScript +{ +public: + npc_daranelle() : CreatureScript("npc_daranelle") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_daranelleAI (creature); + } + + struct npc_daranelleAI : public ScriptedAI + { + npc_daranelleAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { } + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* who) + { + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (who->HasAura(SPELL_LASHHAN_CHANNEL) && me->IsWithinDistInMap(who, 10.0f)) + { + Talk(SAY_SPELL_INFLUENCE, who->GetGUID()); + //TODO: Move the below to updateAI and run if this statement == true + DoCast(who, 37028, true); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + }; +}; + +/*###### +## npc_overseer_nuaar +######*/ + +#define GOSSIP_HELLO_ON "Overseer, I am here to negotiate on behalf of the Cenarion Expedition." + +class npc_overseer_nuaar : public CreatureScript +{ +public: + npc_overseer_nuaar() : CreatureScript("npc_overseer_nuaar") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->SEND_GOSSIP_MENU(10533, creature->GetGUID()); + player->AreaExploredOrEventHappens(10682); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(10682) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_ON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(10532, creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_saikkal_the_elder +######*/ + +#define GOSSIP_HELLO_STE "Yes... yes, it's me." +#define GOSSIP_SELECT_STE "Yes elder. Tell me more of the book." + +class npc_saikkal_the_elder : public CreatureScript +{ +public: + npc_saikkal_the_elder() : CreatureScript("npc_saikkal_the_elder") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_STE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(10795, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); + player->SEND_GOSSIP_MENU(10796, creature->GetGUID()); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(10980) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_STE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(10794, creature->GetGUID()); + + return true; + } +}; + +/*###### +## go_legion_obelisk +######*/ + +class go_legion_obelisk : public GameObjectScript +{ +public: + go_legion_obelisk() : GameObjectScript("go_legion_obelisk") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE) + { + switch (go->GetEntry()) + { + case LEGION_OBELISK_ONE: + obelisk_one = true; + break; + case LEGION_OBELISK_TWO: + obelisk_two = true; + break; + case LEGION_OBELISK_THREE: + obelisk_three = true; + break; + case LEGION_OBELISK_FOUR: + obelisk_four = true; + break; + case LEGION_OBELISK_FIVE: + obelisk_five = true; + break; + } + + if (obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true) + { + go->SummonCreature(19963, 2943.40f, 4778.20f, 284.49f, 0.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + //reset global var + obelisk_one = false; + obelisk_two = false; + obelisk_three = false; + obelisk_four = false; + obelisk_five = false; + } + } + + return true; + } +}; + +/*###### +## npc_bloodmaul_brutebane +######*/ + +enum eBloodmaul +{ + NPC_OGRE_BRUTE = 19995, + NPC_QUEST_CREDIT = 21241, + GO_KEG = 184315, + QUEST_GETTING_THE_BLADESPIRE_TANKED = 10512, + QUEST_BLADESPIRE_KEGGER = 10545, +}; + +class npc_bloodmaul_brutebane : public CreatureScript +{ +public: + npc_bloodmaul_brutebane() : CreatureScript("npc_bloodmaul_brutebane") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_bloodmaul_brutebaneAI(creature); + } + + struct npc_bloodmaul_brutebaneAI : public ScriptedAI + { + npc_bloodmaul_brutebaneAI(Creature* creature) : ScriptedAI(creature) + { + if (Creature* Ogre = me->FindNearestCreature(NPC_OGRE_BRUTE, 50, true)) + { + Ogre->SetReactState(REACT_DEFENSIVE); + Ogre->GetMotionMaster()->MovePoint(1, me->GetPositionX()-1, me->GetPositionY()+1, me->GetPositionZ()); + } + } + + uint64 OgreGUID; + + void Reset() + { + OgreGUID = 0; + } + + void UpdateAI(const uint32 /*uiDiff*/) {} + }; +}; + +/*###### +## npc_ogre_brute +######*/ + +class npc_ogre_brute : public CreatureScript +{ +public: + npc_ogre_brute() : CreatureScript("npc_ogre_brute") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ogre_bruteAI(creature); + } + + struct npc_ogre_bruteAI : public ScriptedAI + { + npc_ogre_bruteAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + + void Reset() + { + PlayerGUID = 0; + } + + void MoveInLineOfSight(Unit* who) + { + if (!who || (!who->isAlive())) + return; + + if (me->IsWithinDistInMap(who, 50.0f)) + { + if (who->GetTypeId() == TYPEID_PLAYER) + if (who->ToPlayer()->GetQuestStatus(QUEST_GETTING_THE_BLADESPIRE_TANKED) == QUEST_STATUS_INCOMPLETE + || who->ToPlayer()->GetQuestStatus(QUEST_BLADESPIRE_KEGGER) == QUEST_STATUS_INCOMPLETE) + PlayerGUID = who->GetGUID(); + } + } + + void MovementInform(uint32 /*type*/, uint32 id) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (id == 1) + { + GameObject* Keg = me->FindNearestGameObject(GO_KEG, 20); + if (Keg) + Keg->Delete(); + me->HandleEmoteCommand(7); + me->SetReactState(REACT_AGGRESSIVE); + me->GetMotionMaster()->MoveTargetedHome(); + Creature* Credit = me->FindNearestCreature(NPC_QUEST_CREDIT, 50, true); + if (player && Credit) + player->KilledMonster(Credit->GetCreatureTemplate(), Credit->GetGUID()); + } + } + + void UpdateAI(const uint32 /*diff*/) + { + if (!UpdateVictim()) + return; + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## go_thunderspike +######*/ + +enum TheThunderspike +{ + NPC_GOR_GRIMGUT = 21319, + QUEST_THUNDERSPIKE = 10526, +}; + +class go_thunderspike : public GameObjectScript +{ + public: + go_thunderspike() : GameObjectScript("go_thunderspike") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_THUNDERSPIKE) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_GOR_GRIMGUT, 25.0f, true)) + if (Creature* gorGrimgut = go->SummonCreature(NPC_GOR_GRIMGUT, -2413.4f, 6914.48f, 25.01f, 3.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000)) + gorGrimgut->AI()->AttackStart(player); + + return true; + } +}; + +enum SimonGame +{ + NPC_SIMON_BUNNY = 22923, + NPC_APEXIS_GUARDIAN = 22275, + + GO_APEXIS_RELIC = 185890, + GO_APEXIS_MONUMENT = 185944, + GO_AURA_BLUE = 185872, + GO_AURA_GREEN = 185873, + GO_AURA_RED = 185874, + GO_AURA_YELLOW = 185875, + + GO_BLUE_CLUSTER_DISPLAY = 7369, + GO_GREEN_CLUSTER_DISPLAY = 7371, + GO_RED_CLUSTER_DISPLAY = 7373, + GO_YELLOW_CLUSTER_DISPLAY = 7375, + GO_BLUE_CLUSTER_DISPLAY_LARGE = 7364, + GO_GREEN_CLUSTER_DISPLAY_LARGE = 7365, + GO_RED_CLUSTER_DISPLAY_LARGE = 7366, + GO_YELLOW_CLUSTER_DISPLAY_LARGE = 7367, + + SPELL_PRE_GAME_BLUE = 40176, + SPELL_PRE_GAME_GREEN = 40177, + SPELL_PRE_GAME_RED = 40178, + SPELL_PRE_GAME_YELLOW = 40179, + SPELL_VISUAL_BLUE = 40244, + SPELL_VISUAL_GREEN = 40245, + SPELL_VISUAL_RED = 40246, + SPELL_VISUAL_YELLOW = 40247, + + SOUND_BLUE = 11588, + SOUND_GREEN = 11589, + SOUND_RED = 11590, + SOUND_YELLOW = 11591, + SOUND_DISABLE_NODE = 11758, + + SPELL_AUDIBLE_GAME_TICK = 40391, + SPELL_VISUAL_START_PLAYER_LEVEL = 40436, + SPELL_VISUAL_START_AI_LEVEL = 40387, + + SPELL_BAD_PRESS_TRIGGER = 41241, + SPELL_BAD_PRESS_DAMAGE = 40065, + SPELL_REWARD_BUFF_1 = 40310, + SPELL_REWARD_BUFF_2 = 40311, + SPELL_REWARD_BUFF_3 = 40312, +}; + +enum SimonEvents +{ + EVENT_SIMON_SETUP_PRE_GAME = 1, + EVENT_SIMON_PLAY_SEQUENCE = 2, + EVENT_SIMON_RESET_CLUSTERS = 3, + EVENT_SIMON_PERIODIC_PLAYER_CHECK = 4, + EVENT_SIMON_TOO_LONG_TIME = 5, + EVENT_SIMON_GAME_TICK = 6, + EVENT_SIMON_ROUND_FINISHED = 7, + + ACTION_SIMON_CORRECT_FULL_SEQUENCE = 8, + ACTION_SIMON_WRONG_SEQUENCE = 9, + ACTION_SIMON_ROUND_FINISHED = 10, +}; + +enum SimonColors +{ + SIMON_BLUE = 0, + SIMON_RED = 1, + SIMON_GREEN = 2, + SIMON_YELLOW = 3, + SIMON_MAX_COLORS = 4, +}; + +class npc_simon_bunny : public CreatureScript +{ + public: + npc_simon_bunny() : CreatureScript("npc_simon_bunny") { } + + struct npc_simon_bunnyAI : public ScriptedAI + { + npc_simon_bunnyAI(Creature* creature) : ScriptedAI(creature) { } + + bool large; + bool listening; + uint8 gameLevel; + uint8 fails; + uint8 gameTicks; + uint64 playerGUID; + uint32 clusterIds[SIMON_MAX_COLORS]; + float zCoordCorrection; + float searchDistance; + EventMap _events; + std::list colorSequence, playableSequence, playerSequence; + + void UpdateAI(const uint32 diff) + { + _events.Update(diff); + + switch (_events.ExecuteEvent()) + { + case EVENT_SIMON_PERIODIC_PLAYER_CHECK: + if (!CheckPlayer()) + ResetNode(); + else + _events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000); + break; + case EVENT_SIMON_SETUP_PRE_GAME: + SetUpPreGame(); + _events.CancelEvent(EVENT_SIMON_GAME_TICK); + _events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1000); + break; + case EVENT_SIMON_PLAY_SEQUENCE: + if (!playableSequence.empty()) + { + PlayNextColor(); + _events.ScheduleEvent(EVENT_SIMON_PLAY_SEQUENCE, 1500); + } + else + { + listening = true; + DoCast(SPELL_VISUAL_START_PLAYER_LEVEL); + playerSequence.clear(); + PrepareClusters(); + gameTicks = 0; + _events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000); + } + break; + case EVENT_SIMON_GAME_TICK: + DoCast(SPELL_AUDIBLE_GAME_TICK); + + if (gameTicks > gameLevel) + _events.ScheduleEvent(EVENT_SIMON_TOO_LONG_TIME, 500); + else + _events.ScheduleEvent(EVENT_SIMON_GAME_TICK, 3000); + gameTicks++; + break; + case EVENT_SIMON_RESET_CLUSTERS: + PrepareClusters(true); + break; + case EVENT_SIMON_TOO_LONG_TIME: + DoAction(ACTION_SIMON_WRONG_SEQUENCE); + break; + case EVENT_SIMON_ROUND_FINISHED: + DoAction(ACTION_SIMON_ROUND_FINISHED); + break; + } + } + + void DoAction(const int32 action) + { + switch (action) + { + case ACTION_SIMON_ROUND_FINISHED: + listening = false; + DoCast(SPELL_VISUAL_START_AI_LEVEL); + GiveRewardForLevel(gameLevel); + _events.CancelEventGroup(0); + if (gameLevel == 10) + ResetNode(); + else + _events.ScheduleEvent(EVENT_SIMON_SETUP_PRE_GAME, 1000); + break; + case ACTION_SIMON_CORRECT_FULL_SEQUENCE: + gameLevel++; + DoAction(ACTION_SIMON_ROUND_FINISHED); + break; + case ACTION_SIMON_WRONG_SEQUENCE: + GivePunishment(); + DoAction(ACTION_SIMON_ROUND_FINISHED); + break; + } + } + + // Called by color clusters script (go_simon_cluster) and used for knowing the button pressed by player + void SetData(uint32 type, uint32 /*data*/) + { + if (!listening) + return; + + uint8 pressedColor = SIMON_MAX_COLORS; + + if (type == clusterIds[SIMON_RED]) + pressedColor = SIMON_RED; + else if (type == clusterIds[SIMON_BLUE]) + pressedColor = SIMON_BLUE; + else if (type == clusterIds[SIMON_GREEN]) + pressedColor = SIMON_GREEN; + else if (type == clusterIds[SIMON_YELLOW]) + pressedColor = SIMON_YELLOW; + + PlayColor(pressedColor); + playerSequence.push_back(pressedColor); + _events.ScheduleEvent(EVENT_SIMON_RESET_CLUSTERS, 500); + CheckPlayerSequence(); + } + + // Used for getting involved player guid. Parameter id is used for defining if is a large(Monument) or small(Relic) node + void SetGUID(uint64 guid, int32 id) + { + me->SetCanFly(true); + + large = (bool)id; + playerGUID = guid; + StartGame(); + } + + /* + Resets all variables and also find the ids of the four closests color clusters, since every simon + node have diferent ids for clusters this is absolutely NECESSARY. + */ + void StartGame() + { + listening = false; + gameLevel = 0; + fails = 0; + gameTicks = 0; + zCoordCorrection = large ? 8.0f : 2.75f; + searchDistance = large ? 13.0f : 5.0f; + colorSequence.clear(); + playableSequence.clear(); + playerSequence.clear(); + me->SetObjectScale(large ? 2.0f : 1.0f); + + std::list ClusterList; + Trinity::AllWorldObjectsInRange objects(me, searchDistance); + Trinity::WorldObjectListSearcher searcher(me, ClusterList, objects); + me->VisitNearbyObject(searchDistance, searcher); + + for (std::list::const_iterator i = ClusterList.begin(); i != ClusterList.end(); ++i) + { + if (GameObject* go = (*i)->ToGameObject()) + { + // We are checking for displayid because all simon nodes have 4 clusters with different entries + if (large) + { + switch (go->GetGOInfo()->displayId) + { + case GO_BLUE_CLUSTER_DISPLAY_LARGE: + clusterIds[SIMON_BLUE] = go->GetEntry(); + break; + + case GO_RED_CLUSTER_DISPLAY_LARGE: + clusterIds[SIMON_RED] = go->GetEntry(); + break; + + case GO_GREEN_CLUSTER_DISPLAY_LARGE: + clusterIds[SIMON_GREEN] = go->GetEntry(); + break; + + case GO_YELLOW_CLUSTER_DISPLAY_LARGE: + clusterIds[SIMON_YELLOW] = go->GetEntry(); + break; + } + } + else + { + switch (go->GetGOInfo()->displayId) + { + case GO_BLUE_CLUSTER_DISPLAY: + clusterIds[SIMON_BLUE] = go->GetEntry(); + break; + + case GO_RED_CLUSTER_DISPLAY: + clusterIds[SIMON_RED] = go->GetEntry(); + break; + + case GO_GREEN_CLUSTER_DISPLAY: + clusterIds[SIMON_GREEN] = go->GetEntry(); + break; + + case GO_YELLOW_CLUSTER_DISPLAY: + clusterIds[SIMON_YELLOW] = go->GetEntry(); + break; + } + } + } + } + + _events.Reset(); + _events.ScheduleEvent(EVENT_SIMON_ROUND_FINISHED, 1000); + _events.ScheduleEvent(EVENT_SIMON_PERIODIC_PLAYER_CHECK, 2000); + + if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) + relic->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + + // Called when despawning the bunny. Sets all the node GOs to their default states. + void ResetNode() + { + DoPlaySoundToSet(me, SOUND_DISABLE_NODE); + + for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++) + if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance)) + cluster->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + + for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++) + if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance)) + auraGo->RemoveFromWorld(); + + if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) + relic->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + + me->DespawnOrUnsummon(1000); + } + + /* + Called on every button click of player. Adds the clicked color to the player created sequence and + checks if it corresponds to the AI created sequence. If so, incremente gameLevel and start a new + round, if not, give punishment and restart current level. + */ + void CheckPlayerSequence() + { + bool correct = true; + if (playerSequence.size() <= colorSequence.size()) + for (std::list::const_iterator i = playerSequence.begin(), j = colorSequence.begin(); i != playerSequence.end(); ++i, ++j) + if ((*i) != (*j)) + correct = false; + + if (correct && (playerSequence.size() == colorSequence.size())) + DoAction(ACTION_SIMON_CORRECT_FULL_SEQUENCE); + else if (!correct) + DoAction(ACTION_SIMON_WRONG_SEQUENCE); + } + + /* + Generates a random sequence of colors depending on the gameLevel. We also copy this sequence to + the playableSequence wich will be used when playing the sequence to the player. + */ + void GenerateColorSequence() + { + colorSequence.clear(); + for (uint8 i = 0; i <= gameLevel; i++) + colorSequence.push_back(RAND(SIMON_BLUE, SIMON_RED, SIMON_GREEN, SIMON_YELLOW)); + + for (std::list::const_iterator i = colorSequence.begin(); i != colorSequence.end(); ++i) + playableSequence.push_back(*i); + } + + + // Remove any existant glowing auras over clusters and set clusters ready for interating with them. + void PrepareClusters(bool clustersOnly = false) + { + for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++) + if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], searchDistance)) + cluster->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + + if (clustersOnly) + return; + + for (uint32 auraId = GO_AURA_BLUE; auraId <= GO_AURA_YELLOW; auraId++) + if (GameObject* auraGo = me->FindNearestGameObject(auraId, searchDistance)) + auraGo->RemoveFromWorld(); + } + + /* + Called when AI is playing the sequence for player. We cast the visual spell and then remove the + casted color from the casting sequence. + */ + void PlayNextColor() + { + PlayColor(*playableSequence.begin()); + playableSequence.erase(playableSequence.begin()); + } + + // Casts a spell and plays a sound depending on parameter color. + void PlayColor(uint8 color) + { + switch (color) + { + case SIMON_BLUE: + DoCast(SPELL_VISUAL_BLUE); + DoPlaySoundToSet(me, SOUND_BLUE); + break; + case SIMON_GREEN: + DoCast(SPELL_VISUAL_GREEN); + DoPlaySoundToSet(me, SOUND_GREEN); + break; + case SIMON_RED: + DoCast(SPELL_VISUAL_RED); + DoPlaySoundToSet(me, SOUND_RED); + break; + case SIMON_YELLOW: + DoCast(SPELL_VISUAL_YELLOW); + DoPlaySoundToSet(me, SOUND_YELLOW); + break; + } + } + + /* + Creates the transparent glowing auras on every cluster of this node. + After calling this function bunny is teleported to the center of the node. + */ + void SetUpPreGame() + { + for (uint32 clusterId = SIMON_BLUE; clusterId < SIMON_MAX_COLORS; clusterId++) + { + if (GameObject* cluster = me->FindNearestGameObject(clusterIds[clusterId], 2.0f*searchDistance)) + { + cluster->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + + // break since we don't need glowing auras for large clusters + if (large) + break; + + float x, y, z, o; + cluster->GetPosition(x, y, z, o); + me->NearTeleportTo(x, y, z, o); + + uint32 preGameSpellId; + if (cluster->GetEntry() == clusterIds[SIMON_RED]) + preGameSpellId = SPELL_PRE_GAME_RED; + else if (cluster->GetEntry() == clusterIds[SIMON_BLUE]) + preGameSpellId = SPELL_PRE_GAME_BLUE; + else if (cluster->GetEntry() == clusterIds[SIMON_GREEN]) + preGameSpellId = SPELL_PRE_GAME_GREEN; + else if (cluster->GetEntry() == clusterIds[SIMON_YELLOW]) + preGameSpellId = SPELL_PRE_GAME_YELLOW; + else break; + + me->CastSpell(cluster, preGameSpellId, true); + } + } + + if (GameObject* relic = me->FindNearestGameObject(large ? GO_APEXIS_MONUMENT : GO_APEXIS_RELIC, searchDistance)) + { + float x, y, z, o; + relic->GetPosition(x, y, z, o); + me->NearTeleportTo(x, y, z + zCoordCorrection, o); + } + + GenerateColorSequence(); + } + + // Handles the spell rewards. The spells also have the QuestCompleteEffect, so quests credits are working. + void GiveRewardForLevel(uint8 level) + { + uint32 rewSpell = 0; + switch (level) + { + case 6: + if (large) + GivePunishment(); + else + rewSpell = SPELL_REWARD_BUFF_1; + break; + case 8: + rewSpell = SPELL_REWARD_BUFF_2; + break; + case 10: + rewSpell = SPELL_REWARD_BUFF_3; + break; + } + + if (rewSpell) + if (Player* player = me->GetPlayer(*me, playerGUID)) + DoCast(player, rewSpell, true); + } + + /* + Depending on the number of failed pushes for player the damage of the spell scales, so we first + cast the spell on the target that hits for 50 and shows the visual and then forces the player + to cast the damaging spell on it self with the modified basepoints. + 4 fails = death. + On large nodes punishment and reward are the same, summoning the Apexis Guardian. + */ + void GivePunishment() + { + if (large) + { + if (Player* player = me->GetPlayer(*me, playerGUID)) + if (Creature* guardian = me->SummonCreature(NPC_APEXIS_GUARDIAN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() - zCoordCorrection, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000)) + guardian->AI()->AttackStart(player); + + ResetNode(); + } + else + { + fails++; + + if (Player* player = me->GetPlayer(*me, playerGUID)) + DoCast(player, SPELL_BAD_PRESS_TRIGGER, true); + + if (fails >= 4) + ResetNode(); + } + } + + void SpellHitTarget(Unit* target, const SpellInfo* spell) + { + // Cast SPELL_BAD_PRESS_DAMAGE with scaled basepoints when the visual hits the target. + // Need Fix: When SPELL_BAD_PRESS_TRIGGER hits target it triggers spell SPELL_BAD_PRESS_DAMAGE by itself + // so player gets damage equal to calculated damage dbc basepoints for SPELL_BAD_PRESS_DAMAGE (~50) + if (spell->Id == SPELL_BAD_PRESS_TRIGGER) + { + int32 bp = (int32)((float)(fails)*0.33f*target->GetMaxHealth()); + target->CastCustomSpell(target, SPELL_BAD_PRESS_DAMAGE, &bp, NULL, NULL, true); + } + } + + // Checks if player has already die or has get too far from the current node + bool CheckPlayer() + { + if (Player* player = me->GetPlayer(*me, playerGUID)) + { + if (player->isDead()) + return false; + if (player->GetDistance2d(me) >= 2.0f*searchDistance) + { + GivePunishment(); + return false; + } + } + else + return false; + + return true; + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_simon_bunnyAI(creature); + } +}; + +class go_simon_cluster : public GameObjectScript +{ + public: + go_simon_cluster() : GameObjectScript("go_simon_cluster") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (Creature* bunny = go->FindNearestCreature(NPC_SIMON_BUNNY, 12.0f, true)) + bunny->AI()->SetData(go->GetEntry(), 0); + + player->CastSpell(player, go->GetGOInfo()->goober.spellId, true); + go->AddUse(); + return true; + } +}; + +enum ApexisRelic +{ + QUEST_CRYSTALS = 11025, + GOSSIP_TEXT_ID = 10948, + + ITEM_APEXIS_SHARD = 32569, + SPELL_TAKE_REAGENTS_SOLO = 41145, + SPELL_TAKE_REAGENTS_GROUP = 41146, +}; + +class go_apexis_relic : public GameObjectScript +{ + public: + go_apexis_relic() : GameObjectScript("go_apexis_relic") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + player->PrepareGossipMenu(go, go->GetGOInfo()->questgiver.gossipID); + player->SendPreparedGossip(go); + return true; + } + + bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) + { + player->CLOSE_GOSSIP_MENU(); + + bool large = (go->GetEntry() == GO_APEXIS_MONUMENT); + if (player->HasItemCount(ITEM_APEXIS_SHARD, large ? 35 : 1)) + { + player->CastSpell(player, large ? SPELL_TAKE_REAGENTS_GROUP : SPELL_TAKE_REAGENTS_SOLO, false); + + if (Creature* bunny = player->SummonCreature(NPC_SIMON_BUNNY, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ())) + bunny->AI()->SetGUID(player->GetGUID(), large); + } + + return true; + } +}; + +void AddSC_blades_edge_mountains() +{ + new mobs_bladespire_ogre(); + new mobs_nether_drake(); + new npc_daranelle(); + new npc_overseer_nuaar(); + new npc_saikkal_the_elder(); + new go_legion_obelisk(); + new npc_bloodmaul_brutebane(); + new npc_ogre_brute(); + new go_thunderspike(); + new npc_simon_bunny(); + new go_simon_cluster(); + new go_apexis_relic(); +} diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp new file mode 100644 index 00000000000..64b484268df --- /dev/null +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -0,0 +1,522 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Hellfire_Peninsula +SD%Complete: 100 +SDComment: Quest support: 9375, 9410, 9418, 10129, 10146, 10162, 10163, 10340, 10346, 10347, 10382 (Special flight paths) +SDCategory: Hellfire Peninsula +EndScriptData */ + +/* ContentData +npc_aeranas +npc_ancestral_wolf +go_haaleshi_altar +npc_naladu +npc_tracy_proudwell +npc_trollbane +npc_wounded_blood_elf +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npc_aeranas +######*/ + +enum eAeranas +{ + SAY_SUMMON = 0, + SAY_FREE = 1, + + FACTION_HOSTILE = 16, + FACTION_FRIENDLY = 35, + + SPELL_ENVELOPING_WINDS = 15535, + SPELL_SHOCK = 12553 +}; + +class npc_aeranas : public CreatureScript +{ +public: + npc_aeranas() : CreatureScript("npc_aeranas") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_aeranasAI (creature); + } + + struct npc_aeranasAI : public ScriptedAI + { + npc_aeranasAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 Faction_Timer; + uint32 EnvelopingWinds_Timer; + uint32 Shock_Timer; + + void Reset() + { + Faction_Timer = 8000; + EnvelopingWinds_Timer = 9000; + Shock_Timer = 5000; + + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + me->setFaction(FACTION_FRIENDLY); + + Talk(SAY_SUMMON); + } + + void UpdateAI(const uint32 diff) + { + if (Faction_Timer) + { + if (Faction_Timer <= diff) + { + me->setFaction(FACTION_HOSTILE); + Faction_Timer = 0; + } else Faction_Timer -= diff; + } + + if (!UpdateVictim()) + return; + + if (HealthBelowPct(30)) + { + me->setFaction(FACTION_FRIENDLY); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + me->RemoveAllAuras(); + me->DeleteThreatList(); + me->CombatStop(true); + Talk(SAY_FREE); + return; + } + + if (Shock_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_SHOCK); + Shock_Timer = 10000; + } else Shock_Timer -= diff; + + if (EnvelopingWinds_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_ENVELOPING_WINDS); + EnvelopingWinds_Timer = 25000; + } else EnvelopingWinds_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_ancestral_wolf +######*/ + +enum eAncestralWolf +{ + EMOTE_WOLF_LIFT_HEAD = 0, + EMOTE_WOLF_HOWL = 1, + SAY_WOLF_WELCOME = 2, + + SPELL_ANCESTRAL_WOLF_BUFF = 29981, + + NPC_RYGA = 17123 +}; + +class npc_ancestral_wolf : public CreatureScript +{ +public: + npc_ancestral_wolf() : CreatureScript("npc_ancestral_wolf") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ancestral_wolfAI(creature); + } + + struct npc_ancestral_wolfAI : public npc_escortAI + { + npc_ancestral_wolfAI(Creature* creature) : npc_escortAI(creature) + { + if (creature->GetOwner() && creature->GetOwner()->GetTypeId() == TYPEID_PLAYER) + Start(false, false, creature->GetOwner()->GetGUID()); + else + sLog->outError(LOG_FILTER_TSCR, "TRINITY: npc_ancestral_wolf can not obtain owner or owner is not a player."); + + creature->SetSpeed(MOVE_WALK, 1.5f); + Reset(); + } + + Creature* pRyga; + + void Reset() + { + pRyga = NULL; + DoCast(me, SPELL_ANCESTRAL_WOLF_BUFF, true); + } + + void MoveInLineOfSight(Unit* who) + { + if (!pRyga && who->GetEntry() == NPC_RYGA && me->IsWithinDistInMap(who, 15.0f)) + if (Creature* temp = who->ToCreature()) + pRyga = temp; + + npc_escortAI::MoveInLineOfSight(who); + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 0: + Talk(EMOTE_WOLF_LIFT_HEAD); + break; + case 2: + Talk(EMOTE_WOLF_HOWL); + break; + case 50: + if (pRyga && pRyga->isAlive() && !pRyga->isInCombat()) + pRyga->AI()->Talk(SAY_WOLF_WELCOME); + break; + } + } + }; +}; + +/*###### +## npc_naladu +######*/ + +#define GOSSIP_NALADU_ITEM1 "Why don't you escape?" + +enum eNaladu +{ + GOSSIP_TEXTID_NALADU1 = 9788 +}; + +class npc_naladu : public CreatureScript +{ +public: + npc_naladu() : CreatureScript("npc_naladu") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_NALADU1, creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_NALADU_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_tracy_proudwell +######*/ + +#define GOSSIP_TEXT_REDEEM_MARKS "I have marks to redeem!" +#define GOSSIP_TRACY_PROUDWELL_ITEM1 "I heard that your dog Fei Fei took Klatu's prayer beads..." +#define GOSSIP_TRACY_PROUDWELL_ITEM2 "" + +enum eTracy +{ + GOSSIP_TEXTID_TRACY_PROUDWELL1 = 10689, + QUEST_DIGGING_FOR_PRAYER_BEADS = 10916 +}; + +class npc_tracy_proudwell : public CreatureScript +{ +public: + npc_tracy_proudwell() : CreatureScript("npc_tracy_proudwell") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TRACY_PROUDWELL_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TRACY_PROUDWELL1, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_TRADE: + player->GetSession()->SendListInventory(creature->GetGUID()); + break; + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_REDEEM_MARKS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + if (player->GetQuestStatus(QUEST_DIGGING_FOR_PRAYER_BEADS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TRACY_PROUDWELL_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_trollbane +######*/ + +#define GOSSIP_TROLLBANE_ITEM1 "Tell me of the Sons of Lothar." +#define GOSSIP_TROLLBANE_ITEM2 "" +#define GOSSIP_TROLLBANE_ITEM3 "Tell me of your homeland." + +enum eTrollbane +{ + GOSSIP_TEXTID_TROLLBANE1 = 9932, + GOSSIP_TEXTID_TROLLBANE2 = 9933, + GOSSIP_TEXTID_TROLLBANE3 = 8772 +}; + +class npc_trollbane : public CreatureScript +{ +public: + npc_trollbane() : CreatureScript("npc_trollbane") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TROLLBANE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TROLLBANE1, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TROLLBANE2, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TROLLBANE3, creature->GetGUID()); + break; + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TROLLBANE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TROLLBANE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_wounded_blood_elf +######*/ + +enum eWoundedBloodElf +{ + SAY_ELF_START = 0, + SAY_ELF_SUMMON1 = 1, + SAY_ELF_RESTING = 2, + SAY_ELF_SUMMON2 = 3, + SAY_ELF_COMPLETE = 4, + SAY_ELF_AGGRO = 5, + + QUEST_ROAD_TO_FALCON_WATCH = 9375 +}; + +class npc_wounded_blood_elf : public CreatureScript +{ +public: + npc_wounded_blood_elf() : CreatureScript("npc_wounded_blood_elf") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ROAD_TO_FALCON_WATCH) + { + if (npc_escortAI* pEscortAI = CAST_AI(npc_wounded_blood_elf::npc_wounded_blood_elfAI, creature->AI())) + pEscortAI->Start(true, false, player->GetGUID()); + + // Change faction so mobs attack + creature->setFaction(775); + } + + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_wounded_blood_elfAI(creature); + } + + struct npc_wounded_blood_elfAI : public npc_escortAI + { + npc_wounded_blood_elfAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 0: + Talk(SAY_ELF_START, player->GetGUID()); + break; + case 9: + Talk(SAY_ELF_SUMMON1, player->GetGUID()); + // Spawn two Haal'eshi Talonguard + DoSpawnCreature(16967, -15, -15, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + DoSpawnCreature(16967, -17, -17, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 13: + Talk(SAY_ELF_RESTING, player->GetGUID()); + break; + case 14: + Talk(SAY_ELF_SUMMON2, player->GetGUID()); + // Spawn two Haal'eshi Windwalker + DoSpawnCreature(16966, -15, -15, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + DoSpawnCreature(16966, -17, -17, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + break; + case 27: + Talk(SAY_ELF_COMPLETE, player->GetGUID()); + // Award quest credit + player->GroupEventHappens(QUEST_ROAD_TO_FALCON_WATCH, me); + break; + } + } + + void Reset() { } + + void EnterCombat(Unit* /*who*/) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + Talk(SAY_ELF_AGGRO); + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + }; +}; + +/*###### +## npc_fel_guard_hound +######*/ + +enum eFelGuard +{ + SPELL_SUMMON_POO = 37688, + + NPC_DERANGED_HELBOAR = 16863 +}; + +class npc_fel_guard_hound : public CreatureScript +{ +public: + npc_fel_guard_hound() : CreatureScript("npc_fel_guard_hound") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_fel_guard_houndAI(creature); + } + + struct npc_fel_guard_houndAI : public ScriptedAI + { + npc_fel_guard_houndAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 uiCheckTimer; + uint64 uiHelboarGUID; + + void Reset() + { + uiCheckTimer = 5000; //check for creature every 5 sec + uiHelboarGUID = 0; + } + + void MovementInform(uint32 uiType, uint32 uiId) + { + if (uiType != POINT_MOTION_TYPE || uiId != 1) + return; + + if (Creature* pHelboar = me->GetCreature(*me, uiHelboarGUID)) + { + pHelboar->RemoveCorpse(); + DoCast(SPELL_SUMMON_POO); + + if (Player* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself()) + me->GetMotionMaster()->MoveFollow(owner, 0.0f, 0.0f); + } + } + + void UpdateAI(const uint32 uiDiff) + { + if (uiCheckTimer <= uiDiff) + { + if (Creature* pHelboar = me->FindNearestCreature(NPC_DERANGED_HELBOAR, 10.0f, false)) + { + if (pHelboar->GetGUID() != uiHelboarGUID && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE && !me->FindCurrentSpellBySpellId(SPELL_SUMMON_POO)) + { + uiHelboarGUID = pHelboar->GetGUID(); + me->GetMotionMaster()->MovePoint(1, pHelboar->GetPositionX(), pHelboar->GetPositionY(), pHelboar->GetPositionZ()); + } + } + uiCheckTimer = 5000; + }else uiCheckTimer -= uiDiff; + + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; +}; + +void AddSC_hellfire_peninsula() +{ + new npc_aeranas(); + new npc_ancestral_wolf(); + new npc_naladu(); + new npc_tracy_proudwell(); + new npc_trollbane(); + new npc_wounded_blood_elf(); + new npc_fel_guard_hound(); +} diff --git a/src/server/scripts/Outland/zone_nagrand.cpp b/src/server/scripts/Outland/zone_nagrand.cpp new file mode 100644 index 00000000000..0a92b985c95 --- /dev/null +++ b/src/server/scripts/Outland/zone_nagrand.cpp @@ -0,0 +1,708 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Nagrand +SD%Complete: 90 +SDComment: Quest support: 9868, 9874, 10044, 10172, 10085. TextId's unknown for altruis_the_sufferer and greatmother_geyah (npc_text) +SDCategory: Nagrand +EndScriptData */ + +/* ContentData +npc_greatmother_geyah +npc_maghar_captive +npc_creditmarker_visit_with_ancestors +EndContentData */ +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "SpellInfo.h" + +/*###### +## npc_greatmother_geyah +######*/ + +#define GOSSIP_HGG1 "Hello, Greatmother. Garrosh told me that you wanted to speak with me." +#define GOSSIP_HGG2 "Garrosh is beyond redemption, Greatmother. I fear that in helping the Mag'har, I have convinced Garrosh that he is unfit to lead." + +#define GOSSIP_SGG1 "You raised all of the orcs here, Greatmother?" +#define GOSSIP_SGG2 "Do you believe that?" +#define GOSSIP_SGG3 "What can be done? I have tried many different things. I have done my best to help the people of Nagrand. Each time I have approached Garrosh, he has dismissed me." +#define GOSSIP_SGG4 "Left? How can you choose to leave?" +#define GOSSIP_SGG5 "What is this duty?" +#define GOSSIP_SGG6 "Is there anything I can do for you, Greatmother?" +#define GOSSIP_SGG7 "I have done all that I could, Greatmother. I thank you for your kind words." +#define GOSSIP_SGG8 "Greatmother, you are the mother of Durotan?" +#define GOSSIP_SGG9 "Greatmother, I never had the honor. Durotan died long before my time, but his heroics are known to all on my world. The orcs of Azeroth reside in a place known as Durotar, named after your son. And ... (You take a moment to breathe and think through what you are about to tell the Greatmother.)" +#define GOSSIP_SGG10 "It is my Warchief, Greatmother. The leader of my people. From my world. He ... He is the son of Durotan. He is your grandchild." +#define GOSSIP_SGG11 "I will return to Azeroth at once, Greatmother." + +//all the textId's for the below is unknown, but i do believe the gossip item texts are proper. +class npc_greatmother_geyah : public CreatureScript +{ +public: + npc_greatmother_geyah() : CreatureScript("npc_greatmother_geyah") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 6: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 7: + player->AreaExploredOrEventHappens(10044); + player->CLOSE_GOSSIP_MENU(); + break; + case GOSSIP_ACTION_INFO_DEF + 10: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 11: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 12: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 13: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 14: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SGG11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 15: + player->AreaExploredOrEventHappens(10172); + player->CLOSE_GOSSIP_MENU(); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(10044) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HGG1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + } + else if (player->GetQuestStatus(10172) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HGG2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*##### +## npc_maghar_captive +#####*/ + +enum eMagharCaptive +{ + SAY_MAG_START = 0, + SAY_MAG_NO_ESCAPE = 0, + SAY_MAG_MORE = 1, + SAY_MAG_MORE_REPLY = 0, + SAY_MAG_LIGHTNING = 2, + SAY_MAG_SHOCK = 3, + SAY_MAG_COMPLETE = 4, + + SPELL_CHAIN_LIGHTNING = 16006, + SPELL_EARTHBIND_TOTEM = 15786, + SPELL_FROST_SHOCK = 12548, + SPELL_HEALING_WAVE = 12491, + + QUEST_TOTEM_KARDASH_H = 9868, + + NPC_MURK_RAIDER = 18203, + NPC_MURK_BRUTE = 18211, + NPC_MURK_SCAVENGER = 18207, + NPC_MURK_PUTRIFIER = 18202 +}; + +static float m_afAmbushA[]= {-1568.805786f, 8533.873047f, 1.958f}; +static float m_afAmbushB[]= {-1491.554321f, 8506.483398f, 1.248f}; + +class npc_maghar_captive : public CreatureScript +{ +public: + npc_maghar_captive() : CreatureScript("npc_maghar_captive") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_H) + { + if (npc_maghar_captiveAI* pEscortAI = dynamic_cast(creature->AI())) + { + creature->SetStandState(UNIT_STAND_STATE_STAND); + creature->setFaction(232); + + pEscortAI->Start(true, false, player->GetGUID(), quest); + + creature->AI()->Talk(SAY_MAG_START); + + creature->SummonCreature(NPC_MURK_RAIDER, m_afAmbushA[0]+2.5f, m_afAmbushA[1]-2.5f, m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + creature->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushA[0]-2.5f, m_afAmbushA[1]+2.5f, m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + creature->SummonCreature(NPC_MURK_BRUTE, m_afAmbushA[0], m_afAmbushA[1], m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + } + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_maghar_captiveAI(creature); + } + + struct npc_maghar_captiveAI : public npc_escortAI + { + npc_maghar_captiveAI(Creature* creature) : npc_escortAI(creature) { Reset(); } + + uint32 m_uiChainLightningTimer; + uint32 m_uiHealTimer; + uint32 m_uiFrostShockTimer; + + void Reset() + { + m_uiChainLightningTimer = 1000; + m_uiHealTimer = 0; + m_uiFrostShockTimer = 6000; + } + + void EnterCombat(Unit* /*who*/) + { + DoCast(me, SPELL_EARTHBIND_TOTEM, false); + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 7: + Talk(SAY_MAG_MORE); + + if (Creature* temp = me->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushB[0], m_afAmbushB[1], m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000)) + temp->AI()->Talk(SAY_MAG_MORE_REPLY); + + me->SummonCreature(NPC_MURK_PUTRIFIER, m_afAmbushB[0]-2.5f, m_afAmbushB[1]-2.5f, m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(NPC_MURK_SCAVENGER, m_afAmbushB[0]+2.5f, m_afAmbushB[1]+2.5f, m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(NPC_MURK_SCAVENGER, m_afAmbushB[0]+2.5f, m_afAmbushB[1]-2.5f, m_afAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 16: + Talk(SAY_MAG_COMPLETE); + + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_TOTEM_KARDASH_H, me); + + SetRun(); + break; + } + } + + void JustSummoned(Creature* summoned) + { + if (summoned->GetEntry() == NPC_MURK_BRUTE) + summoned->AI()->Talk(SAY_MAG_NO_ESCAPE); + + if (summoned->isTotem()) + return; + + summoned->SetWalk(false); + summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + summoned->AI()->AttackStart(me); + + } + + void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell) + { + if (pSpell->Id == SPELL_CHAIN_LIGHTNING) + { + if (rand()%10) + return; + + Talk(SAY_MAG_LIGHTNING); + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + if (!me->getVictim()) + return; + + if (m_uiChainLightningTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_CHAIN_LIGHTNING); + m_uiChainLightningTimer = urand(7000, 14000); + } + else + m_uiChainLightningTimer -= uiDiff; + + if (HealthBelowPct(30)) + { + if (m_uiHealTimer <= uiDiff) + { + DoCast(me, SPELL_HEALING_WAVE); + m_uiHealTimer = 5000; + } + else + m_uiHealTimer -= uiDiff; + } + + if (m_uiFrostShockTimer <= uiDiff) + { + DoCast(me->getVictim(), SPELL_FROST_SHOCK); + m_uiFrostShockTimer = urand(7500, 15000); + } + else + m_uiFrostShockTimer -= uiDiff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_creditmarker_visist_with_ancestors +######*/ + +class npc_creditmarker_visit_with_ancestors : public CreatureScript +{ +public: + npc_creditmarker_visit_with_ancestors() : CreatureScript("npc_creditmarker_visit_with_ancestors") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_creditmarker_visit_with_ancestorsAI (creature); + } + + struct npc_creditmarker_visit_with_ancestorsAI : public ScriptedAI + { + npc_creditmarker_visit_with_ancestorsAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* who) + { + if (!who) + return; + + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (CAST_PLR(who)->GetQuestStatus(10085) == QUEST_STATUS_INCOMPLETE) + { + uint32 creditMarkerId = me->GetEntry(); + if ((creditMarkerId >= 18840) && (creditMarkerId <= 18843)) + { + // 18840: Sunspring, 18841: Laughing, 18842: Garadar, 18843: Bleeding + if (!CAST_PLR(who)->GetReqKillOrCastCurrentCount(10085, creditMarkerId)) + CAST_PLR(who)->KilledMonsterCredit(creditMarkerId, me->GetGUID()); + } + } + } + } + }; +}; + +/*###### +## go_corkis_prison and npc_corki +######*/ + +enum CorkiData +{ + // first quest + QUEST_HELP = 9923, + NPC_CORKI = 18445, + NPC_CORKI_CREDIT_1 = 18369, + GO_CORKIS_PRISON = 182349, + CORKI_SAY_THANKS = 0, + // 2nd quest + QUEST_CORKIS_GONE_MISSING_AGAIN = 9924, + NPC_CORKI_2 = 20812, + GO_CORKIS_PRISON_2 = 182350, + CORKI_SAY_PROMISE = 0, + // 3rd quest + QUEST_CHOWAR_THE_PILLAGER = 9955, + NPC_CORKI_3 = 18369, + NPC_CORKI_CREDIT_3 = 18444, + GO_CORKIS_PRISON_3 = 182521, + CORKI_SAY_LAST = 0 +}; + +class go_corkis_prison : public GameObjectScript +{ +public: + go_corkis_prison() : GameObjectScript("go_corkis_prison") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->SetGoState(GO_STATE_READY); + if (go->GetEntry() == GO_CORKIS_PRISON) + { + if (Creature* corki = go->FindNearestCreature(NPC_CORKI, 25, true)) + { + corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()+5, go->GetPositionY(), go->GetPositionZ()); + if (player) + player->KilledMonsterCredit(NPC_CORKI_CREDIT_1, 0); + } + } + + if (go->GetEntry() == GO_CORKIS_PRISON_2) + { + if (Creature* corki = go->FindNearestCreature(NPC_CORKI_2, 25, true)) + { + corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()-5, go->GetPositionY(), go->GetPositionZ()); + if (player) + player->KilledMonsterCredit(NPC_CORKI_2, 0); + } + } + + if (go->GetEntry() == GO_CORKIS_PRISON_3) + { + if (Creature* corki = go->FindNearestCreature(NPC_CORKI_3, 25, true)) + { + corki->GetMotionMaster()->MovePoint(1, go->GetPositionX()+4, go->GetPositionY(), go->GetPositionZ()); + if (player) + player->KilledMonsterCredit(NPC_CORKI_CREDIT_3, 0); + } + } + return true; + } +}; + +class npc_corki : public CreatureScript +{ +public: + npc_corki() : CreatureScript("npc_corki") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_corkiAI(creature); + } + + struct npc_corkiAI : public ScriptedAI + { + npc_corkiAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 Say_Timer; + bool ReleasedFromCage; + + void Reset() + { + Say_Timer = 5000; + ReleasedFromCage = false; + } + + void UpdateAI(uint32 const diff) + { + if (ReleasedFromCage) + { + if (Say_Timer <= diff) + { + me->DespawnOrUnsummon(); + ReleasedFromCage = false; + } + else + Say_Timer -= diff; + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type == POINT_MOTION_TYPE && id == 1) + { + Say_Timer = 5000; + ReleasedFromCage = true; + if (me->GetEntry() == NPC_CORKI) + Talk(CORKI_SAY_THANKS); + if (me->GetEntry() == NPC_CORKI_2) + Talk(CORKI_SAY_PROMISE); + if (me->GetEntry() == NPC_CORKI_3) + Talk(CORKI_SAY_LAST); + } + }; + }; +}; + +/*##### +## npc_kurenai_captive +#####*/ + +enum KurenaiCaptive +{ + SAY_KUR_START = 0, + SAY_KUR_NO_ESCAPE = 1, + SAY_KUR_MORE = 2, + SAY_KUR_MORE_TWO = 3, + SAY_KUR_LIGHTNING = 4, + SAY_KUR_SHOCK = 5, + SAY_KUR_COMPLETE = 6, + + SPELL_KUR_CHAIN_LIGHTNING = 16006, + SPELL_KUR_EARTHBIND_TOTEM = 15786, + SPELL_KUR_FROST_SHOCK = 12548, + SPELL_KUR_HEALING_WAVE = 12491, + + QUEST_TOTEM_KARDASH_A = 9879, + + NPC_KUR_MURK_RAIDER = 18203, + NPC_KUR_MURK_BRUTE = 18211, + NPC_KUR_MURK_SCAVENGER = 18207, + NPC_KUR_MURK_PUTRIFIER = 18202, +}; + +static float kurenaiAmbushA[]= {-1568.805786f, 8533.873047f, 1.958f}; +static float kurenaiAmbushB[]= {-1491.554321f, 8506.483398f, 1.248f}; + +class npc_kurenai_captive : public CreatureScript +{ +public: + npc_kurenai_captive() : CreatureScript("npc_kurenai_captive") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_A) + { + if (npc_kurenai_captiveAI* EscortAI = dynamic_cast(creature->AI())) + { + creature->SetStandState(UNIT_STAND_STATE_STAND); + EscortAI->Start(true, false, player->GetGUID(), quest); + creature->AI()->Talk(SAY_KUR_START); + + creature->SummonCreature(NPC_KUR_MURK_RAIDER, kurenaiAmbushA[0]+2.5f, kurenaiAmbushA[1]-2.5f, kurenaiAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + creature->SummonCreature(NPC_KUR_MURK_BRUTE, kurenaiAmbushA[0]-2.5f, kurenaiAmbushA[1]+2.5f, kurenaiAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + creature->SummonCreature(NPC_KUR_MURK_SCAVENGER, kurenaiAmbushA[0], kurenaiAmbushA[1], kurenaiAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + } + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kurenai_captiveAI(creature); + } + + struct npc_kurenai_captiveAI : public npc_escortAI + { + npc_kurenai_captiveAI(Creature* creature) : npc_escortAI(creature) { } + + uint32 ChainLightningTimer; + uint32 HealTimer; + uint32 FrostShockTimer; + + void Reset() + { + ChainLightningTimer = 1000; + HealTimer = 0; + FrostShockTimer = 6000; + } + + void EnterCombat(Unit* /*who*/) + { + DoCast(me, SPELL_KUR_EARTHBIND_TOTEM, false); + } + + void JustDied(Unit* /*killer*/) + { + if (!HasEscortState(STATE_ESCORT_ESCORTING)) + return; + + if (Player* player = GetPlayerForEscort()) + { + if (player->GetQuestStatus(QUEST_TOTEM_KARDASH_A) != QUEST_STATUS_COMPLETE) + player->FailQuest(QUEST_TOTEM_KARDASH_A); + } + } + + void WaypointReached(uint32 waypointId) + { + switch (waypointId) + { + case 3: + { + Talk(SAY_KUR_MORE); + + if (me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0], kurenaiAmbushB[1], kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000)) + Talk(SAY_KUR_MORE_TWO); + + me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0]-2.5f, kurenaiAmbushB[1]-2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(NPC_KUR_MURK_SCAVENGER, kurenaiAmbushB[0]+2.5f, kurenaiAmbushB[1]+2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(NPC_KUR_MURK_SCAVENGER, kurenaiAmbushB[0]+2.5f, kurenaiAmbushB[1]-2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + } + case 7: + { + Talk(SAY_KUR_COMPLETE); + + if (Player* player = GetPlayerForEscort()) + player->GroupEventHappens(QUEST_TOTEM_KARDASH_A, me); + + SetRun(); + break; + } + } + } + + void JustSummoned(Creature* summoned) + { + if (summoned->GetEntry() == NPC_KUR_MURK_BRUTE) + Talk(SAY_KUR_NO_ESCAPE); + + // This function is for when we summoned enemies to fight - so that does NOT mean we should make our totem count in this! + if (summoned->isTotem()) + return; + + summoned->SetWalk(false); + summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + summoned->AI()->AttackStart(me); + } + + void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell) + { + if (spell->Id == SPELL_KUR_CHAIN_LIGHTNING) + { + if (rand()%30) + return; + + Talk(SAY_KUR_LIGHTNING); + } + + if (spell->Id == SPELL_KUR_FROST_SHOCK) + { + if (rand()%30) + return; + + Talk(SAY_KUR_SHOCK); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + if (ChainLightningTimer <= diff) + { + DoCast(me->getVictim(), SPELL_KUR_CHAIN_LIGHTNING); + ChainLightningTimer = urand(7000,14000); + } else ChainLightningTimer -= diff; + + if (HealthBelowPct(30)) + { + if (HealTimer <= diff) + { + DoCast(me, SPELL_KUR_HEALING_WAVE); + HealTimer = 5000; + } else HealTimer -= diff; + } + + if (FrostShockTimer <= diff) + { + DoCast(me->getVictim(), SPELL_KUR_FROST_SHOCK); + FrostShockTimer = urand(7500,15000); + } else FrostShockTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## go_warmaul_prison +######*/ + +enum FindingTheSurvivorsData +{ + QUEST_FINDING_THE_SURVIVORS = 9948, + NPC_MAGHAR_PRISONER = 18428, + + SAY_FREE = 0, +}; + +class go_warmaul_prison : public GameObjectScript +{ + public: + go_warmaul_prison() : GameObjectScript("go_warmaul_prison") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + if (player->GetQuestStatus(QUEST_FINDING_THE_SURVIVORS) != QUEST_STATUS_INCOMPLETE) + return false; + + if (Creature* prisoner = go->FindNearestCreature(NPC_MAGHAR_PRISONER, 5.0f)) + { + player->KilledMonsterCredit(NPC_MAGHAR_PRISONER, 0); + + prisoner->AI()->Talk(SAY_FREE, player->GetGUID()); + prisoner->DespawnOrUnsummon(6000); + } + return true; + } +}; + +void AddSC_nagrand() +{ + new npc_greatmother_geyah(); + new npc_maghar_captive(); + new npc_creditmarker_visit_with_ancestors(); + new npc_corki(); + new go_corkis_prison(); + new npc_kurenai_captive(); + new go_warmaul_prison(); +} diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp new file mode 100644 index 00000000000..769ee7dc68d --- /dev/null +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -0,0 +1,1077 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Netherstorm +SD%Complete: 80 +SDComment: Quest support: 10337, 10438, 10652 (special flight paths), 10299, 10321, 10322, 10323, 10329, 10330, 10338, 10365(Shutting Down Manaforge), 10198, 10191 +SDCategory: Netherstorm +EndScriptData */ + +/* ContentData +npc_manaforge_control_console +go_manaforge_control_console +npc_commander_dawnforge +npc_bessy +npc_maxx_a_million +go_captain_tyralius_prison +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" + +/*###### +## npc_manaforge_control_console +######*/ + +//used by 20209, 20417, 20418, 20440, signed for 20209 +enum eManaforgeConsoleData +{ + EMOTE_START = 0, + EMOTE_60 = 1, + EMOTE_30 = 2, + EMOTE_10 = 3, + EMOTE_COMPLETE = 4, + EMOTE_ABORT = 5, + + ENTRY_BNAAR_C_CONSOLE = 20209, + ENTRY_CORUU_C_CONSOLE = 20417, + ENTRY_DURO_C_CONSOLE = 20418, + ENTRY_ARA_C_CONSOLE = 20440, + + ENTRY_SUNFURY_TECH = 20218, + ENTRY_SUNFURY_PROT = 20436, + + ENTRY_ARA_TECH = 20438, + ENTRY_ARA_ENGI = 20439, + ENTRY_ARA_GORKLONN = 20460, + + SPELL_DISABLE_VISUAL = 35031, + SPELL_INTERRUPT_1 = 35016, //ACID mobs should cast this + SPELL_INTERRUPT_2 = 35176, //ACID mobs should cast this (Manaforge Ara-version) +}; + +class npc_manaforge_control_console : public CreatureScript +{ +public: + npc_manaforge_control_console() : CreatureScript("npc_manaforge_control_console") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_manaforge_control_consoleAI (creature); + } + + struct npc_manaforge_control_consoleAI : public ScriptedAI + { + npc_manaforge_control_consoleAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 Event_Timer; + uint32 Wave_Timer; + uint32 Phase; + bool Wave; + uint64 someplayer; + uint64 goConsole; + Creature* add; + + void Reset() + { + Event_Timer = 3000; + Wave_Timer = 0; + Phase = 1; + Wave = false; + someplayer = 0; + goConsole = 0; + add = NULL; + } + + void EnterCombat(Unit* /*who*/) {} + + /*void SpellHit(Unit* caster, const SpellInfo* spell) + { + //we have no way of telling the Creature was hit by spell -> got aura applied after 10-12 seconds + //then no way for the mobs to actually stop the shutdown as intended. + if (spell->Id == SPELL_INTERRUPT_1) + DoSay("Silence! I kill you!", LANG_UNIVERSAL, NULL); + }*/ + + void JustDied(Unit* /*killer*/) + { + Talk(EMOTE_ABORT); + + if (someplayer) + { + Unit* p = Unit::GetUnit(*me, someplayer); + if (p && p->GetTypeId() == TYPEID_PLAYER) + { + switch (me->GetEntry()) + { + case ENTRY_BNAAR_C_CONSOLE: + CAST_PLR(p)->FailQuest(10299); + CAST_PLR(p)->FailQuest(10329); + break; + case ENTRY_CORUU_C_CONSOLE: + CAST_PLR(p)->FailQuest(10321); + CAST_PLR(p)->FailQuest(10330); + break; + case ENTRY_DURO_C_CONSOLE: + CAST_PLR(p)->FailQuest(10322); + CAST_PLR(p)->FailQuest(10338); + break; + case ENTRY_ARA_C_CONSOLE: + CAST_PLR(p)->FailQuest(10323); + CAST_PLR(p)->FailQuest(10365); + break; + } + } + } + + if (goConsole) + { + if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + } + } + + void DoWaveSpawnForCreature(Creature* creature) + { + switch (creature->GetEntry()) + { + case ENTRY_BNAAR_C_CONSOLE: + if (rand()%2) + { + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2933.68f, 4162.55f, 164.00f, 1.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2927.36f, 4212.97f, 164.00f); + } + else + { + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2927.36f, 4212.97f, 164.00f, 4.94f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2933.68f, 4162.55f, 164.00f); + } + Wave_Timer = 30000; + break; + case ENTRY_CORUU_C_CONSOLE: + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2445.21f, 2765.26f, 134.49f, 3.93f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2424.21f, 2740.15f, 133.81f); + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2429.86f, 2731.85f, 134.53f, 1.31f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2435.37f, 2766.04f, 133.81f); + Wave_Timer = 20000; + break; + case ENTRY_DURO_C_CONSOLE: + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2986.80f, 2205.36f, 165.37f, 3.74f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2985.15f, 2197.32f, 164.79f); + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2952.91f, 2191.20f, 165.32f, 0.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2060.01f, 2185.27f, 164.67f); + Wave_Timer = 15000; + break; + case ENTRY_ARA_C_CONSOLE: + if (rand()%2) + { + add = me->SummonCreature(ENTRY_ARA_TECH, 4035.11f, 4038.97f, 194.27f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); + add = me->SummonCreature(ENTRY_ARA_TECH, 4033.66f, 4036.79f, 194.28f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); + add = me->SummonCreature(ENTRY_ARA_TECH, 4037.13f, 4037.30f, 194.23f, 2.57f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4003.42f, 4040.19f, 193.49f); + } + else + { + add = me->SummonCreature(ENTRY_ARA_TECH, 3099.59f, 4049.30f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); + add = me->SummonCreature(ENTRY_ARA_TECH, 3999.72f, 4046.75f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); + add = me->SummonCreature(ENTRY_ARA_TECH, 3996.81f, 4048.26f, 194.22f, 0.05f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4028.01f, 4035.17f, 193.59f); + } + Wave_Timer = 15000; + break; + } + } + void DoFinalSpawnForCreature(Creature* creature) + { + switch (creature->GetEntry()) + { + case ENTRY_BNAAR_C_CONSOLE: + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2946.52f, 4201.42f, 163.47f, 3.54f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2927.49f, 4192.81f, 163.00f); + break; + case ENTRY_CORUU_C_CONSOLE: + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2453.88f, 2737.85f, 133.27f, 2.59f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2441.62f, 2735.32f, 134.49f, 1.97f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2450.73f, 2754.50f, 134.49f, 3.29f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2433.96f, 2751.53f, 133.85f); + break; + case ENTRY_DURO_C_CONSOLE: + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2956.18f, 2202.85f, 165.32f, 5.45f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); + add = me->SummonCreature(ENTRY_SUNFURY_TECH, 2975.30f, 2211.50f, 165.32f, 4.55f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); + add = me->SummonCreature(ENTRY_SUNFURY_PROT, 2965.02f, 2217.45f, 164.16f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 2972.27f, 2193.22f, 164.48f); + break; + case ENTRY_ARA_C_CONSOLE: + add = me->SummonCreature(ENTRY_ARA_ENGI, 3994.51f, 4020.46f, 192.18f, 0.91f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4008.35f, 4035.04f, 192.70f); + add = me->SummonCreature(ENTRY_ARA_GORKLONN, 4021.56f, 4059.35f, 193.59f, 4.44f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 120000); + if (add) add->GetMotionMaster()->MovePoint(0, 4016.62f, 4039.89f, 193.46f); + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (Event_Timer <= diff) + { + switch (Phase) + { + case 1: + if (someplayer) + { + Unit* u = Unit::GetUnit(*me, someplayer); + if (u && u->GetTypeId() == TYPEID_PLAYER) + Talk(EMOTE_START, u->GetGUID()); + } + Event_Timer = 60000; + Wave = true; + ++Phase; + break; + case 2: + Talk(EMOTE_60); + Event_Timer = 30000; + ++Phase; + break; + case 3: + Talk(EMOTE_30); + Event_Timer = 20000; + DoFinalSpawnForCreature(me); + ++Phase; + break; + case 4: + Talk(EMOTE_10); + Event_Timer = 10000; + Wave = false; + ++Phase; + break; + case 5: + Talk(EMOTE_COMPLETE); + if (someplayer) + { + Unit* u = Unit::GetUnit(*me, someplayer); + if (u && u->GetTypeId() == TYPEID_PLAYER) + CAST_PLR(u)->KilledMonsterCredit(me->GetEntry(), me->GetGUID()); + DoCast(me, SPELL_DISABLE_VISUAL); + } + if (goConsole) + { + if (GameObject* go = GameObject::GetGameObject(*me, goConsole)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + } + ++Phase; + break; + } + } else Event_Timer -= diff; + + if (Wave) + { + if (Wave_Timer <= diff) + { + DoWaveSpawnForCreature(me); + } else Wave_Timer -= diff; + } + } + }; +}; + +/*###### +## go_manaforge_control_console +######*/ + +//TODO: clean up this workaround when Trinity adds support to do it properly (with gossip selections instead of instant summon) +class go_manaforge_control_console : public GameObjectScript +{ +public: + go_manaforge_control_console() : GameObjectScript("go_manaforge_control_console") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) + { + player->PrepareQuestMenu(go->GetGUID()); + player->SendPreparedQuest(go->GetGUID()); + } + + Creature* manaforge = NULL; + + switch (go->GetAreaId()) + { + case 3726: //b'naar + if ((player->GetQuestStatus(10299) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10329) == QUEST_STATUS_INCOMPLETE) && + player->HasItemCount(29366)) + manaforge = player->SummonCreature(ENTRY_BNAAR_C_CONSOLE, 2918.95f, 4189.98f, 161.88f, 0.34f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); + break; + case 3730: //coruu + if ((player->GetQuestStatus(10321) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10330) == QUEST_STATUS_INCOMPLETE) && + player->HasItemCount(29396)) + manaforge = player->SummonCreature(ENTRY_CORUU_C_CONSOLE, 2426.77f, 2750.38f, 133.24f, 2.14f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); + break; + case 3734: //duro + if ((player->GetQuestStatus(10322) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10338) == QUEST_STATUS_INCOMPLETE) && + player->HasItemCount(29397)) + manaforge = player->SummonCreature(ENTRY_DURO_C_CONSOLE, 2976.48f, 2183.29f, 163.20f, 1.85f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); + break; + case 3722: //ara + if ((player->GetQuestStatus(10323) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10365) == QUEST_STATUS_INCOMPLETE) && + player->HasItemCount(29411)) + manaforge = player->SummonCreature(ENTRY_ARA_C_CONSOLE, 4013.71f, 4028.76f, 192.10f, 1.25f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 125000); + break; + } + + if (manaforge) + { + CAST_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->someplayer = player->GetGUID(); + CAST_AI(npc_manaforge_control_console::npc_manaforge_control_consoleAI, manaforge->AI())->goConsole = go->GetGUID(); + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + } + return true; + } +}; + +/*###### +## npc_commander_dawnforge +######*/ + +// The Speech of Dawnforge, Ardonis & Pathaleon +enum eCommanderDawnforgeData +{ + SAY_COMMANDER_DAWNFORGE_1 = 0, + SAY_COMMANDER_DAWNFORGE_2 = 1, + SAY_COMMANDER_DAWNFORGE_3 = 2, + SAY_COMMANDER_DAWNFORGE_4 = 3, + SAY_COMMANDER_DAWNFORGE_5 = 4, + + SAY_ARCANIST_ARDONIS_1 = 0, + SAY_ARCANIST_ARDONIS_2 = 1, + + SAY_PATHALEON_CULATOR_IMAGE_1 = 0, + SAY_PATHALEON_CULATOR_IMAGE_2 = 1, + SAY_PATHALEON_CULATOR_IMAGE_2_1 = 2, + SAY_PATHALEON_CULATOR_IMAGE_2_2 = 3, + + QUEST_INFO_GATHERING = 10198, + SPELL_SUNFURY_DISGUISE = 34603, +}; + +// Entries of Arcanist Ardonis, Commander Dawnforge, Pathaleon the Curators Image +const uint32 CreatureEntry[3] = +{ + 19830, // Ardonis + 19831, // Dawnforge + 21504 // Pathaleon +}; + +class npc_commander_dawnforge : public CreatureScript +{ +public: + npc_commander_dawnforge() : CreatureScript("npc_commander_dawnforge") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_commander_dawnforgeAI(creature); + } + + struct npc_commander_dawnforgeAI : public ScriptedAI + { + npc_commander_dawnforgeAI(Creature* creature) : ScriptedAI(creature) { Reset(); } + + uint64 PlayerGUID; + uint64 ardonisGUID; + uint64 pathaleonGUID; + + uint32 Phase; + uint32 PhaseSubphase; + uint32 Phase_Timer; + bool isEvent; + + float angle_dawnforge; + float angle_ardonis; + + void Reset() + { + PlayerGUID = 0; + ardonisGUID = 0; + pathaleonGUID = 0; + + Phase = 1; + PhaseSubphase = 0; + Phase_Timer = 4000; + isEvent = false; + } + + void EnterCombat(Unit* /*who*/) { } + + void JustSummoned(Creature* summoned) + { + pathaleonGUID = summoned->GetGUID(); + } + + // Emote Ardonis and Pathaleon + void Turn_to_Pathaleons_Image() + { + Creature* ardonis = Unit::GetCreature(*me, ardonisGUID); + Creature* pathaleon = Unit::GetCreature(*me, pathaleonGUID); + Player* player = Unit::GetPlayer(*me, PlayerGUID); + + if (!ardonis || !pathaleon || !player) + return; + + //Calculate the angle to Pathaleon + angle_dawnforge = me->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY()); + angle_ardonis = ardonis->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY()); + + //Turn Dawnforge and update + me->SetOrientation(angle_dawnforge); + me->SendUpdateToPlayer(player); + //Turn Ardonis and update + ardonis->SetOrientation(angle_ardonis); + ardonis->SendUpdateToPlayer(player); + + //Set them to kneel + me->SetStandState(UNIT_STAND_STATE_KNEEL); + ardonis->SetStandState(UNIT_STAND_STATE_KNEEL); + } + + //Set them back to each other + void Turn_to_eachother() + { + if (Unit* ardonis = Unit::GetUnit(*me, ardonisGUID)) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + + if (!player) + return; + + angle_dawnforge = me->GetAngle(ardonis->GetPositionX(), ardonis->GetPositionY()); + angle_ardonis = ardonis->GetAngle(me->GetPositionX(), me->GetPositionY()); + + //Turn Dawnforge and update + me->SetOrientation(angle_dawnforge); + me->SendUpdateToPlayer(player); + //Turn Ardonis and update + ardonis->SetOrientation(angle_ardonis); + ardonis->SendUpdateToPlayer(player); + + //Set state + me->SetStandState(UNIT_STAND_STATE_STAND); + ardonis->SetStandState(UNIT_STAND_STATE_STAND); + } + } + + bool CanStartEvent(Player* player) + { + if (!isEvent) + { + Creature* ardonis = me->FindNearestCreature(CreatureEntry[0], 10.0f); + if (!ardonis) + return false; + + ardonisGUID = ardonis->GetGUID(); + PlayerGUID = player->GetGUID(); + + isEvent = true; + + Turn_to_eachother(); + return true; + } + + sLog->outDebug(LOG_FILTER_TSCR, "npc_commander_dawnforge event already in progress, need to wait."); + return false; + } + + void UpdateAI(const uint32 diff) + { + //Is event even running? + if (!isEvent) + return; + + //Phase timing + if (Phase_Timer >= diff) + { + Phase_Timer -= diff; + return; + } + + Creature* ardonis = Creature::GetCreature(*me, ardonisGUID); + Creature* pathaleon = Creature::GetCreature(*me, pathaleonGUID); + Player* player = Unit::GetPlayer(*me, PlayerGUID); + + if (!ardonis || !player) + { + Reset(); + return; + } + + if (Phase > 4 && !pathaleon) + { + Reset(); + return; + } + + //Phase 1 Dawnforge say + switch (Phase) + { + case 1: + Talk(SAY_COMMANDER_DAWNFORGE_1); + ++Phase; + Phase_Timer = 16000; + break; + //Phase 2 Ardonis say + case 2: + ardonis->AI()->Talk(SAY_ARCANIST_ARDONIS_1); + ++Phase; + Phase_Timer = 16000; + break; + //Phase 3 Dawnforge say + case 3: + Talk(SAY_COMMANDER_DAWNFORGE_2); + ++Phase; + Phase_Timer = 16000; + break; + //Phase 4 Pathaleon spawns up to phase 9 + case 4: + //spawn pathaleon's image + me->SummonCreature(CreatureEntry[2], 2325.851563f, 2799.534668f, 133.084229f, 6.038996f, TEMPSUMMON_TIMED_DESPAWN, 90000); + ++Phase; + Phase_Timer = 500; + break; + //Phase 5 Pathaleon say + case 5: + pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_1); + ++Phase; + Phase_Timer = 6000; + break; + //Phase 6 + case 6: + switch (PhaseSubphase) + { + //Subphase 1: Turn Dawnforge and Ardonis + case 0: + Turn_to_Pathaleons_Image(); + ++PhaseSubphase; + Phase_Timer = 8000; + break; + //Subphase 2 Dawnforge say + case 1: + Talk(SAY_COMMANDER_DAWNFORGE_3); + PhaseSubphase = 0; + ++Phase; + Phase_Timer = 8000; + break; + } + break; + //Phase 7 Pathaleons say 3 Sentence, every sentence need a subphase + case 7: + switch (PhaseSubphase) + { + //Subphase 1 + case 0: + pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_2); + ++PhaseSubphase; + Phase_Timer = 12000; + break; + //Subphase 2 + case 1: + pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_2_1); + ++PhaseSubphase; + Phase_Timer = 16000; + break; + //Subphase 3 + case 2: + pathaleon->AI()->Talk(SAY_PATHALEON_CULATOR_IMAGE_2_2); + PhaseSubphase = 0; + ++Phase; + Phase_Timer = 10000; + break; + } + break; + //Phase 8 Dawnforge & Ardonis say + case 8: + Talk(SAY_COMMANDER_DAWNFORGE_4); + ardonis->AI()->Talk(SAY_ARCANIST_ARDONIS_2); + ++Phase; + Phase_Timer = 4000; + break; + //Phase 9 Pathaleons Despawn, Reset Dawnforge & Ardonis angle + case 9: + Turn_to_eachother(); + //hide pathaleon, unit will despawn shortly + pathaleon->SetVisible(false); + PhaseSubphase = 0; + ++Phase; + Phase_Timer = 3000; + break; + //Phase 10 Dawnforge say + case 10: + Talk(SAY_COMMANDER_DAWNFORGE_5); + player->AreaExploredOrEventHappens(QUEST_INFO_GATHERING); + Reset(); + break; + } + } + }; +}; + +class at_commander_dawnforge : public AreaTriggerScript +{ +public: + at_commander_dawnforge() : AreaTriggerScript("at_commander_dawnforge") { } + + bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) + { + //if player lost aura or not have at all, we should not try start event. + if (!player->HasAura(SPELL_SUNFURY_DISGUISE)) + return false; + + if (player->isAlive() && player->GetQuestStatus(QUEST_INFO_GATHERING) == QUEST_STATUS_INCOMPLETE) + { + Creature* Dawnforge = player->FindNearestCreature(CreatureEntry[1], 30.0f); + if (!Dawnforge) + return false; + + if (CAST_AI(npc_commander_dawnforge::npc_commander_dawnforgeAI, Dawnforge->AI())->CanStartEvent(player)) + return true; + } + return false; + } +}; + +/*###### +## npc_professor_dabiri +######*/ +enum eProfessorDabiriData +{ + SPELL_PHASE_DISTRUPTOR = 35780, + + //WHISPER_DABIRI = 0, not existing in database + + QUEST_DIMENSIUS = 10439, + QUEST_ON_NETHERY_WINGS = 10438, +}; + +#define GOSSIP_ITEM "I need a new phase distruptor, Professor" + +class npc_professor_dabiri : public CreatureScript +{ +public: + npc_professor_dabiri() : CreatureScript("npc_professor_dabiri") { } + + //OnQuestAccept: + //if (quest->GetQuestId() == QUEST_DIMENSIUS) + //creature->AI()->Talk(WHISPER_DABIRI, player->GetGUID()); + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + creature->CastSpell(player, SPELL_PHASE_DISTRUPTOR, false); + player->CLOSE_GOSSIP_MENU(); + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_ON_NETHERY_WINGS) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(29778)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +## mob_phase_hunter +######*/ + +enum ePhaseHunterData +{ + QUEST_RECHARGING_THE_BATTERIES = 10190, + + NPC_PHASE_HUNTER_ENTRY = 18879, + NPC_DRAINED_PHASE_HUNTER_ENTRY = 19595, + + EMOTE_WEAK = 0, + + // Spells + SPELL_RECHARGING_BATTERY = 34219, + SPELL_PHASE_SLIP = 36574, + SPELL_MANA_BURN = 13321, + SPELL_MATERIALIZE = 34804, + SPELL_DE_MATERIALIZE = 34814, +}; + +class mob_phase_hunter : public CreatureScript +{ +public: + mob_phase_hunter() : CreatureScript("mob_phase_hunter") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_phase_hunterAI (creature); + } + + struct mob_phase_hunterAI : public ScriptedAI + { + mob_phase_hunterAI(Creature* creature) : ScriptedAI(creature) {} + + bool Weak; + bool Materialize; + bool Drained; + uint8 WeakPercent; + + Player* player; + uint64 PlayerGUID; + + uint32 ManaBurnTimer; + + void Reset() + { + Weak = false; + Materialize = false; + Drained = false; + WeakPercent = 25 + (rand() % 16); // 25-40 + + PlayerGUID = 0; + + ManaBurnTimer = 5000 + (rand() % 3 * 1000); // 5-8 sec cd + + if (me->GetEntry() == NPC_DRAINED_PHASE_HUNTER_ENTRY) + me->UpdateEntry(NPC_PHASE_HUNTER_ENTRY); + } + + void EnterCombat(Unit* who) + { + if (who->GetTypeId() == TYPEID_PLAYER) + PlayerGUID = who->GetGUID(); + } + + //void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/) + //{ + // DoCast(me, SPELL_DE_MATERIALIZE); + //} + + void UpdateAI(const uint32 diff) + { + if (!Materialize) + { + DoCast(me, SPELL_MATERIALIZE); + Materialize = true; + } + + if (me->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || me->HasUnitState(UNIT_STATE_ROOT)) // if the mob is rooted/slowed by spells eg.: Entangling Roots, Frost Nova, Hamstring, Crippling Poison, etc. => remove it + DoCast(me, SPELL_PHASE_SLIP); + + if (!UpdateVictim()) + return; + + // some code to cast spell Mana Burn on random target which has mana + if (ManaBurnTimer <= diff) + { + std::list AggroList = me->getThreatManager().getThreatList(); + std::list UnitsWithMana; + + for (std::list::const_iterator itr = AggroList.begin(); itr != AggroList.end(); ++itr) + { + if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) + { + if (unit->GetCreateMana() > 0) + UnitsWithMana.push_back(unit); + } + } + if (!UnitsWithMana.empty()) + { + DoCast(Trinity::Containers::SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN); + ManaBurnTimer = 8000 + (rand() % 10 * 1000); // 8-18 sec cd + } + else + ManaBurnTimer = 3500; + } else ManaBurnTimer -= diff; + + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) // start: support for quest 10190 + { + if (!Weak && HealthBelowPct(WeakPercent) + && player->GetQuestStatus(QUEST_RECHARGING_THE_BATTERIES) == QUEST_STATUS_INCOMPLETE) + { + Talk(EMOTE_WEAK); + Weak = true; + } + if (Weak && !Drained && me->HasAura(SPELL_RECHARGING_BATTERY)) + { + Drained = true; + int32 uHpPct = int32(me->GetHealthPct()); + + me->UpdateEntry(NPC_DRAINED_PHASE_HUNTER_ENTRY); + + me->SetHealth(me->CountPctFromMaxHealth(uHpPct)); + me->LowerPlayerDamageReq(me->GetMaxHealth() - me->GetHealth()); + me->SetInCombatWith(player); + } + } // end: support for quest 10190 + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_bessy +######*/ +enum eBessyData +{ + Q_ALMABTRIEB = 10337, + N_THADELL = 20464, + SPAWN_FIRST = 20512, + SPAWN_SECOND = 19881, + SAY_THADELL_1 = 0, + SAY_THADELL_2 = 1, +}; + +class npc_bessy : public CreatureScript +{ +public: + npc_bessy() : CreatureScript("npc_bessy") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == Q_ALMABTRIEB) + { + creature->setFaction(113); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_bessyAI(creature); + } + + struct npc_bessyAI : public npc_escortAI + { + npc_bessyAI(Creature* creature) : npc_escortAI(creature) {} + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(Q_ALMABTRIEB); + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 3: //first spawn + me->SummonCreature(SPAWN_FIRST, 2449.67f, 2183.11f, 96.85f, 6.20f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_FIRST, 2449.53f, 2184.43f, 96.36f, 6.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_FIRST, 2449.85f, 2186.34f, 97.57f, 6.08f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 7: + me->SummonCreature(SPAWN_SECOND, 2309.64f, 2186.24f, 92.25f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(SPAWN_SECOND, 2309.25f, 2183.46f, 91.75f, 6.22f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 12: + player->GroupEventHappens(Q_ALMABTRIEB, me); + if (me->FindNearestCreature(N_THADELL, 30)) + Talk(SAY_THADELL_1); + break; + case 13: + if (me->FindNearestCreature(N_THADELL, 30)) + Talk(SAY_THADELL_2, player->GetGUID()); + break; + } + } + + void JustSummoned(Creature* summoned) + { + summoned->AI()->AttackStart(me); + } + + void Reset() + { + me->RestoreFaction(); + } + }; +}; + +/*###### +## npc_maxx_a_million +######*/ + +enum +{ + QUEST_MARK_V_IS_ALIVE = 10191, + GO_DRAENEI_MACHINE = 183771 +}; + +class npc_maxx_a_million_escort : public CreatureScript +{ +public: + npc_maxx_a_million_escort() : CreatureScript("npc_maxx_a_million_escort") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_maxx_a_million_escortAI(creature); + } + + struct npc_maxx_a_million_escortAI : public npc_escortAI + { + npc_maxx_a_million_escortAI(Creature* creature) : npc_escortAI(creature) {} + + bool bTake; + uint32 uiTakeTimer; + + void Reset() + { + bTake=false; + uiTakeTimer=3000; + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 7: + case 17: + case 29: + //Find Object and "work" + if (GetClosestGameObjectWithEntry(me, GO_DRAENEI_MACHINE, INTERACTION_DISTANCE)) + { + // take the GO -> animation + me->HandleEmoteCommand(EMOTE_STATE_LOOT); + SetEscortPaused(true); + bTake=true; + } + break; + case 36: //return and quest_complete + player->CompleteQuest(QUEST_MARK_V_IS_ALIVE); + break; + } + } + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + player->FailQuest(QUEST_MARK_V_IS_ALIVE); + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (bTake) + { + if (uiTakeTimer < uiDiff) + { + me->HandleEmoteCommand(EMOTE_STATE_NONE); + if (GameObject* go = GetClosestGameObjectWithEntry(me, GO_DRAENEI_MACHINE, INTERACTION_DISTANCE)) + { + SetEscortPaused(false); + bTake=false; + uiTakeTimer = 3000; + go->Delete(); + } + } + else + uiTakeTimer -= uiDiff; + } + DoMeleeAttackIfReady(); + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_MARK_V_IS_ALIVE) + { + if (npc_maxx_a_million_escortAI* pEscortAI = CAST_AI(npc_maxx_a_million_escort::npc_maxx_a_million_escortAI, creature->AI())) + { + creature->setFaction(113); + pEscortAI->Start(false, false, player->GetGUID()); + } + } + return true; + } +}; + +/*###### +## go_captain_tyralius_prison +######*/ + +enum CaptainTyralius +{ + NPC_CAPTAIN_TYRALIUS = 20787, + SAY_FREE = 0, +}; + +class go_captain_tyralius_prison : public GameObjectScript +{ + public: + go_captain_tyralius_prison() : GameObjectScript("go_captain_tyralius_prison") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + go->UseDoorOrButton(); + if (Creature* tyralius = go->FindNearestCreature(NPC_CAPTAIN_TYRALIUS, 1.0f)) + { + player->KilledMonsterCredit(NPC_CAPTAIN_TYRALIUS, 0); + tyralius->AI()->Talk(SAY_FREE); + tyralius->DespawnOrUnsummon(8000); + } + return true; + } +}; + +void AddSC_netherstorm() +{ + new go_manaforge_control_console(); + new npc_manaforge_control_console(); + new npc_commander_dawnforge(); + new at_commander_dawnforge(); + new npc_professor_dabiri(); + new mob_phase_hunter(); + new npc_bessy(); + new npc_maxx_a_million_escort(); + new go_captain_tyralius_prison(); +} diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp new file mode 100644 index 00000000000..0a016f0923c --- /dev/null +++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp @@ -0,0 +1,1998 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Shadowmoon_Valley +SD%Complete: 100 +SDComment: Quest support: 10519, 10583, 10601, 10804, 10854, 10458, 10481, 10480, 11082, 10781, 10451. Vendor Drake Dealer Hurlunk. +SDCategory: Shadowmoon Valley +EndScriptData */ + +/* ContentData +mob_mature_netherwing_drake +mob_enslaved_netherwing_drake +npc_drake_dealer_hurlunk +npcs_flanis_swiftwing_and_kagrosh +npc_murkblood_overseer +npc_karynaku +npc_oronok_tornheart +npc_overlord_morghor +npc_earthmender_wilda +mob_torloth_the_magnificent +mob_illidari_spawn +npc_lord_illidan_stormrage +go_crystal_prison +npc_enraged_spirit +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Group.h" +#include "SpellScript.h" +#include "Player.h" +#include "WorldSession.h" + +/*##### +# mob_mature_netherwing_drake +#####*/ + +enum eMatureNetherwing +{ + SAY_JUST_EATEN = 0, + + SPELL_PLACE_CARCASS = 38439, + SPELL_JUST_EATEN = 38502, + SPELL_NETHER_BREATH = 38467, + POINT_ID = 1, + + GO_CARCASS = 185155, + + QUEST_KINDNESS = 10804, + NPC_EVENT_PINGER = 22131 +}; + +class mob_mature_netherwing_drake : public CreatureScript +{ +public: + mob_mature_netherwing_drake() : CreatureScript("mob_mature_netherwing_drake") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_mature_netherwing_drakeAI(creature); + } + + struct mob_mature_netherwing_drakeAI : public ScriptedAI + { + mob_mature_netherwing_drakeAI(Creature* creature) : ScriptedAI(creature) { } + + uint64 uiPlayerGUID; + + bool bCanEat; + bool bIsEating; + + uint32 EatTimer; + uint32 CastTimer; + + void Reset() + { + uiPlayerGUID = 0; + + bCanEat = false; + bIsEating = false; + + EatTimer = 5000; + CastTimer = 5000; + } + + void SpellHit(Unit* pCaster, SpellInfo const* spell) + { + if (bCanEat || bIsEating) + return; + + if (pCaster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_PLACE_CARCASS && !me->HasAura(SPELL_JUST_EATEN)) + { + uiPlayerGUID = pCaster->GetGUID(); + bCanEat = true; + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id == POINT_ID) + { + bIsEating = true; + EatTimer = 7000; + me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK_UNARMED); + } + } + + void UpdateAI(const uint32 diff) + { + if (bCanEat || bIsEating) + { + if (EatTimer <= diff) + { + if (bCanEat && !bIsEating) + { + if (Unit* unit = Unit::GetUnit(*me, uiPlayerGUID)) + { + if (GameObject* go = unit->FindNearestGameObject(GO_CARCASS, 10)) + { + if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) + me->GetMotionMaster()->MovementExpired(); + + me->GetMotionMaster()->MoveIdle(); + me->StopMoving(); + + me->GetMotionMaster()->MovePoint(POINT_ID, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ()); + } + } + bCanEat = false; + } + else if (bIsEating) + { + DoCast(me, SPELL_JUST_EATEN); + Talk(SAY_JUST_EATEN); + + if (Player* pPlr = Unit::GetPlayer(*me, uiPlayerGUID)) + { + pPlr->KilledMonsterCredit(NPC_EVENT_PINGER, 0); + + if (GameObject* go = pPlr->FindNearestGameObject(GO_CARCASS, 10)) + go->Delete(); + } + + Reset(); + me->GetMotionMaster()->Clear(); + } + } + else + EatTimer -= diff; + + return; + } + + if (!UpdateVictim()) + return; + + if (CastTimer <= diff) + { + DoCast(me->getVictim(), SPELL_NETHER_BREATH); + CastTimer = 5000; + } else CastTimer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*### +# mob_enslaved_netherwing_drake +####*/ + +#define FACTION_DEFAULT 62 +#define FACTION_FRIENDLY 1840 // Not sure if this is correct, it was taken off of Mordenai. + +#define SPELL_HIT_FORCE_OF_NELTHARAKU 38762 +#define SPELL_FORCE_OF_NELTHARAKU 38775 + +#define CREATURE_DRAGONMAW_SUBJUGATOR 21718 +#define CREATURE_ESCAPE_DUMMY 22317 + +class mob_enslaved_netherwing_drake : public CreatureScript +{ +public: + mob_enslaved_netherwing_drake() : CreatureScript("mob_enslaved_netherwing_drake") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_enslaved_netherwing_drakeAI(creature); + } + + struct mob_enslaved_netherwing_drakeAI : public ScriptedAI + { + mob_enslaved_netherwing_drakeAI(Creature* creature) : ScriptedAI(creature) + { + PlayerGUID = 0; + Tapped = false; + Reset(); + } + + uint64 PlayerGUID; + uint32 FlyTimer; + bool Tapped; + + void Reset() + { + if (!Tapped) + me->setFaction(FACTION_DEFAULT); + + FlyTimer = 10000; + me->SetDisableGravity(false); + me->SetVisible(true); + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (!caster) + return; + + if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == SPELL_HIT_FORCE_OF_NELTHARAKU && !Tapped) + { + Tapped = true; + PlayerGUID = caster->GetGUID(); + + me->setFaction(FACTION_FRIENDLY); + DoCast(caster, SPELL_FORCE_OF_NELTHARAKU, true); + + Unit* Dragonmaw = me->FindNearestCreature(CREATURE_DRAGONMAW_SUBJUGATOR, 50); + if (Dragonmaw) + { + me->AddThreat(Dragonmaw, 100000.0f); + AttackStart(Dragonmaw); + } + + HostileReference* ref = me->getThreatManager().getOnlineContainer().getReferenceByTarget(caster); + if (ref) + ref->removeReference(); + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id == 1) + { + if (PlayerGUID) + { + Unit* player = Unit::GetUnit(*me, PlayerGUID); + if (player) + DoCast(player, SPELL_FORCE_OF_NELTHARAKU, true); + + PlayerGUID = 0; + } + me->SetVisible(false); + me->SetDisableGravity(false); + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + me->RemoveCorpse(); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + { + if (Tapped) + { + if (FlyTimer <= diff) + { + Tapped = false; + if (PlayerGUID) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->GetQuestStatus(10854) == QUEST_STATUS_INCOMPLETE) + { + DoCast(player, SPELL_FORCE_OF_NELTHARAKU, true); + /* + float x, y, z; + me->GetPosition(x, y, z); + + float dx, dy, dz; + me->GetRandomPoint(x, y, z, 20, dx, dy, dz); + dz += 20; // so it's in the air, not ground*/ + + Position pos; + if (Unit* EscapeDummy = me->FindNearestCreature(CREATURE_ESCAPE_DUMMY, 30)) + EscapeDummy->GetPosition(&pos); + else + { + me->GetRandomNearPosition(pos, 20); + pos.m_positionZ += 25; + } + + me->SetDisableGravity(true); + me->GetMotionMaster()->MovePoint(1, pos); + } + } + } else FlyTimer -= diff; + } + return; + } + + DoMeleeAttackIfReady(); + } + }; +}; + +/*##### +# mob_dragonmaw_peon +#####*/ + +class mob_dragonmaw_peon : public CreatureScript +{ +public: + mob_dragonmaw_peon() : CreatureScript("mob_dragonmaw_peon") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_dragonmaw_peonAI(creature); + } + + struct mob_dragonmaw_peonAI : public ScriptedAI + { + mob_dragonmaw_peonAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + bool Tapped; + uint32 PoisonTimer; + + void Reset() + { + PlayerGUID = 0; + Tapped = false; + PoisonTimer = 0; + } + + void SpellHit(Unit* caster, const SpellInfo* spell) + { + if (!caster) + return; + + if (caster->GetTypeId() == TYPEID_PLAYER && spell->Id == 40468 && !Tapped) + { + PlayerGUID = caster->GetGUID(); + + Tapped = true; + float x, y, z; + caster->GetClosePoint(x, y, z, me->GetObjectSize()); + + me->SetWalk(false); + me->GetMotionMaster()->MovePoint(1, x, y, z); + } + } + + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id) + { + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_EAT); + PoisonTimer = 15000; + } + } + + void UpdateAI(const uint32 diff) + { + if (PoisonTimer) + { + if (PoisonTimer <= diff) + { + if (PlayerGUID) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player && player->GetQuestStatus(11020) == QUEST_STATUS_INCOMPLETE) + player->KilledMonsterCredit(23209, 0); + } + PoisonTimer = 0; + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } else PoisonTimer -= diff; + } + } + }; +}; + +/*###### +## npc_drake_dealer_hurlunk +######*/ + +class npc_drake_dealer_hurlunk : public CreatureScript +{ +public: + npc_drake_dealer_hurlunk() : CreatureScript("npc_drake_dealer_hurlunk") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isVendor() && player->GetReputationRank(1015) == REP_EXALTED) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_flanis_swiftwing_and_kagrosh +######*/ + +#define GOSSIP_HSK1 "Take Flanis's Pack" +#define GOSSIP_HSK2 "Take Kagrosh's Pack" + +class npcs_flanis_swiftwing_and_kagrosh : public CreatureScript +{ +public: + npcs_flanis_swiftwing_and_kagrosh() : CreatureScript("npcs_flanis_swiftwing_and_kagrosh") { } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 30658, 1, NULL); + if (msg == EQUIP_ERR_OK) + { + player->StoreNewItem(dest, 30658, 1, true); + player->PlayerTalkClass->ClearMenus(); + } + } + if (action == GOSSIP_ACTION_INFO_DEF+2) + { + ItemPosCountVec dest; + uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 30659, 1, NULL); + if (msg == EQUIP_ERR_OK) + { + player->StoreNewItem(dest, 30659, 1, true); + player->PlayerTalkClass->ClearMenus(); + } + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(10583) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(30658, 1, true)) + player->ADD_GOSSIP_ITEM(0, GOSSIP_HSK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + if (player->GetQuestStatus(10601) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(30659, 1, true)) + player->ADD_GOSSIP_ITEM(0, GOSSIP_HSK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +## npc_murkblood_overseer +######*/ + +#define QUEST_11082 11082 + +#define GOSSIP_HMO "I am here for you, overseer." +#define GOSSIP_SMO1 "How dare you question an overseer of the Dragonmaw!" +#define GOSSIP_SMO2 "Who speaks of me? What are you talking about, broken?" +#define GOSSIP_SMO3 "Continue please." +#define GOSSIP_SMO4 "Who are these bidders?" +#define GOSSIP_SMO5 "Well... yes." + +class npc_murkblood_overseer : public CreatureScript +{ +public: + npc_murkblood_overseer() : CreatureScript("npc_murkblood_overseer") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + //correct id not known + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + //correct id not known + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + //correct id not known + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + //correct id not known + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SMO5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + //correct id not known + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + //correct id not known + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + creature->CastSpell(player, 41121, false); + player->AreaExploredOrEventHappens(QUEST_11082); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_11082) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(0, GOSSIP_HMO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(10940, creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_oronok +######*/ + +#define GOSSIP_ORONOK1 "I am ready to hear your story, Oronok." +#define GOSSIP_ORONOK2 "How do I find the cipher?" +#define GOSSIP_ORONOK3 "How do you know all of this?" +#define GOSSIP_ORONOK4 "Yet what? What is it, Oronok?" +#define GOSSIP_ORONOK5 "Continue, please." +#define GOSSIP_ORONOK6 "So what of the cipher now? And your boys?" +#define GOSSIP_ORONOK7 "I will find your boys and the cipher, Oronok." + +class npc_oronok_tornheart : public CreatureScript +{ +public: + npc_oronok_tornheart() : CreatureScript("npc_oronok_tornheart") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_TRADE: + player->GetSession()->SendListInventory(creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(10313, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(10314, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(10315, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(10316, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(10317, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(10318, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->CLOSE_GOSSIP_MENU(); + player->AreaExploredOrEventHappens(10519); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + if (creature->isVendor()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + if (player->GetQuestStatus(10519) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM(0, GOSSIP_ORONOK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->SEND_GOSSIP_MENU(10312, creature->GetGUID()); + }else + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*#### +# npc_karynaku +####*/ + +enum Karynaku +{ + QUEST_ALLY_OF_NETHER = 10870, + QUEST_ZUHULED_THE_WACK = 10866, + + NPC_ZUHULED_THE_WACKED = 11980, + + TAXI_PATH_ID = 649, +}; + +class npc_karynaku : public CreatureScript +{ + public: + npc_karynaku() : CreatureScript("npc_karynaku") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER) + player->ActivateTaxiPathTo(TAXI_PATH_ID); + + if (quest->GetQuestId() == QUEST_ZUHULED_THE_WACK) + creature->SummonCreature(NPC_ZUHULED_THE_WACKED, -4204.94f, 316.397f, 122.508f, 1.309f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); + + return true; + } +}; + +/*#### +# npc_overlord_morghor +####*/ +enum eOverlordData +{ + QUEST_LORD_ILLIDAN_STORMRAGE = 11108, + + C_ILLIDAN = 22083, + C_YARZILL = 23141, + + SPELL_ONE = 39990, // Red Lightning Bolt + SPELL_TWO = 41528, // Mark of Stormrage + SPELL_THREE = 40216, // Dragonaw Faction + SPELL_FOUR = 42016, // Dragonaw Trasform + + OVERLORD_SAY_1 = 0, + OVERLORD_SAY_2 = 1, + //OVERLORD_SAY_3 = 2, + OVERLORD_SAY_4 = 3, + OVERLORD_SAY_5 = 4, + OVERLORD_SAY_6 = 5, + + OVERLORD_YELL_1 = 6, + OVERLORD_YELL_2 = 7, + + LORD_ILLIDAN_SAY_1 = 0, + LORD_ILLIDAN_SAY_2 = 1, + LORD_ILLIDAN_SAY_3 = 2, + LORD_ILLIDAN_SAY_4 = 3, + LORD_ILLIDAN_SAY_5 = 4, + LORD_ILLIDAN_SAY_6 = 5, + LORD_ILLIDAN_SAY_7 = 6, + + YARZILL_THE_MERC_SAY = 0 +}; + +class npc_overlord_morghor : public CreatureScript +{ +public: + npc_overlord_morghor() : CreatureScript("npc_overlord_morghor") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest *_Quest) + { + if (_Quest->GetQuestId() == QUEST_LORD_ILLIDAN_STORMRAGE) + { + CAST_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->PlayerGUID = player->GetGUID(); + CAST_AI(npc_overlord_morghor::npc_overlord_morghorAI, creature->AI())->StartEvent(); + return true; + } + return false; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_overlord_morghorAI(creature); + } + + struct npc_overlord_morghorAI : public ScriptedAI + { + npc_overlord_morghorAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + uint64 IllidanGUID; + + uint32 ConversationTimer; + uint32 Step; + + bool Event; + + void Reset() + { + PlayerGUID = 0; + IllidanGUID = 0; + + ConversationTimer = 0; + Step = 0; + + Event = false; + me->SetUInt32Value(UNIT_NPC_FLAGS, 2); + } + + void StartEvent() + { + me->SetUInt32Value(UNIT_NPC_FLAGS, 0); + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Unit* Illidan = me->SummonCreature(C_ILLIDAN, -5107.83f, 602.584f, 85.2393f, 4.92598f, TEMPSUMMON_CORPSE_DESPAWN, 0); + if (Illidan) + { + IllidanGUID = Illidan->GetGUID(); + Illidan->SetVisible(false); + } + if (PlayerGUID) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player) + Talk(OVERLORD_SAY_1, player->GetGUID()); + } + ConversationTimer = 4200; + Step = 0; + Event = true; + } + + uint32 NextStep(uint32 Step) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + Creature* Illi = Creature::GetCreature(*me, IllidanGUID); + + if (!player || !Illi) + { + EnterEvadeMode(); + return 0; + } + + switch (Step) + { + case 0: + return 0; + break; + case 1: + me->GetMotionMaster()->MovePoint(0, -5104.41f, 595.297f, 85.6838f); + return 9000; + break; + case 2: + Talk(OVERLORD_YELL_1, player->GetGUID()); + return 4500; + break; + case 3: + me->SetInFront(player); + return 3200; + break; + case 4: + Talk(OVERLORD_SAY_2, player->GetGUID()); + return 2000; + break; + case 5: + Illi->SetVisible(true); + Illi->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + return 350; + break; + case 6: + Illi->CastSpell(Illi, SPELL_ONE, true); + Illi->SetTarget(me->GetGUID()); + me->SetTarget(IllidanGUID); + return 2000; + break; + case 7: + Talk(OVERLORD_YELL_2); + return 4500; + break; + case 8: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); + return 9000; + break; + case 10: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_1); + return 5000; + break; + case 11: + Talk(OVERLORD_SAY_4, player->GetGUID()); + return 6000; + break; + case 12: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_2); + return 5500; + break; + case 13: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_3); + return 4000; + break; + case 14: + Illi->SetTarget(PlayerGUID); + return 1500; + break; + case 15: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_4); + return 1500; + break; + case 16: + Illi->CastSpell(player, SPELL_TWO, true); + player->RemoveAurasDueToSpell(SPELL_THREE); + player->RemoveAurasDueToSpell(SPELL_FOUR); + return 5000; + break; + case 17: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_5); + return 5000; + break; + case 18: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_6); + return 5000; + break; + case 19: + Illi->AI()->Talk(LORD_ILLIDAN_SAY_7); + return 5000; + break; + case 20: + Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + Illi->SetDisableGravity(true); + return 500; + break; + case 21: + Talk(OVERLORD_SAY_5); + return 500; + break; + case 22: + Illi->SetVisible(false); + Illi->setDeathState(JUST_DIED); + return 1000; + break; + case 23: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + return 2000; + break; + case 24: + me->SetTarget(PlayerGUID); + return 5000; + break; + case 25: + Talk(OVERLORD_SAY_6); + return 2000; + break; + case 26: + player->GroupEventHappens(QUEST_LORD_ILLIDAN_STORMRAGE, me); + return 6000; + break; + case 27: + { + Unit* Yarzill = me->FindNearestCreature(C_YARZILL, 50); + if (Yarzill) + Yarzill->SetTarget(PlayerGUID); + return 500; + } + break; + case 28: + player->RemoveAurasDueToSpell(SPELL_TWO); + player->RemoveAurasDueToSpell(41519); + player->CastSpell(player, SPELL_THREE, true); + player->CastSpell(player, SPELL_FOUR, true); + return 1000; + break; + case 29: + { + if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) + Yarzill->AI()->Talk(YARZILL_THE_MERC_SAY, player->GetGUID()); + return 5000; + } + break; + case 30: + { + if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) + Yarzill->SetTarget(0); + return 5000; + } + break; + case 31: + { + if (Creature* Yarzill = me->FindNearestCreature(C_YARZILL, 50.0f)) + Yarzill->CastSpell(player, 41540, true); + return 1000; + } + break; + case 32: + me->GetMotionMaster()->MovePoint(0, -5085.77f, 577.231f, 86.6719f); return 5000; + break; + case 33: + Reset(); + return 100; + break; + default : + return 0; + break; + } + } + + void UpdateAI(const uint32 diff) + { + if (!ConversationTimer) + return; + + if (ConversationTimer <= diff) + { + if (Event && IllidanGUID && PlayerGUID) + ConversationTimer = NextStep(++Step); + } else ConversationTimer -= diff; + } + }; +}; + +/*#### +# npc_earthmender_wilda +####*/ + +enum eEarthmender +{ + SAY_WIL_START = 0, + SAY_WIL_AGGRO = 1, + SAY_WIL_PROGRESS1 = 2, + SAY_WIL_PROGRESS2 = 3, + SAY_WIL_FIND_EXIT = 4, + SAY_WIL_JUST_AHEAD = 5, + SAY_WIL_END = 6, + + SPELL_CHAIN_LIGHTNING = 16006, + SPELL_EARTHBING_TOTEM = 15786, + SPELL_FROST_SHOCK = 12548, + SPELL_HEALING_WAVE = 12491, + + QUEST_ESCAPE_COILSCAR = 10451, + NPC_COILSKAR_ASSASSIN = 21044, + FACTION_EARTHEN = 1726 //guessed +}; + +class npc_earthmender_wilda : public CreatureScript +{ +public: + npc_earthmender_wilda() : CreatureScript("npc_earthmender_wilda") { } + + bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPE_COILSCAR) + { + creature->AI()->Talk(SAY_WIL_START, player->GetGUID()); + creature->setFaction(FACTION_EARTHEN); + + if (npc_earthmender_wildaAI* pEscortAI = CAST_AI(npc_earthmender_wilda::npc_earthmender_wildaAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID(), quest); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_earthmender_wildaAI(creature); + } + + struct npc_earthmender_wildaAI : public npc_escortAI + { + npc_earthmender_wildaAI(Creature* creature) : npc_escortAI(creature) { } + + uint32 m_uiHealingTimer; + + void Reset() + { + m_uiHealingTimer = 0; + } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 13: + Talk(SAY_WIL_PROGRESS1, player->GetGUID()); + DoSpawnAssassin(); + break; + case 14: + DoSpawnAssassin(); + break; + case 15: + Talk(SAY_WIL_FIND_EXIT, player->GetGUID()); + break; + case 19: + DoRandomSay(); + break; + case 20: + DoSpawnAssassin(); + break; + case 26: + DoRandomSay(); + break; + case 27: + DoSpawnAssassin(); + break; + case 33: + DoRandomSay(); + break; + case 34: + DoSpawnAssassin(); + break; + case 37: + DoRandomSay(); + break; + case 38: + DoSpawnAssassin(); + break; + case 39: + Talk(SAY_WIL_JUST_AHEAD, player->GetGUID()); + break; + case 43: + DoRandomSay(); + break; + case 44: + DoSpawnAssassin(); + break; + case 50: + Talk(SAY_WIL_END, player->GetGUID()); + player->GroupEventHappens(QUEST_ESCAPE_COILSCAR, me); + break; + } + } + + void JustSummoned(Creature* summoned) + { + if (summoned->GetEntry() == NPC_COILSKAR_ASSASSIN) + summoned->AI()->AttackStart(me); + } + + //this is very unclear, random say without no real relevance to script/event + void DoRandomSay() + { + Talk(SAY_WIL_PROGRESS2); + } + + void DoSpawnAssassin() + { + //unknown where they actually appear + DoSummon(NPC_COILSKAR_ASSASSIN, me, 15.0f, 5000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT); + } + + void EnterCombat(Unit* who) + { + //don't always use + if (rand()%5) + return; + + //only aggro text if not player + if (who->GetTypeId() != TYPEID_PLAYER) + { + //appears to be random + if (urand(0, 1)) + Talk(SAY_WIL_AGGRO); + } + } + + void UpdateAI(const uint32 uiDiff) + { + npc_escortAI::UpdateAI(uiDiff); + + if (!UpdateVictim()) + return; + + //TODO: add more abilities + if (!HealthAbovePct(30)) + { + if (m_uiHealingTimer <= uiDiff) + { + DoCast(me, SPELL_HEALING_WAVE); + m_uiHealingTimer = 15000; + } + else + m_uiHealingTimer -= uiDiff; + } + } + }; +}; + +/*##### +# Quest: Battle of the crimson watch +#####*/ + +/* ContentData +Battle of the crimson watch - creatures, gameobjects and defines +mob_illidari_spawn : Adds that are summoned in the Crimson Watch battle. +mob_torloth_the_magnificent : Final Creature that players have to face before quest is completed +npc_lord_illidan_stormrage : Creature that controls the event. +go_crystal_prison : GameObject that begins the event and hands out quest +EndContentData */ + +#define QUEST_BATTLE_OF_THE_CRIMSON_WATCH 10781 +#define EVENT_AREA_RADIUS 65 //65yds +#define EVENT_COOLDOWN 30000 //in ms. appear after event completed or failed (should be = Adds despawn time) + +struct TorlothCinematic +{ + uint32 creature, Timer; +}; + +// Creature 0 - Torloth, 1 - Illidan +static TorlothCinematic TorlothAnim[]= +{ + {0, 2000}, + {1, 7000}, + {0, 3000}, + {0, 2000}, // Torloth stand + {0, 1000}, + {0, 3000}, + {0, 0} +}; + +struct Location +{ + float x, y, z, o; +}; + +//Cordinates for Spawns +static Location SpawnLocation[]= +{ + //Cords used for: + {-4615.8556f, 1342.2532f, 139.9f, 1.612f}, //Illidari Soldier + {-4598.9365f, 1377.3182f, 139.9f, 3.917f}, //Illidari Soldier + {-4598.4697f, 1360.8999f, 139.9f, 2.427f}, //Illidari Soldier + {-4589.3599f, 1369.1061f, 139.9f, 3.165f}, //Illidari Soldier + {-4608.3477f, 1386.0076f, 139.9f, 4.108f}, //Illidari Soldier + {-4633.1889f, 1359.8033f, 139.9f, 0.949f}, //Illidari Soldier + {-4623.5791f, 1351.4574f, 139.9f, 0.971f}, //Illidari Soldier + {-4607.2988f, 1351.6099f, 139.9f, 2.416f}, //Illidari Soldier + {-4633.7764f, 1376.0417f, 139.9f, 5.608f}, //Illidari Soldier + {-4600.2461f, 1369.1240f, 139.9f, 3.056f}, //Illidari Mind Breaker + {-4631.7808f, 1367.9459f, 139.9f, 0.020f}, //Illidari Mind Breaker + {-4600.2461f, 1369.1240f, 139.9f, 3.056f}, //Illidari Highlord + {-4631.7808f, 1367.9459f, 139.9f, 0.020f}, //Illidari Highlord + {-4615.5586f, 1353.0031f, 139.9f, 1.540f}, //Illidari Highlord + {-4616.4736f, 1384.2170f, 139.9f, 4.971f}, //Illidari Highlord + {-4627.1240f, 1378.8752f, 139.9f, 2.544f} //Torloth The Magnificent +}; + +struct WaveData +{ + uint8 SpawnCount, UsedSpawnPoint; + uint32 CreatureId, SpawnTimer, YellTimer; +}; + +static WaveData WavesInfo[]= +{ + {9, 0, 22075, 10000, 7000}, //Illidari Soldier + {2, 9, 22074, 10000, 7000}, //Illidari Mind Breaker + {4, 11, 19797, 10000, 7000}, //Illidari Highlord + {1, 15, 22076, 10000, 7000} //Torloth The Magnificent +}; + +struct SpawnSpells +{ + uint32 Timer1, Timer2, SpellId; +}; + +static SpawnSpells SpawnCast[]= +{ + {10000, 15000, 35871}, // Illidari Soldier Cast - Spellbreaker + {10000, 10000, 38985}, // Illidari Mind Breake Cast - Focused Bursts + {35000, 35000, 22884}, // Illidari Mind Breake Cast - Psychic Scream + {20000, 20000, 17194}, // Illidari Mind Breake Cast - Mind Blast + {8000, 15000, 38010}, // Illidari Highlord Cast - Curse of Flames + {12000, 20000, 16102}, // Illidari Highlord Cast - Flamestrike + {10000, 15000, 15284}, // Torloth the Magnificent Cast - Cleave + {18000, 20000, 39082}, // Torloth the Magnificent Cast - Shadowfury + {25000, 28000, 33961} // Torloth the Magnificent Cast - Spell Reflection +}; + +/*###### +# mob_torloth_the_magnificent +#####*/ + +class mob_torloth_the_magnificent : public CreatureScript +{ +public: + mob_torloth_the_magnificent() : CreatureScript("mob_torloth_the_magnificent") { } + + CreatureAI* GetAI(Creature* c) const + { + return new mob_torloth_the_magnificentAI(c); + } + + struct mob_torloth_the_magnificentAI : public ScriptedAI + { + mob_torloth_the_magnificentAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 AnimationTimer, SpellTimer1, SpellTimer2, SpellTimer3; + + uint8 AnimationCount; + + uint64 LordIllidanGUID; + uint64 AggroTargetGUID; + + bool Timers; + + void Reset() + { + AnimationTimer = 4000; + AnimationCount = 0; + LordIllidanGUID = 0; + AggroTargetGUID = 0; + Timers = false; + + me->AddUnitState(UNIT_STATE_ROOT); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetTarget(0); + } + + void EnterCombat(Unit* /*who*/){} + + void HandleAnimation() + { + Creature* creature = me; + + if (TorlothAnim[AnimationCount].creature == 1) + { + creature = (Unit::GetCreature(*me, LordIllidanGUID)); + + if (!creature) + return; + } + + AnimationTimer = TorlothAnim[AnimationCount].Timer; + + switch (AnimationCount) + { + case 0: + me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8); + break; + case 3: + me->RemoveFlag(UNIT_FIELD_BYTES_1, 8); + break; + case 5: + if (Player* AggroTarget = (Unit::GetPlayer(*me, AggroTargetGUID))) + { + me->SetTarget(AggroTarget->GetGUID()); + me->AddThreat(AggroTarget, 1); + me->HandleEmoteCommand(EMOTE_ONESHOT_POINT); + } + break; + case 6: + if (Player* AggroTarget = (Unit::GetPlayer(*me, AggroTargetGUID))) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->ClearUnitState(UNIT_STATE_ROOT); + + float x, y, z; + AggroTarget->GetPosition(x, y, z); + me->GetMotionMaster()->MovePoint(0, x, y, z); + } + break; + } + ++AnimationCount; + } + + void UpdateAI(const uint32 diff) + { + if (AnimationTimer) + { + if (AnimationTimer <= diff) + { + HandleAnimation(); + } else AnimationTimer -= diff; + } + + if (AnimationCount < 6) + { + me->CombatStop(); + } else if (!Timers) + { + SpellTimer1 = SpawnCast[6].Timer1; + SpellTimer2 = SpawnCast[7].Timer1; + SpellTimer3 = SpawnCast[8].Timer1; + Timers = true; + } + + if (Timers) + { + if (SpellTimer1 <= diff) + { + DoCast(me->getVictim(), SpawnCast[6].SpellId);//Cleave + SpellTimer1 = SpawnCast[6].Timer2 + (rand()%10 * 1000); + } else SpellTimer1 -= diff; + + if (SpellTimer2 <= diff) + { + DoCast(me->getVictim(), SpawnCast[7].SpellId);//Shadowfury + SpellTimer2 = SpawnCast[7].Timer2 + (rand()%5 * 1000); + } else SpellTimer2 -= diff; + + if (SpellTimer3 <= diff) + { + DoCast(me, SpawnCast[8].SpellId); + SpellTimer3 = SpawnCast[8].Timer2 + (rand()%7 * 1000);//Spell Reflection + } else SpellTimer3 -= diff; + } + + DoMeleeAttackIfReady(); + } + + void JustDied(Unit* killer) + { + switch (killer->GetTypeId()) + { + case TYPEID_UNIT: + if (Unit* owner = killer->GetOwner()) + if (owner->GetTypeId() == TYPEID_PLAYER) + CAST_PLR(owner)->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, me); + break; + case TYPEID_PLAYER: + CAST_PLR(killer)->GroupEventHappens(QUEST_BATTLE_OF_THE_CRIMSON_WATCH, me); + break; + default: + break; + } + + if (Creature* LordIllidan = (Unit::GetCreature(*me, LordIllidanGUID))) + { + LordIllidan->AI()->EnterEvadeMode(); + } + } + }; +}; + +/*##### +# npc_lord_illidan_stormrage +#####*/ + +class npc_lord_illidan_stormrage : public CreatureScript +{ +public: + npc_lord_illidan_stormrage() : CreatureScript("npc_lord_illidan_stormrage") { } + + CreatureAI* GetAI(Creature* c) const + { + return new npc_lord_illidan_stormrageAI(c); + } + + struct npc_lord_illidan_stormrageAI : public ScriptedAI + { + npc_lord_illidan_stormrageAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 PlayerGUID; + + uint32 WaveTimer; + uint32 AnnounceTimer; + + int8 LiveCount; + uint8 WaveCount; + + bool EventStarted; + bool Announced; + bool Failed; + + void Reset() + { + PlayerGUID = 0; + + WaveTimer = 10000; + AnnounceTimer = 7000; + LiveCount = 0; + WaveCount = 0; + + EventStarted = false; + Announced = false; + Failed = false; + + me->SetVisible(false); + } + + void EnterCombat(Unit* /*who*/) {} + void MoveInLineOfSight(Unit* /*who*/) {} + void AttackStart(Unit* /*who*/) {} + + void SummonNextWave(); + + void CheckEventFail() + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + + if (!player) + return; + + if (Group* EventGroup = player->GetGroup()) + { + Player* GroupMember; + + uint8 GroupMemberCount = 0; + uint8 DeadMemberCount = 0; + uint8 FailedMemberCount = 0; + + const Group::MemberSlotList members = EventGroup->GetMemberSlots(); + + for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) + { + GroupMember = (Unit::GetPlayer(*me, itr->guid)); + if (!GroupMember) + continue; + if (!GroupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && GroupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE) + { + GroupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH); + ++FailedMemberCount; + } + ++GroupMemberCount; + + if (GroupMember->isDead()) + { + ++DeadMemberCount; + } + } + + if (GroupMemberCount == FailedMemberCount) + { + Failed = true; + } + + if (GroupMemberCount == DeadMemberCount) + { + for (Group::member_citerator itr = members.begin(); itr!= members.end(); ++itr) + { + GroupMember = Unit::GetPlayer(*me, itr->guid); + + if (GroupMember && GroupMember->GetQuestStatus(QUEST_BATTLE_OF_THE_CRIMSON_WATCH) == QUEST_STATUS_INCOMPLETE) + { + GroupMember->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH); + } + } + Failed = true; + } + } else if (player->isDead() || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS)) + { + player->FailQuest(QUEST_BATTLE_OF_THE_CRIMSON_WATCH); + Failed = true; + } + } + + void LiveCounter() + { + --LiveCount; + if (!LiveCount) + Announced = false; + } + + void UpdateAI(const uint32 diff) + { + if (!PlayerGUID || !EventStarted) + return; + + if (!LiveCount && WaveCount < 4) + { + if (!Announced && AnnounceTimer <= diff) + { + Announced = true; + } + else + AnnounceTimer -= diff; + + if (WaveTimer <= diff) + { + SummonNextWave(); + } + else + WaveTimer -= diff; + } + CheckEventFail(); + + if (Failed) + EnterEvadeMode(); + } + }; +}; + +/*###### +# mob_illidari_spawn +######*/ + +class mob_illidari_spawn : public CreatureScript +{ +public: + mob_illidari_spawn() : CreatureScript("mob_illidari_spawn") { } + + CreatureAI* GetAI(Creature* c) const + { + return new mob_illidari_spawnAI(c); + } + + struct mob_illidari_spawnAI : public ScriptedAI + { + mob_illidari_spawnAI(Creature* creature) : ScriptedAI(creature) {} + + uint64 LordIllidanGUID; + uint32 SpellTimer1, SpellTimer2, SpellTimer3; + bool Timers; + + void Reset() + { + LordIllidanGUID = 0; + Timers = false; + } + + void EnterCombat(Unit* /*who*/) {} + + void JustDied(Unit* /*killer*/) + { + me->RemoveCorpse(); + if (Creature* LordIllidan = (Unit::GetCreature(*me, LordIllidanGUID))) + if (LordIllidan) + CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, LordIllidan->AI())->LiveCounter(); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (!Timers) + { + if (me->GetEntry() == 22075)//Illidari Soldier + { + SpellTimer1 = SpawnCast[0].Timer1 + (rand()%4 * 1000); + } + if (me->GetEntry() == 22074)//Illidari Mind Breaker + { + SpellTimer1 = SpawnCast[1].Timer1 + (rand()%10 * 1000); + SpellTimer2 = SpawnCast[2].Timer1 + (rand()%4 * 1000); + SpellTimer3 = SpawnCast[3].Timer1 + (rand()%4 * 1000); + } + if (me->GetEntry() == 19797)// Illidari Highlord + { + SpellTimer1 = SpawnCast[4].Timer1 + (rand()%4 * 1000); + SpellTimer2 = SpawnCast[5].Timer1 + (rand()%4 * 1000); + } + Timers = true; + } + //Illidari Soldier + if (me->GetEntry() == 22075) + { + if (SpellTimer1 <= diff) + { + DoCast(me->getVictim(), SpawnCast[0].SpellId);//Spellbreaker + SpellTimer1 = SpawnCast[0].Timer2 + (rand()%5 * 1000); + } else SpellTimer1 -= diff; + } + //Illidari Mind Breaker + if (me->GetEntry() == 22074) + { + if (SpellTimer1 <= diff) + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + { + if (target->GetTypeId() == TYPEID_PLAYER) + { + DoCast(target, SpawnCast[1].SpellId); //Focused Bursts + SpellTimer1 = SpawnCast[1].Timer2 + (rand()%5 * 1000); + } else SpellTimer1 = 2000; + } + } else SpellTimer1 -= diff; + + if (SpellTimer2 <= diff) + { + DoCast(me->getVictim(), SpawnCast[2].SpellId);//Psychic Scream + SpellTimer2 = SpawnCast[2].Timer2 + (rand()%13 * 1000); + } else SpellTimer2 -= diff; + + if (SpellTimer3 <= diff) + { + DoCast(me->getVictim(), SpawnCast[3].SpellId);//Mind Blast + SpellTimer3 = SpawnCast[3].Timer2 + (rand()%8 * 1000); + } else SpellTimer3 -= diff; + } + //Illidari Highlord + if (me->GetEntry() == 19797) + { + if (SpellTimer1 <= diff) + { + DoCast(me->getVictim(), SpawnCast[4].SpellId);//Curse Of Flames + SpellTimer1 = SpawnCast[4].Timer2 + (rand()%10 * 1000); + } else SpellTimer1 -= diff; + + if (SpellTimer2 <= diff) + { + DoCast(me->getVictim(), SpawnCast[5].SpellId);//Flamestrike + SpellTimer2 = SpawnCast[5].Timer2 + (rand()%7 * 13000); + } else SpellTimer2 -= diff; + } + + DoMeleeAttackIfReady(); + } + }; +}; + +void npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI::SummonNextWave() +{ + uint8 count = WavesInfo[WaveCount].SpawnCount; + uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; + uint8 FelguardCount = 0; + uint8 DreadlordCount = 0; + + for (uint8 i = 0; i < count; ++i) + { + Creature* Spawn = NULL; + float X = SpawnLocation[locIndex + i].x; + float Y = SpawnLocation[locIndex + i].y; + float Z = SpawnLocation[locIndex + i].z; + float O = SpawnLocation[locIndex + i].o; + Spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, X, Y, Z, O, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + ++LiveCount; + + if (Spawn) + { + Spawn->LoadCreaturesAddon(); + + if (WaveCount == 0)//1 Wave + { + if (rand()%3 == 1 && FelguardCount<2) + { + Spawn->SetDisplayId(18654); + ++FelguardCount; + } + else if (DreadlordCount < 3) + { + Spawn->SetDisplayId(19991); + ++DreadlordCount; + } + else if (FelguardCount<2) + { + Spawn->SetDisplayId(18654); + ++FelguardCount; + } + } + + if (WaveCount < 3)//1-3 Wave + { + if (PlayerGUID) + { + if (Player* target = Unit::GetPlayer(*me, PlayerGUID)) + { + float x, y, z; + target->GetPosition(x, y, z); + Spawn->GetMotionMaster()->MovePoint(0, x, y, z); + } + } + CAST_AI(mob_illidari_spawn::mob_illidari_spawnAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); + } + + if (WavesInfo[WaveCount].CreatureId == 22076) // Torloth + { + CAST_AI(mob_torloth_the_magnificent::mob_torloth_the_magnificentAI, Spawn->AI())->LordIllidanGUID = me->GetGUID(); + if (PlayerGUID) + CAST_AI(mob_torloth_the_magnificent::mob_torloth_the_magnificentAI, Spawn->AI())->AggroTargetGUID = PlayerGUID; + } + } + } + ++WaveCount; + WaveTimer = WavesInfo[WaveCount].SpawnTimer; + AnnounceTimer = WavesInfo[WaveCount].YellTimer; +} + +/*##### +# go_crystal_prison +######*/ + +class go_crystal_prison : public GameObjectScript +{ +public: + go_crystal_prison() : GameObjectScript("go_crystal_prison") { } + + bool OnQuestAccept(Player* player, GameObject* /*go*/, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_BATTLE_OF_THE_CRIMSON_WATCH) + { + Creature* Illidan = player->FindNearestCreature(22083, 50); + + if (Illidan && !CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted) + { + CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->PlayerGUID = player->GetGUID(); + CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->LiveCount = 0; + CAST_AI(npc_lord_illidan_stormrage::npc_lord_illidan_stormrageAI, Illidan->AI())->EventStarted=true; + } + } + return true; + } +}; + +/*#### +# npc_enraged_spirits +####*/ + +/* QUESTS */ +#define QUEST_ENRAGED_SPIRITS_FIRE_EARTH 10458 +#define QUEST_ENRAGED_SPIRITS_AIR 10481 +#define QUEST_ENRAGED_SPIRITS_WATER 10480 + +/* Totem */ +#define ENTRY_TOTEM_OF_SPIRITS 21071 +#define RADIUS_TOTEM_OF_SPIRITS 15 + +/* SPIRITS */ +#define ENTRY_ENRAGED_EARTH_SPIRIT 21050 +#define ENTRY_ENRAGED_FIRE_SPIRIT 21061 +#define ENTRY_ENRAGED_AIR_SPIRIT 21060 +#define ENTRY_ENRAGED_WATER_SPIRIT 21059 + +/* SOULS */ +#define ENTRY_EARTHEN_SOUL 21073 +#define ENTRY_FIERY_SOUL 21097 +#define ENTRY_ENRAGED_AIRY_SOUL 21116 +#define ENTRY_ENRAGED_WATERY_SOUL 21109 // wrong model + +/* SPELL KILLCREDIT - not working!?! - using KilledMonsterCredit */ +#define SPELL_EARTHEN_SOUL_CAPTURED_CREDIT 36108 +#define SPELL_FIERY_SOUL_CAPTURED_CREDIT 36117 +#define SPELL_AIRY_SOUL_CAPTURED_CREDIT 36182 +#define SPELL_WATERY_SOUL_CAPTURED_CREDIT 36171 + +/* KilledMonsterCredit Workaround */ +#define CREDIT_FIRE 21094 +#define CREDIT_WATER 21095 +#define CREDIT_AIR 21096 +#define CREDIT_EARTH 21092 + +/* Captured Spell/Buff */ +#define SPELL_SOUL_CAPTURED 36115 + +/* Factions */ +#define ENRAGED_SOUL_FRIENDLY 35 +#define ENRAGED_SOUL_HOSTILE 14 + +class npc_enraged_spirit : public CreatureScript +{ +public: + npc_enraged_spirit() : CreatureScript("npc_enraged_spirit") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_enraged_spiritAI(creature); + } + + struct npc_enraged_spiritAI : public ScriptedAI + { + npc_enraged_spiritAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { } + + void EnterCombat(Unit* /*who*/){} + + void JustDied(Unit* /*killer*/) + { + // always spawn spirit on death + // if totem around + // move spirit to totem and cast kill count + uint32 entry = 0; + uint32 credit = 0; + + switch (me->GetEntry()) + { + case ENTRY_ENRAGED_FIRE_SPIRIT: + entry = ENTRY_FIERY_SOUL; + //credit = SPELL_FIERY_SOUL_CAPTURED_CREDIT; + credit = CREDIT_FIRE; + break; + case ENTRY_ENRAGED_EARTH_SPIRIT: + entry = ENTRY_EARTHEN_SOUL; + //credit = SPELL_EARTHEN_SOUL_CAPTURED_CREDIT; + credit = CREDIT_EARTH; + break; + case ENTRY_ENRAGED_AIR_SPIRIT: + entry = ENTRY_ENRAGED_AIRY_SOUL; + //credit = SPELL_AIRY_SOUL_CAPTURED_CREDIT; + credit = CREDIT_AIR; + break; + case ENTRY_ENRAGED_WATER_SPIRIT: + entry = ENTRY_ENRAGED_WATERY_SOUL; + //credit = SPELL_WATERY_SOUL_CAPTURED_CREDIT; + credit = CREDIT_WATER; + break; + } + + // Spawn Soul on Kill ALWAYS! + Creature* Summoned = NULL; + Unit* totemOspirits = NULL; + + if (entry != 0) + Summoned = DoSpawnCreature(entry, 0, 0, 1, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); + + // FIND TOTEM, PROCESS QUEST + if (Summoned) + { + totemOspirits = me->FindNearestCreature(ENTRY_TOTEM_OF_SPIRITS, RADIUS_TOTEM_OF_SPIRITS); + if (totemOspirits) + { + Summoned->setFaction(ENRAGED_SOUL_FRIENDLY); + Summoned->GetMotionMaster()->MovePoint(0, totemOspirits->GetPositionX(), totemOspirits->GetPositionY(), Summoned->GetPositionZ()); + + Unit* Owner = totemOspirits->GetOwner(); + if (Owner && Owner->GetTypeId() == TYPEID_PLAYER) + // DoCast(Owner, credit); -- not working! + CAST_PLR(Owner)->KilledMonsterCredit(credit, 0); + DoCast(totemOspirits, SPELL_SOUL_CAPTURED); + } + } + } + }; +}; + +enum ZuluhedChains +{ + QUEST_ZULUHED = 10866, + NPC_KARYNAKU = 22112, +}; + +class spell_unlocking_zuluheds_chains : public SpellScriptLoader +{ + public: + spell_unlocking_zuluheds_chains() : SpellScriptLoader("spell_unlocking_zuluheds_chains") { } + + class spell_unlocking_zuluheds_chains_SpellScript : public SpellScript + { + PrepareSpellScript(spell_unlocking_zuluheds_chains_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleAfterHit() + { + Player* caster = GetCaster()->ToPlayer(); + if (caster->GetQuestStatus(QUEST_ZULUHED) == QUEST_STATUS_INCOMPLETE) + caster->KilledMonsterCredit(NPC_KARYNAKU, 0); + } + + void Register() + { + AfterHit += SpellHitFn(spell_unlocking_zuluheds_chains_SpellScript::HandleAfterHit); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_unlocking_zuluheds_chains_SpellScript(); + } +}; + +enum ShadowMoonTuberEnum +{ + SPELL_WHISTLE = 36652, + SPELL_SHADOWMOON_TUBER = 36462, + + NPC_BOAR_ENTRY = 21195, + GO_SHADOWMOON_TUBER_MOUND = 184701, + + POINT_TUBER = 1, + TYPE_BOAR = 1, + DATA_BOAR = 1 +}; + +class npc_shadowmoon_tuber_node : public CreatureScript +{ +public: + npc_shadowmoon_tuber_node() : CreatureScript("npc_shadowmoon_tuber_node") {} + + struct npc_shadowmoon_tuber_nodeAI : public ScriptedAI + { + npc_shadowmoon_tuber_nodeAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() + { + tapped = false; + tuberGUID = 0; + resetTimer = 60000; + } + + void SetData(uint32 id, uint32 data) + { + if (id == TYPE_BOAR && data == DATA_BOAR) + { + // Spawn chest GO + DoCast(SPELL_SHADOWMOON_TUBER); + + // Despawn the tuber + if (GameObject* tuber = me->FindNearestGameObject(GO_SHADOWMOON_TUBER_MOUND, 5.0f)) + { + tuberGUID = tuber->GetGUID(); + // @Workaround: find how to properly despawn the GO + tuber->SetPhaseMask(2, true); + } + } + } + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + { + if (!tapped && spell->Id == SPELL_WHISTLE) + { + if (Creature* boar = me->FindNearestCreature(NPC_BOAR_ENTRY, 30.0f)) + { + // Disable trigger and force nearest boar to walk to him + tapped = true; + boar->SetWalk(false); + boar->GetMotionMaster()->MovePoint(POINT_TUBER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (tapped) + { + if (resetTimer <= diff) + { + // Respawn the tuber + if (tuberGUID) + if (GameObject* tuber = GameObject::GetGameObject(*me, tuberGUID)) + // @Workaround: find how to properly respawn the GO + tuber->SetPhaseMask(1, true); + + Reset(); + } + else + resetTimer -= diff; + } + } + private: + bool tapped; + uint64 tuberGUID; + uint32 resetTimer; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_shadowmoon_tuber_nodeAI(creature); + } +}; + +void AddSC_shadowmoon_valley() +{ + new mob_mature_netherwing_drake(); + new mob_enslaved_netherwing_drake(); + new mob_dragonmaw_peon(); + new npc_drake_dealer_hurlunk(); + new npcs_flanis_swiftwing_and_kagrosh(); + new npc_murkblood_overseer(); + new npc_karynaku(); + new npc_oronok_tornheart(); + new npc_overlord_morghor(); + new npc_earthmender_wilda(); + new npc_lord_illidan_stormrage(); + new go_crystal_prison(); + new mob_illidari_spawn(); + new mob_torloth_the_magnificent(); + new npc_enraged_spirit(); + new spell_unlocking_zuluheds_chains(); + new npc_shadowmoon_tuber_node(); +} diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp new file mode 100644 index 00000000000..ac26614ae69 --- /dev/null +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -0,0 +1,739 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Shattrath_City +SD%Complete: 100 +SDComment: Quest support: 10004, 10009, 10211, 10231. Flask vendors, Teleport to Caverns of Time +SDCategory: Shattrath City +EndScriptData */ + +/* ContentData +npc_raliq_the_drunk +npc_salsalabim +npc_shattrathflaskvendors +npc_zephyr +npc_kservant +npc_dirty_larry +npc_ishanah +npc_khadgar +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npc_raliq_the_drunk +######*/ + +#define GOSSIP_RALIQ "You owe Sim'salabim money. Hand them over or die!" + +enum eRaliq +{ + SPELL_UPPERCUT = 10966, + QUEST_CRACK_SKULLS = 10009, + FACTION_HOSTILE_RD = 45 +}; + +class npc_raliq_the_drunk : public CreatureScript +{ +public: + npc_raliq_the_drunk() : CreatureScript("npc_raliq_the_drunk") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_HOSTILE_RD); + creature->AI()->AttackStart(player); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_RALIQ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(9440, creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_raliq_the_drunkAI (creature); + } + + struct npc_raliq_the_drunkAI : public ScriptedAI + { + npc_raliq_the_drunkAI(Creature* creature) : ScriptedAI(creature) + { + m_uiNormFaction = creature->getFaction(); + } + + uint32 m_uiNormFaction; + uint32 Uppercut_Timer; + + void Reset() + { + Uppercut_Timer = 5000; + me->RestoreFaction(); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (Uppercut_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_UPPERCUT); + Uppercut_Timer = 15000; + } else Uppercut_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +# npc_salsalabim +######*/ + +#define FACTION_HOSTILE_SA 90 +#define FACTION_FRIENDLY_SA 35 +#define QUEST_10004 10004 + +#define SPELL_MAGNETIC_PULL 31705 + +class npc_salsalabim : public CreatureScript +{ +public: + npc_salsalabim() : CreatureScript("npc_salsalabim") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_10004) == QUEST_STATUS_INCOMPLETE) + { + creature->setFaction(FACTION_HOSTILE_SA); + creature->AI()->AttackStart(player); + } + else + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_salsalabimAI (creature); + } + + struct npc_salsalabimAI : public ScriptedAI + { + npc_salsalabimAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 MagneticPull_Timer; + + void Reset() + { + MagneticPull_Timer = 15000; + me->RestoreFaction(); + } + + void DamageTaken(Unit* done_by, uint32 &damage) + { + if (done_by->GetTypeId() == TYPEID_PLAYER) + if (me->HealthBelowPctDamaged(20, damage)) + { + CAST_PLR(done_by)->GroupEventHappens(QUEST_10004, me); + damage = 0; + EnterEvadeMode(); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (MagneticPull_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_MAGNETIC_PULL); + MagneticPull_Timer = 15000; + } else MagneticPull_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/* +################################################## +Shattrath City Flask Vendors provides flasks to people exalted with 3 fActions: +Haldor the Compulsive +Arcanist Xorith +Both sell special flasks for use in Outlands 25man raids only, +purchasable for one Mark of Illidari each +Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and The Sha'tar +################################################## +*/ + +class npc_shattrathflaskvendors : public CreatureScript +{ +public: + npc_shattrathflaskvendors() : CreatureScript("npc_shattrathflaskvendors") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->GetEntry() == 23484) + { + // Aldor vendor + if (creature->isVendor() && (player->GetReputationRank(932) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); + } + else + { + player->SEND_GOSSIP_MENU(11083, creature->GetGUID()); + } + } + + if (creature->GetEntry() == 23483) + { + // Scryers vendor + if (creature->isVendor() && (player->GetReputationRank(934) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); + } + else + { + player->SEND_GOSSIP_MENU(11084, creature->GetGUID()); + } + } + + return true; + } +}; + +/*###### +# npc_zephyr +######*/ + +#define GOSSIP_HZ "Take me to the Caverns of Time." + +class npc_zephyr : public CreatureScript +{ +public: + npc_zephyr() : CreatureScript("npc_zephyr") { } + + bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + player->CastSpell(player, 37778, false); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetReputationRank(989) >= REP_REVERED) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HZ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +# npc_kservant +######*/ + +enum KServant +{ + SAY1 = 0, + WHISP1 = 1, + WHISP2 = 2, + WHISP3 = 3, + WHISP4 = 4, + WHISP5 = 5, + WHISP6 = 6, + WHISP7 = 7, + WHISP8 = 8, + WHISP9 = 9, + WHISP10 = 10, + WHISP11 = 11, + WHISP12 = 12, + WHISP13 = 13, + WHISP14 = 14, + WHISP15 = 15, + WHISP16 = 16, + WHISP17 = 17, + WHISP18 = 18, + WHISP19 = 19, + WHISP20 = 20, + WHISP21 = 21 +}; + +class npc_kservant : public CreatureScript +{ +public: + npc_kservant() : CreatureScript("npc_kservant") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kservantAI(creature); + } + + struct npc_kservantAI : public npc_escortAI + { + public: + npc_kservantAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 0: + Talk(SAY1, player->GetGUID()); + break; + case 4: + Talk(WHISP1, player->GetGUID()); + break; + case 6: + Talk(WHISP2, player->GetGUID()); + break; + case 7: + Talk(WHISP3, player->GetGUID()); + break; + case 8: + Talk(WHISP4, player->GetGUID()); + break; + case 17: + Talk(WHISP5, player->GetGUID()); + break; + case 18: + Talk(WHISP6, player->GetGUID()); + break; + case 19: + Talk(WHISP7, player->GetGUID()); + break; + case 33: + Talk(WHISP8, player->GetGUID()); + break; + case 34: + Talk(WHISP9, player->GetGUID()); + break; + case 35: + Talk(WHISP10, player->GetGUID()); + break; + case 36: + Talk(WHISP11, player->GetGUID()); + break; + case 43: + Talk(WHISP12, player->GetGUID()); + break; + case 44: + Talk(WHISP13, player->GetGUID()); + break; + case 49: + Talk(WHISP14, player->GetGUID()); + break; + case 50: + Talk(WHISP15, player->GetGUID()); + break; + case 51: + Talk(WHISP16, player->GetGUID()); + break; + case 52: + Talk(WHISP17, player->GetGUID()); + break; + case 53: + Talk(WHISP18, player->GetGUID()); + break; + case 54: + Talk(WHISP19, player->GetGUID()); + break; + case 55: + Talk(WHISP20, player->GetGUID()); + break; + case 56: + Talk(WHISP21, player->GetGUID()); + player->GroupEventHappens(10211, me); + break; + } + } + + void MoveInLineOfSight(Unit* who) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + return; + + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (CAST_PLR(who)->GetQuestStatus(10211) == QUEST_STATUS_INCOMPLETE) + { + float Radius = 10.0f; + if (me->IsWithinDistInMap(who, Radius)) + { + Start(false, false, who->GetGUID()); + } + } + } + } + + void Reset() {} + }; +}; + +/*###### +# npc_dirty_larry +######*/ + +#define GOSSIP_BOOK "Ezekiel said that you might have a certain book..." + +enum DirtyLarry +{ + SAY_1 = 0, + SAY_2 = 1, + SAY_3 = 2, + SAY_4 = 3, + SAY_5 = 4, + SAY_GIVEUP = 5, + + QUEST_WBI = 10231, + NPC_CREEPJACK = 19726, + NPC_MALONE = 19725 +}; + +class npc_dirty_larry : public CreatureScript +{ +public: + npc_dirty_larry() : CreatureScript("npc_dirty_larry") { } + + struct npc_dirty_larryAI : public ScriptedAI + { + npc_dirty_larryAI(Creature* creature) : ScriptedAI(creature) {} + + bool Event; + bool Attack; + bool Done; + + uint64 PlayerGUID; + + uint32 SayTimer; + uint32 Step; + + void Reset() + { + Event = false; + Attack = false; + Done = false; + + PlayerGUID = 0; + SayTimer = 0; + Step = 0; + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->setFaction(1194); + Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); + if (Creepjack) + { + CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); + Creepjack->setFaction(1194); + Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); + if (Malone) + { + CAST_CRE(Malone)->AI()->EnterEvadeMode(); + Malone->setFaction(1194); + Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + uint32 NextStep(uint32 Step) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + + switch (Step) + { + case 0:{ me->SetInFront(player); + Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); + if (Creepjack) + Creepjack->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); + if (Malone) + Malone->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }return 2000; + case 1: Talk(SAY_1, player->GetGUID()); return 3000; + case 2: Talk(SAY_2, player->GetGUID()); return 5000; + case 3: Talk(SAY_3, player->GetGUID()); return 2000; + case 4: Talk(SAY_4, player->GetGUID()); return 2000; + case 5: Talk(SAY_5, player->GetGUID()); return 2000; + case 6: Attack = true; return 2000; + default: return 0; + } + } + + void EnterCombat(Unit* /*who*/){} + + void UpdateAI(const uint32 diff) + { + if (SayTimer <= diff) + { + if (Event) + SayTimer = NextStep(++Step); + } else SayTimer -= diff; + + if (Attack) + { + Player* player = Unit::GetPlayer(*me, PlayerGUID); + me->setFaction(14); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if (player) + { + Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); + if (Creepjack) + { + Creepjack->Attack(player, true); + Creepjack->setFaction(14); + Creepjack->GetMotionMaster()->MoveChase(player); + Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); + if (Malone) + { + Malone->Attack(player, true); + Malone->setFaction(14); + Malone->GetMotionMaster()->MoveChase(player); + Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + DoStartMovement(player); + AttackStart(player); + } + Attack = false; + } + + if (HealthBelowPct(5) && !Done) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->RemoveAllAuras(); + + Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20); + if (Creepjack) + { + CAST_CRE(Creepjack)->AI()->EnterEvadeMode(); + Creepjack->setFaction(1194); + Creepjack->GetMotionMaster()->MoveTargetedHome(); + Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20); + if (Malone) + { + CAST_CRE(Malone)->AI()->EnterEvadeMode(); + Malone->setFaction(1194); + Malone->GetMotionMaster()->MoveTargetedHome(); + Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + me->setFaction(1194); + Done = true; + Talk(SAY_GIVEUP); + me->DeleteThreatList(); + me->CombatStop(); + me->GetMotionMaster()->MoveTargetedHome(); + Player* player = Unit::GetPlayer(*me, PlayerGUID); + if (player) + CAST_PLR(player)->GroupEventHappens(QUEST_WBI, me); + } + DoMeleeAttackIfReady(); + } + }; + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + CAST_AI(npc_dirty_larry::npc_dirty_larryAI, creature->AI())->Event = true; + CAST_AI(npc_dirty_larry::npc_dirty_larryAI, creature->AI())->PlayerGUID = player->GetGUID(); + player->CLOSE_GOSSIP_MENU(); + } + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_WBI) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BOOK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_dirty_larryAI (creature); + } +}; + +/*###### +# npc_ishanah +######*/ + +#define ISANAH_GOSSIP_1 "Who are the Sha'tar?" +#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" + +class npc_ishanah : public CreatureScript +{ +public: + npc_ishanah() : CreatureScript("npc_ishanah") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + player->SEND_GOSSIP_MENU(9458, creature->GetGUID()); + else if (action == GOSSIP_ACTION_INFO_DEF+2) + player->SEND_GOSSIP_MENU(9459, creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } +}; + +/*###### +# npc_khadgar +######*/ + +#define KHADGAR_GOSSIP_1 "I've heard your name spoken only in whispers, mage. Who are you?" +#define KHADGAR_GOSSIP_2 "Go on, please." +#define KHADGAR_GOSSIP_3 "I see." //6th too this +#define KHADGAR_GOSSIP_4 "What did you do then?" +#define KHADGAR_GOSSIP_5 "What happened next?" +#define KHADGAR_GOSSIP_7 "There was something else I wanted to ask you." + +class npc_khadgar : public CreatureScript +{ +public: + npc_khadgar() : CreatureScript("npc_khadgar") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(9876, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(9877, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(9878, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(9879, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(9880, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); + player->SEND_GOSSIP_MENU(9881, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); + break; + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (!player->hasQuest(10211)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); + + return true; + } +}; + +void AddSC_shattrath_city() +{ + new npc_raliq_the_drunk(); + new npc_salsalabim(); + new npc_shattrathflaskvendors(); + new npc_zephyr(); + new npc_kservant(); + new npc_dirty_larry(); + new npc_ishanah(); + new npc_khadgar(); +} diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp new file mode 100644 index 00000000000..2b046a7518e --- /dev/null +++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp @@ -0,0 +1,715 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Terokkar_Forest +SD%Complete: 85 +SDComment: Quest support: 9889, 10009, 10873, 10896, 10898, 11096, 10052, 10051. Skettis->Ogri'la Flight +SDCategory: Terokkar Forest +EndScriptData */ + +/* ContentData +mob_unkor_the_ruthless +mob_infested_root_walker +mob_rotting_forest_rager +mob_netherweb_victim +npc_floon +npc_isla_starmane +npc_slim +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Group.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## mob_unkor_the_ruthless +######*/ + +enum UnkorTheRuthless +{ + SAY_SUBMIT = 0, + + FACTION_HOSTILE = 45, + FACTION_FRIENDLY = 35, + QUEST_DONTKILLTHEFATONE = 9889, + + SPELL_PULVERIZE = 2676 +}; + +class mob_unkor_the_ruthless : public CreatureScript +{ +public: + mob_unkor_the_ruthless() : CreatureScript("mob_unkor_the_ruthless") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_unkor_the_ruthlessAI (creature); + } + + struct mob_unkor_the_ruthlessAI : public ScriptedAI + { + mob_unkor_the_ruthlessAI(Creature* creature) : ScriptedAI(creature) {} + + bool CanDoQuest; + uint32 UnkorUnfriendly_Timer; + uint32 Pulverize_Timer; + + void Reset() + { + CanDoQuest = false; + UnkorUnfriendly_Timer = 0; + Pulverize_Timer = 3000; + me->SetStandState(UNIT_STAND_STATE_STAND); + me->setFaction(FACTION_HOSTILE); + } + + void EnterCombat(Unit* /*who*/) {} + + void DoNice() + { + Talk(SAY_SUBMIT); + me->setFaction(FACTION_FRIENDLY); + me->SetStandState(UNIT_STAND_STATE_SIT); + me->RemoveAllAuras(); + me->DeleteThreatList(); + me->CombatStop(true); + UnkorUnfriendly_Timer = 60000; + } + + void DamageTaken(Unit* done_by, uint32 &damage) + { + if (done_by->GetTypeId() == TYPEID_PLAYER) + if (me->HealthBelowPctDamaged(30, damage)) + { + if (Group* group = CAST_PLR(done_by)->GetGroup()) + { + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* groupie = itr->getSource(); + if (groupie && + groupie->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && + groupie->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) + { + groupie->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); + if (!CanDoQuest) + CanDoQuest = true; + } + } + } else + if (CAST_PLR(done_by)->GetQuestStatus(QUEST_DONTKILLTHEFATONE) == QUEST_STATUS_INCOMPLETE && + CAST_PLR(done_by)->GetReqKillOrCastCurrentCount(QUEST_DONTKILLTHEFATONE, 18260) == 10) + { + CAST_PLR(done_by)->AreaExploredOrEventHappens(QUEST_DONTKILLTHEFATONE); + CanDoQuest = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + if (CanDoQuest) + { + if (!UnkorUnfriendly_Timer) + { + //DoCast(me, SPELL_QUID9889); //not using spell for now + DoNice(); + } + else + { + if (UnkorUnfriendly_Timer <= diff) + { + EnterEvadeMode(); + return; + } else UnkorUnfriendly_Timer -= diff; + } + } + + if (!UpdateVictim()) + return; + + if (Pulverize_Timer <= diff) + { + DoCast(me, SPELL_PULVERIZE); + Pulverize_Timer = 9000; + } else Pulverize_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## mob_infested_root_walker +######*/ + +class mob_infested_root_walker : public CreatureScript +{ +public: + mob_infested_root_walker() : CreatureScript("mob_infested_root_walker") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_infested_root_walkerAI (creature); + } + + struct mob_infested_root_walkerAI : public ScriptedAI + { + mob_infested_root_walkerAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { } + void EnterCombat(Unit* /*who*/) { } + + void DamageTaken(Unit* done_by, uint32 &damage) + { + if (done_by && done_by->GetTypeId() == TYPEID_PLAYER) + if (me->GetHealth() <= damage) + if (rand()%100 < 75) + //Summon Wood Mites + DoCast(me, 39130, true); + } + }; +}; + +/*###### +## mob_skywing +######*/ +class npc_skywing : public CreatureScript +{ +public: + npc_skywing() : CreatureScript("npc_skywing") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_skywingAI(creature); + } + + struct npc_skywingAI : public npc_escortAI + { + public: + npc_skywingAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 8: + player->AreaExploredOrEventHappens(10898); + break; + } + } + + void EnterCombat(Unit* /*who*/) {} + + void MoveInLineOfSight(Unit* who) + { + if (HasEscortState(STATE_ESCORT_ESCORTING)) + return; + + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (CAST_PLR(who)->GetQuestStatus(10898) == QUEST_STATUS_INCOMPLETE) + { + float Radius = 10.0f; + if (me->IsWithinDistInMap(who, Radius)) + { + Start(false, false, who->GetGUID()); + } + } + } + } + + void Reset() {} + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } + }; +}; + +/*###### +## mob_rotting_forest_rager +######*/ + +class mob_rotting_forest_rager : public CreatureScript +{ +public: + mob_rotting_forest_rager() : CreatureScript("mob_rotting_forest_rager") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_rotting_forest_ragerAI (creature); + } + + struct mob_rotting_forest_ragerAI : public ScriptedAI + { + mob_rotting_forest_ragerAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { } + void EnterCombat(Unit* /*who*/) { } + + void DamageTaken(Unit* done_by, uint32 &damage) + { + if (done_by->GetTypeId() == TYPEID_PLAYER) + if (me->GetHealth() <= damage) + if (rand()%100 < 75) + //Summon Lots of Wood Mights + DoCast(me, 39134, true); + } + }; +}; + +/*###### +## mob_netherweb_victim +######*/ + +#define QUEST_TARGET 22459 +//#define SPELL_FREE_WEBBED 38950 + +const uint32 netherwebVictims[6] = +{ + 18470, 16805, 21242, 18452, 22482, 21285 +}; +class mob_netherweb_victim : public CreatureScript +{ +public: + mob_netherweb_victim() : CreatureScript("mob_netherweb_victim") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_netherweb_victimAI (creature); + } + + struct mob_netherweb_victimAI : public ScriptedAI + { + mob_netherweb_victimAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() { } + void EnterCombat(Unit* /*who*/) { } + void MoveInLineOfSight(Unit* /*who*/) { } + + void JustDied(Unit* killer) + { + Player* player = killer->ToPlayer(); + if (!player) + return; + + if (player->GetQuestStatus(10873) == QUEST_STATUS_INCOMPLETE) + { + if (rand()%100 < 25) + { + me->SummonCreature(QUEST_TARGET, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + player->KilledMonsterCredit(QUEST_TARGET, 0); + } + else + me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + + if (rand()%100 < 75) + me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + + me->SummonCreature(netherwebVictims[rand()%6], 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); + } + } + }; +}; + +/*###### +## npc_floon +######*/ + +#define GOSSIP_FLOON1 "You owe Sim'salabim money. Hand them over or die!" +#define GOSSIP_FLOON2 "Hand over the money or die...again!" + +enum eFloon +{ + SAY_FLOON_ATTACK = 0, + + SPELL_SILENCE = 6726, + SPELL_FROSTBOLT = 9672, + SPELL_FROST_NOVA = 11831, + + FACTION_HOSTILE_FL = 1738, + QUEST_CRACK_SKULLS = 10009 +}; + +class npc_floon : public CreatureScript +{ +public: + npc_floon() : CreatureScript("npc_floon") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(9443, creature->GetGUID()); + } + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_HOSTILE_FL); + creature->AI()->Talk(SAY_FLOON_ATTACK, player->GetGUID()); + creature->AI()->AttackStart(player); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_FLOON1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(9442, creature->GetGUID()); + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_floonAI (creature); + } + + struct npc_floonAI : public ScriptedAI + { + npc_floonAI(Creature* creature) : ScriptedAI(creature) + { + m_uiNormFaction = creature->getFaction(); + } + + uint32 m_uiNormFaction; + uint32 Silence_Timer; + uint32 Frostbolt_Timer; + uint32 FrostNova_Timer; + + void Reset() + { + Silence_Timer = 2000; + Frostbolt_Timer = 4000; + FrostNova_Timer = 9000; + if (me->getFaction() != m_uiNormFaction) + me->setFaction(m_uiNormFaction); + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (Silence_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_SILENCE); + Silence_Timer = 30000; + } else Silence_Timer -= diff; + + if (FrostNova_Timer <= diff) + { + DoCast(me, SPELL_FROST_NOVA); + FrostNova_Timer = 20000; + } else FrostNova_Timer -= diff; + + if (Frostbolt_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_FROSTBOLT); + Frostbolt_Timer = 5000; + } else Frostbolt_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; +}; + +/*###### +## npc_isla_starmane +######*/ +enum eIslaStarmaneData +{ + SAY_PROGRESS_1 = 0, + SAY_PROGRESS_2 = 1, + SAY_PROGRESS_3 = 2, + SAY_PROGRESS_4 = 3, + + QUEST_EFTW_H = 10052, + QUEST_EFTW_A = 10051, + GO_CAGE = 182794, + SPELL_CAT = 32447, +}; + +class npc_isla_starmane : public CreatureScript +{ +public: + npc_isla_starmane() : CreatureScript("npc_isla_starmane") { } + + struct npc_isla_starmaneAI : public npc_escortAI + { + npc_isla_starmaneAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 0: + if (GameObject* Cage = me->FindNearestGameObject(GO_CAGE, 10)) + Cage->SetGoState(GO_STATE_ACTIVE); + break; + case 2: + Talk(SAY_PROGRESS_1, player->GetGUID()); + break; + case 5: + Talk(SAY_PROGRESS_2, player->GetGUID()); + break; + case 6: + Talk(SAY_PROGRESS_3, player->GetGUID()); + break; + case 29: + Talk(SAY_PROGRESS_4, player->GetGUID()); + if (player->GetTeam() == ALLIANCE) + player->GroupEventHappens(QUEST_EFTW_A, me); + else if (player->GetTeam() == HORDE) + player->GroupEventHappens(QUEST_EFTW_H, me); + me->SetInFront(player); + break; + case 30: + me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); + break; + case 31: + DoCast(me, SPELL_CAT); + me->SetWalk(false); + break; + } + } + + void Reset() + { + me->RestoreFaction(); + } + + void JustDied(Unit* /*killer*/) + { + if (Player* player = GetPlayerForEscort()) + { + if (player->GetTeam() == ALLIANCE) + player->FailQuest(QUEST_EFTW_A); + else if (player->GetTeam() == HORDE) + player->FailQuest(QUEST_EFTW_H); + } + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_EFTW_H || quest->GetQuestId() == QUEST_EFTW_A) + { + CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); + creature->setFaction(113); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_isla_starmaneAI(creature); + } +}; + +/*###### +## go_skull_pile +######*/ +#define GOSSIP_S_DARKSCREECHER_AKKARAI "Summon Darkscreecher Akkarai" +#define GOSSIP_S_KARROG "Summon Karrog" +#define GOSSIP_S_GEZZARAK_THE_HUNTRESS "Summon Gezzarak the Huntress" +#define GOSSIP_S_VAKKIZ_THE_WINDRAGER "Summon Vakkiz the Windrager" + +class go_skull_pile : public GameObjectScript +{ +public: + go_skull_pile() : GameObjectScript("go_skull_pile") { } + + bool OnGossipSelect(Player* player, GameObject* go, uint32 sender, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (sender) + { + case GOSSIP_SENDER_MAIN: SendActionMenu(player, go, action); break; + } + return true; + } + + bool OnGossipHello(Player* player, GameObject* go) + { + if ((player->GetQuestStatus(11885) == QUEST_STATUS_INCOMPLETE) || player->GetQuestRewardStatus(11885)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_DARKSCREECHER_AKKARAI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_KARROG, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_GEZZARAK_THE_HUNTRESS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_S_VAKKIZ_THE_WINDRAGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4); + } + + player->SEND_GOSSIP_MENU(go->GetGOInfo()->questgiver.gossipID, go->GetGUID()); + return true; + } + + void SendActionMenu(Player* player, GameObject* /*go*/, uint32 action) + { + switch (action) + { + case GOSSIP_ACTION_INFO_DEF + 1: + player->CastSpell(player, 40642, false); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + player->CastSpell(player, 40640, false); + break; + case GOSSIP_ACTION_INFO_DEF + 3: + player->CastSpell(player, 40632, false); + break; + case GOSSIP_ACTION_INFO_DEF + 4: + player->CastSpell(player, 40644, false); + break; + } + } +}; + +/*###### +## npc_slim +######*/ + +enum eSlim +{ + FACTION_CONSORTIUM = 933 +}; + +class npc_slim : public CreatureScript +{ +public: + npc_slim() : CreatureScript("npc_slim") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isVendor() && player->GetReputationRank(FACTION_CONSORTIUM) >= REP_FRIENDLY) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(9896, creature->GetGUID()); + } + else + player->SEND_GOSSIP_MENU(9895, creature->GetGUID()); + + return true; + } +}; + +/*######## +####npc_akuno +#####*/ + +enum eAkuno +{ + QUEST_ESCAPING_THE_TOMB = 10887, + NPC_CABAL_SKRIMISHER = 21661 +}; + +class npc_akuno : public CreatureScript +{ +public: + npc_akuno() : CreatureScript("npc_akuno") { } + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPING_THE_TOMB) + { + if (npc_akunoAI* pEscortAI = CAST_AI(npc_akuno::npc_akunoAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID()); + + if (player->GetTeamId() == TEAM_ALLIANCE) + creature->setFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE); + else + creature->setFaction(FACTION_ESCORT_H_NEUTRAL_PASSIVE); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_akunoAI(creature); + } + + struct npc_akunoAI : public npc_escortAI + { + npc_akunoAI(Creature* creature) : npc_escortAI(creature) {} + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 3: + me->SummonCreature(NPC_CABAL_SKRIMISHER, -2795.99f, 5420.33f, -34.53f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + me->SummonCreature(NPC_CABAL_SKRIMISHER, -2793.55f, 5412.79f, -34.53f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); + break; + case 11: + if (player->GetTypeId() == TYPEID_PLAYER) + player->GroupEventHappens(QUEST_ESCAPING_THE_TOMB, me); + break; + } + } + + void JustSummoned(Creature* summon) + { + summon->AI()->AttackStart(me); + } + }; +}; + +void AddSC_terokkar_forest() +{ + new mob_unkor_the_ruthless(); + new mob_infested_root_walker(); + new mob_rotting_forest_rager(); + new mob_netherweb_victim(); + new npc_floon(); + new npc_isla_starmane(); + new go_skull_pile(); + new npc_skywing(); + new npc_slim(); + new npc_akuno(); +} diff --git a/src/server/scripts/Outland/zone_zangarmarsh.cpp b/src/server/scripts/Outland/zone_zangarmarsh.cpp new file mode 100644 index 00000000000..319da372bf8 --- /dev/null +++ b/src/server/scripts/Outland/zone_zangarmarsh.cpp @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * 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, see . + */ + +/* ScriptData +SDName: Zangarmarsh +SD%Complete: 100 +SDComment: Quest support: 9752, 9785, 9803, 10009. Mark Of ... buffs. +SDCategory: Zangarmarsh +EndScriptData */ + +/* ContentData +npcs_ashyen_and_keleth +npc_cooshcoosh +npc_elder_kuruti +npc_mortog_steamhead +npc_kayra_longmane +npc_timothy_daniels +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "ScriptedEscortAI.h" +#include "Player.h" +#include "WorldSession.h" + +/*###### +## npcs_ashyen_and_keleth +######*/ + +#define GOSSIP_ITEM_BLESS_ASH "Grant me your mark, wise ancient." +#define GOSSIP_ITEM_BLESS_KEL "Grant me your mark, mighty ancient." + +enum AshyenAndKeleth +{ + GOSSIP_REWARD_BLESS = 0, + + NPC_ASHYEN = 17900, + NPC_KELETH = 17901, + + SPELL_BLESS_ASH_EXA = 31815, + SPELL_BLESS_ASH_REV = 31811, + SPELL_BLESS_ASH_HON = 31810, + SPELL_BLESS_ASH_FRI = 31808, + + SPELL_BLESS_KEL_EXA = 31814, + SPELL_BLESS_KEL_REV = 31813, + SPELL_BLESS_KEL_HON = 31812, + SPELL_BLESS_KEL_FRI = 31807 +}; + +class npcs_ashyen_and_keleth : public CreatureScript +{ +public: + npcs_ashyen_and_keleth() : CreatureScript("npcs_ashyen_and_keleth") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetReputationRank(942) > REP_NEUTRAL) + { + if (creature->GetEntry() == NPC_ASHYEN) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BLESS_ASH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + if (creature->GetEntry() == NPC_KELETH) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BLESS_KEL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + } + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + creature->setPowerType(POWER_MANA); + creature->SetMaxPower(POWER_MANA, 200); //set a "fake" mana value, we can't depend on database doing it in this case + creature->SetPower(POWER_MANA, 200); + + if (creature->GetEntry() == NPC_ASHYEN) //check which Creature we are dealing with + { + uint32 spell = 0; + switch (player->GetReputationRank(942)) + { //mark of lore + case REP_FRIENDLY: + spell = SPELL_BLESS_ASH_FRI; + break; + case REP_HONORED: + spell = SPELL_BLESS_ASH_HON; + break; + case REP_REVERED: + spell = SPELL_BLESS_ASH_REV; + break; + case REP_EXALTED: + spell = SPELL_BLESS_ASH_EXA; + break; + default: + break; + } + + if (spell) + { + creature->CastSpell(player, spell, true); + creature->AI()->Talk(GOSSIP_REWARD_BLESS); + } + } + + if (creature->GetEntry() == NPC_KELETH) + { + uint32 spell = 0; + switch (player->GetReputationRank(942)) //mark of war + { + case REP_FRIENDLY: + spell = SPELL_BLESS_KEL_FRI; + break; + case REP_HONORED: + spell = SPELL_BLESS_KEL_HON; + break; + case REP_REVERED: + spell = SPELL_BLESS_KEL_REV; + break; + case REP_EXALTED: + spell = SPELL_BLESS_KEL_EXA; + break; + default: + break; + } + + if (spell) + { + creature->CastSpell(player, spell, true); + creature->AI()->Talk(GOSSIP_REWARD_BLESS); + } + } + player->CLOSE_GOSSIP_MENU(); + player->TalkedToCreature(creature->GetEntry(), creature->GetGUID()); + } + return true; + } +}; + +/*###### +## npc_cooshcoosh +######*/ + +#define GOSSIP_COOSH "You owe Sim'salabim money. Hand them over or die!" + +enum eCooshhooosh +{ + SPELL_LIGHTNING_BOLT = 9532, + QUEST_CRACK_SKULLS = 10009, + FACTION_HOSTILE_CO = 45 +}; + +class npc_cooshcoosh : public CreatureScript +{ +public: + npc_cooshcoosh() : CreatureScript("npc_cooshcoosh") { } + + struct npc_cooshcooshAI : public ScriptedAI + { + npc_cooshcooshAI(Creature* creature) : ScriptedAI(creature) + { + m_uiNormFaction = creature->getFaction(); + } + + uint32 m_uiNormFaction; + uint32 LightningBolt_Timer; + + void Reset() + { + LightningBolt_Timer = 2000; + if (me->getFaction() != m_uiNormFaction) + me->setFaction(m_uiNormFaction); + } + + void EnterCombat(Unit* /*who*/) {} + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (LightningBolt_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_LIGHTNING_BOLT); + LightningBolt_Timer = 5000; + } else LightningBolt_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_cooshcooshAI (creature); + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_COOSH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(9441, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF) + { + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_HOSTILE_CO); + creature->AI()->AttackStart(player); + } + return true; + } +}; + +/*###### +## npc_elder_kuruti +######*/ + +#define GOSSIP_ITEM_KUR1 "Greetings, elder. It is time for your people to end their hostility towards the draenei and their allies." +#define GOSSIP_ITEM_KUR2 "I did not mean to deceive you, elder. The draenei of Telredor thought to approach you in a way that would seem familiar to you." +#define GOSSIP_ITEM_KUR3 "I will tell them. Farewell, elder." + +class npc_elder_kuruti : public CreatureScript +{ +public: + npc_elder_kuruti() : CreatureScript("npc_elder_kuruti") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (player->GetQuestStatus(9803) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + + player->SEND_GOSSIP_MENU(9226, creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(9227, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 1: + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KUR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + player->SEND_GOSSIP_MENU(9229, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF + 2: + { + if (!player->HasItemCount(24573)) + { + ItemPosCountVec dest; + uint32 itemId = 24573; + InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, 1, NULL); + if (msg == EQUIP_ERR_OK) + { + player->StoreNewItem(dest, itemId, true); + } + else + player->SendEquipError(msg, NULL, NULL, itemId); + } + player->SEND_GOSSIP_MENU(9231, creature->GetGUID()); + break; + } + } + return true; + } +}; + +/*###### +## npc_mortog_steamhead +######*/ +class npc_mortog_steamhead : public CreatureScript +{ +public: + npc_mortog_steamhead() : CreatureScript("npc_mortog_steamhead") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isVendor() && player->GetReputationRank(942) == REP_EXALTED) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_TRADE) + player->GetSession()->SendListInventory(creature->GetGUID()); + return true; + } +}; + +/*###### +## npc_kayra_longmane +######*/ + +enum eKayra +{ + SAY_START = 0, + SAY_AMBUSH1 = 1, + SAY_PROGRESS = 2, + SAY_AMBUSH2 = 3, + SAY_END = 4, + + QUEST_ESCAPE_FROM = 9752, + NPC_SLAVEBINDER = 18042 +}; + +class npc_kayra_longmane : public CreatureScript +{ +public: + npc_kayra_longmane() : CreatureScript("npc_kayra_longmane") { } + + struct npc_kayra_longmaneAI : public npc_escortAI + { + npc_kayra_longmaneAI(Creature* creature) : npc_escortAI(creature) {} + + void Reset() { } + + void WaypointReached(uint32 waypointId) + { + Player* player = GetPlayerForEscort(); + if (!player) + return; + + switch (waypointId) + { + case 4: + Talk(SAY_AMBUSH1, player->GetGUID()); + DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 5: + Talk(SAY_PROGRESS, player->GetGUID()); + SetRun(); + break; + case 16: + Talk(SAY_AMBUSH2, player->GetGUID()); + DoSpawnCreature(NPC_SLAVEBINDER, -10.0f, -5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + DoSpawnCreature(NPC_SLAVEBINDER, -8.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); + break; + case 17: + SetRun(false); + break; + case 25: + Talk(SAY_END, player->GetGUID()); + player->GroupEventHappens(QUEST_ESCAPE_FROM, me); + break; + } + } + }; + + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ESCAPE_FROM) + { + creature->AI()->Talk(SAY_START, player->GetGUID()); + + if (npc_escortAI* pEscortAI = CAST_AI(npc_kayra_longmane::npc_kayra_longmaneAI, creature->AI())) + pEscortAI->Start(false, false, player->GetGUID()); + } + return true; + } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_kayra_longmaneAI(creature); + } +}; + +/*###### +## npc_timothy_daniels +######*/ + +#define GOSSIP_TIMOTHY_DANIELS_ITEM1 "Specialist, eh? Just what kind of specialist are you, anyway?" +#define GOSSIP_TEXT_BROWSE_POISONS "Let me browse your reagents and poison supplies." + +enum eTimothy +{ + GOSSIP_TEXTID_TIMOTHY_DANIELS1 = 9239 +}; + +class npc_timothy_daniels : public CreatureScript +{ +public: + npc_timothy_daniels() : CreatureScript("npc_timothy_daniels") { } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (creature->isVendor()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_POISONS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TIMOTHY_DANIELS_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_TIMOTHY_DANIELS1, creature->GetGUID()); + break; + case GOSSIP_ACTION_TRADE: + player->GetSession()->SendListInventory(creature->GetGUID()); + break; + } + + return true; + } +}; + +/*###### +## AddSC +######*/ + +void AddSC_zangarmarsh() +{ + new npcs_ashyen_and_keleth(); + new npc_cooshcoosh(); + new npc_elder_kuruti(); + new npc_mortog_steamhead(); + new npc_kayra_longmane(); + new npc_timothy_daniels(); +} -- cgit v1.2.3 From dbfc4b83aa64425cf14e8c40cc5605ca91d5b8f4 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Wed, 2 Jan 2013 15:08:13 -0330 Subject: Core/Scripting: Some file name updates. --- src/server/scripts/EasternKingdoms/CMakeLists.txt | 2 +- .../ScarletEnclave/the_scarlet_enclave.cpp | 124 --------------------- .../ScarletEnclave/zone_the_scarlet_enclave.cpp | 124 +++++++++++++++++++++ src/server/scripts/Northrend/CMakeLists.txt | 4 +- .../Nexus/Nexus/boss_commander_kolurg.cpp | 75 +++++++++++++ .../Nexus/Nexus/boss_commander_stoutbeard.cpp | 71 ++++++++++++ .../Northrend/Nexus/Nexus/commander_kolurg.cpp | 75 ------------- .../Northrend/Nexus/Nexus/commander_stoutbeard.cpp | 71 ------------ 8 files changed, 273 insertions(+), 273 deletions(-) delete mode 100644 src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp create mode 100644 src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp create mode 100644 src/server/scripts/Northrend/Nexus/Nexus/boss_commander_kolurg.cpp create mode 100644 src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp delete mode 100644 src/server/scripts/Northrend/Nexus/Nexus/commander_kolurg.cpp delete mode 100644 src/server/scripts/Northrend/Nexus/Nexus/commander_stoutbeard.cpp (limited to 'src') diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index bbdbe396a95..15faf9dfb83 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -71,7 +71,7 @@ set(scripts_STAT_SRCS EasternKingdoms/ScarletEnclave/chapter2.cpp EasternKingdoms/ScarletEnclave/chapter5.cpp EasternKingdoms/ScarletEnclave/chapter1.cpp - EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp + EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp EasternKingdoms/zone_eastern_plaguelands.cpp EasternKingdoms/MoltenCore/boss_gehennas.cpp EasternKingdoms/MoltenCore/boss_lucifron.cpp diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp deleted file mode 100644 index a86b15a7f5c..00000000000 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "PassiveAI.h" -#include "Player.h" - -/*#### -## npc_valkyr_battle_maiden -####*/ -#define SPELL_REVIVE 51918 -#define VALK_WHISPER "It is not yet your time, champion. Rise! Rise and fight once more!" - -class npc_valkyr_battle_maiden : public CreatureScript -{ -public: - npc_valkyr_battle_maiden() : CreatureScript("npc_valkyr_battle_maiden") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_valkyr_battle_maidenAI (creature); - } - - struct npc_valkyr_battle_maidenAI : public PassiveAI - { - npc_valkyr_battle_maidenAI(Creature* creature) : PassiveAI(creature) {} - - uint32 FlyBackTimer; - float x, y, z; - uint32 phase; - - void Reset() - { - me->setActive(true); - me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetCanFly(true); - FlyBackTimer = 500; - phase = 0; - - me->GetPosition(x, y, z); - z += 4.0f; - x -= 3.5f; - y -= 5.0f; - me->GetMotionMaster()->Clear(false); - me->SetPosition(x, y, z, 0.0f); - } - - void UpdateAI(const uint32 diff) - { - if (FlyBackTimer <= diff) - { - Player* player = NULL; - if (me->isSummon()) - if (Unit* summoner = me->ToTempSummon()->GetSummoner()) - if (summoner->GetTypeId() == TYPEID_PLAYER) - player = CAST_PLR(summoner); - - if (!player) - phase = 3; - - switch (phase) - { - case 0: - me->SetWalk(false); - me->HandleEmoteCommand(EMOTE_STATE_FLYGRABCLOSED); - FlyBackTimer = 500; - break; - case 1: - player->GetClosePoint(x, y, z, me->GetObjectSize()); - z += 2.5f; - x -= 2.0f; - y -= 1.5f; - me->GetMotionMaster()->MovePoint(0, x, y, z); - me->SetTarget(player->GetGUID()); - me->SetVisible(true); - FlyBackTimer = 4500; - break; - case 2: - if (!player->isRessurectRequested()) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01); - DoCast(player, SPELL_REVIVE, true); - me->MonsterWhisper(VALK_WHISPER, player->GetGUID()); - } - FlyBackTimer = 5000; - break; - case 3: - me->SetVisible(false); - FlyBackTimer = 3000; - break; - case 4: - me->DisappearAndDie(); - break; - default: - //Nothing To DO - break; - } - ++phase; - } else FlyBackTimer-=diff; - } - }; - -}; - -void AddSC_the_scarlet_enclave() -{ - new npc_valkyr_battle_maiden(); -} diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp new file mode 100644 index 00000000000..a86b15a7f5c --- /dev/null +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "PassiveAI.h" +#include "Player.h" + +/*#### +## npc_valkyr_battle_maiden +####*/ +#define SPELL_REVIVE 51918 +#define VALK_WHISPER "It is not yet your time, champion. Rise! Rise and fight once more!" + +class npc_valkyr_battle_maiden : public CreatureScript +{ +public: + npc_valkyr_battle_maiden() : CreatureScript("npc_valkyr_battle_maiden") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_valkyr_battle_maidenAI (creature); + } + + struct npc_valkyr_battle_maidenAI : public PassiveAI + { + npc_valkyr_battle_maidenAI(Creature* creature) : PassiveAI(creature) {} + + uint32 FlyBackTimer; + float x, y, z; + uint32 phase; + + void Reset() + { + me->setActive(true); + me->SetVisible(false); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + me->SetCanFly(true); + FlyBackTimer = 500; + phase = 0; + + me->GetPosition(x, y, z); + z += 4.0f; + x -= 3.5f; + y -= 5.0f; + me->GetMotionMaster()->Clear(false); + me->SetPosition(x, y, z, 0.0f); + } + + void UpdateAI(const uint32 diff) + { + if (FlyBackTimer <= diff) + { + Player* player = NULL; + if (me->isSummon()) + if (Unit* summoner = me->ToTempSummon()->GetSummoner()) + if (summoner->GetTypeId() == TYPEID_PLAYER) + player = CAST_PLR(summoner); + + if (!player) + phase = 3; + + switch (phase) + { + case 0: + me->SetWalk(false); + me->HandleEmoteCommand(EMOTE_STATE_FLYGRABCLOSED); + FlyBackTimer = 500; + break; + case 1: + player->GetClosePoint(x, y, z, me->GetObjectSize()); + z += 2.5f; + x -= 2.0f; + y -= 1.5f; + me->GetMotionMaster()->MovePoint(0, x, y, z); + me->SetTarget(player->GetGUID()); + me->SetVisible(true); + FlyBackTimer = 4500; + break; + case 2: + if (!player->isRessurectRequested()) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01); + DoCast(player, SPELL_REVIVE, true); + me->MonsterWhisper(VALK_WHISPER, player->GetGUID()); + } + FlyBackTimer = 5000; + break; + case 3: + me->SetVisible(false); + FlyBackTimer = 3000; + break; + case 4: + me->DisappearAndDie(); + break; + default: + //Nothing To DO + break; + } + ++phase; + } else FlyBackTimer-=diff; + } + }; + +}; + +void AddSC_the_scarlet_enclave() +{ + new npc_valkyr_battle_maiden(); +} diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 18549a1bf70..1da1e4ab178 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -78,8 +78,8 @@ set(scripts_STAT_SRCS Northrend/Nexus/Oculus/boss_urom.cpp Northrend/Nexus/Oculus/oculus.cpp Northrend/Nexus/Oculus/instance_oculus.cpp - Northrend/Nexus/Nexus/commander_kolurg.cpp - Northrend/Nexus/Nexus/commander_stoutbeard.cpp + Northrend/Nexus/Nexus/boss_commander_kolurg.cpp + Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp Northrend/Nexus/Nexus/boss_ormorok.cpp Northrend/Nexus/Nexus/boss_magus_telestra.cpp Northrend/Nexus/Nexus/instance_nexus.cpp diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_kolurg.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_kolurg.cpp new file mode 100644 index 00000000000..fedb1f5cebc --- /dev/null +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_kolurg.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* Script Data Start +SDName: Boss Commander Kolurg +SDAuthor: LordVanMartin +SD%Complete: +SDComment: Only Alliance Heroic +SDCategory: +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" + +#define SPELL_BATTLE_SHOUT 31403 +#define SPELL_CHARGE 60067 +#define SPELL_FRIGHTENING_SHOUT 19134 +#define SPELL_WHIRLWIND_1 38619 +#define SPELL_WHIRLWIND_2 38618 + +//not used +//Yell +#define SAY_AGGRO -1576024 +#define SAY_KILL -1576025 +#define SAY_DEATH -1576026 + +class boss_commander_kolurg : public CreatureScript +{ +public: + boss_commander_kolurg() : CreatureScript("boss_commander_kolurg") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_commander_kolurgAI (creature); + } + + struct boss_commander_kolurgAI : public ScriptedAI + { + boss_commander_kolurgAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + void EnterCombat(Unit* /*who*/) {} + void AttackStart(Unit* /*who*/) {} + void MoveInLineOfSight(Unit* /*who*/) {} + void UpdateAI(const uint32 /*diff*/) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + void JustDied(Unit* /*killer*/) {} + }; + +}; + +void AddSC_boss_commander_kolurg() +{ + new boss_commander_kolurg(); +} diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp new file mode 100644 index 00000000000..39c93f15d6f --- /dev/null +++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008-2013 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, see . + */ + +/* Script Data Start +SDName: Boss Commander Stoutbeard +SDAuthor: LordVanMartin +SD%Complete: +SDComment: Only Horde Heroic +SDCategory: +Script Data End */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" + +enum CommanderStoutbeard +{ + SPELL_BATTLE_SHOUT = 31403, + SPELL_CHARGE = 60067, + SPELL_FRIGHTENING_SHOUT = 19134, + SPELL_WHIRLWIND_1 = 38619, + SPELL_WHIRLWIND_2 = 38618 +}; + + +class boss_commander_stoutbeard : public CreatureScript +{ +public: + boss_commander_stoutbeard() : CreatureScript("boss_commander_stoutbeard") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_commander_stoutbeardAI (creature); + } + + struct boss_commander_stoutbeardAI : public ScriptedAI + { + boss_commander_stoutbeardAI(Creature* creature) : ScriptedAI(creature) {} + + void Reset() {} + void AttackStart(Unit* /*who*/) {} + void MoveInLineOfSight(Unit* /*who*/) {} + void UpdateAI(const uint32 /*diff*/) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + +}; + +void AddSC_boss_commander_stoutbeard() +{ + new boss_commander_stoutbeard(); +} diff --git a/src/server/scripts/Northrend/Nexus/Nexus/commander_kolurg.cpp b/src/server/scripts/Northrend/Nexus/Nexus/commander_kolurg.cpp deleted file mode 100644 index fedb1f5cebc..00000000000 --- a/src/server/scripts/Northrend/Nexus/Nexus/commander_kolurg.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* Script Data Start -SDName: Boss Commander Kolurg -SDAuthor: LordVanMartin -SD%Complete: -SDComment: Only Alliance Heroic -SDCategory: -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" - -#define SPELL_BATTLE_SHOUT 31403 -#define SPELL_CHARGE 60067 -#define SPELL_FRIGHTENING_SHOUT 19134 -#define SPELL_WHIRLWIND_1 38619 -#define SPELL_WHIRLWIND_2 38618 - -//not used -//Yell -#define SAY_AGGRO -1576024 -#define SAY_KILL -1576025 -#define SAY_DEATH -1576026 - -class boss_commander_kolurg : public CreatureScript -{ -public: - boss_commander_kolurg() : CreatureScript("boss_commander_kolurg") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_commander_kolurgAI (creature); - } - - struct boss_commander_kolurgAI : public ScriptedAI - { - boss_commander_kolurgAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - void EnterCombat(Unit* /*who*/) {} - void AttackStart(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - void UpdateAI(const uint32 /*diff*/) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - void JustDied(Unit* /*killer*/) {} - }; - -}; - -void AddSC_boss_commander_kolurg() -{ - new boss_commander_kolurg(); -} diff --git a/src/server/scripts/Northrend/Nexus/Nexus/commander_stoutbeard.cpp b/src/server/scripts/Northrend/Nexus/Nexus/commander_stoutbeard.cpp deleted file mode 100644 index 39c93f15d6f..00000000000 --- a/src/server/scripts/Northrend/Nexus/Nexus/commander_stoutbeard.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008-2013 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, see . - */ - -/* Script Data Start -SDName: Boss Commander Stoutbeard -SDAuthor: LordVanMartin -SD%Complete: -SDComment: Only Horde Heroic -SDCategory: -Script Data End */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" - -enum CommanderStoutbeard -{ - SPELL_BATTLE_SHOUT = 31403, - SPELL_CHARGE = 60067, - SPELL_FRIGHTENING_SHOUT = 19134, - SPELL_WHIRLWIND_1 = 38619, - SPELL_WHIRLWIND_2 = 38618 -}; - - -class boss_commander_stoutbeard : public CreatureScript -{ -public: - boss_commander_stoutbeard() : CreatureScript("boss_commander_stoutbeard") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_commander_stoutbeardAI (creature); - } - - struct boss_commander_stoutbeardAI : public ScriptedAI - { - boss_commander_stoutbeardAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - void AttackStart(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - void UpdateAI(const uint32 /*diff*/) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; - -}; - -void AddSC_boss_commander_stoutbeard() -{ - new boss_commander_stoutbeard(); -} -- cgit v1.2.3 From 786f27b74c697db19071288ca4d138c374ed25ea Mon Sep 17 00:00:00 2001 From: Spp Date: Wed, 2 Jan 2013 21:23:54 +0100 Subject: Core/Misc: Missing changes from 8968dbc (Partial revert of 2292025) Closes #8843 --- src/server/game/Entities/Object/ObjectDefines.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index e41716dde36..021e3d0aea5 100644 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -23,18 +23,18 @@ enum HighGuid { - HIGHGUID_ITEM = 0x400, // blizz 4000 - HIGHGUID_CONTAINER = 0x400, // blizz 4000 - HIGHGUID_PLAYER = 0x000, // blizz 0000 - HIGHGUID_GAMEOBJECT = 0xF11, // blizz F110 - HIGHGUID_TRANSPORT = 0xF12, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) - HIGHGUID_UNIT = 0xF13, // blizz F130 - HIGHGUID_PET = 0xF14, // blizz F140 - HIGHGUID_VEHICLE = 0xF15, // blizz F550 - HIGHGUID_DYNAMICOBJECT = 0xF10, // blizz F100 + HIGHGUID_ITEM = 0x4000, // blizz 4000 + HIGHGUID_CONTAINER = 0x4000, // blizz 4000 + HIGHGUID_PLAYER = 0x0000, // blizz 0000 + HIGHGUID_GAMEOBJECT = 0xF110, // blizz F110 + HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) + HIGHGUID_UNIT = 0xF130, // blizz F130 + HIGHGUID_PET = 0xF140, // blizz F140 + HIGHGUID_VEHICLE = 0xF150, // blizz F550 + HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100 HIGHGUID_CORPSE = 0xF101, // blizz F100 - HIGHGUID_MO_TRANSPORT = 0x1FC, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) - HIGHGUID_GROUP = 0x1F5 + HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) + HIGHGUID_GROUP = 0x1F05 }; // used for creating values for respawn for example -- cgit v1.2.3 From 57c275f3e176d561cff5823ab1a89054aba033ef Mon Sep 17 00:00:00 2001 From: Vincent_Michael Date: Wed, 2 Jan 2013 21:42:50 +0100 Subject: Core: Fix warning --- src/server/game/AI/EventAI/CreatureEventAI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index 43f6a91242a..f1a1b8824c7 100644 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -1268,7 +1268,7 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger return false; //Check for power - if (!triggered && me->GetPower((Powers)spell->PowerType) < spell->CalcPowerCost(me, spell->GetSchoolMask())) + if (!triggered && me->GetPower((Powers)spell->PowerType) < uint32(spell->CalcPowerCost(me, spell->GetSchoolMask()))) return false; //Unit is out of range of this spell -- cgit v1.2.3