diff options
Diffstat (limited to 'src/server/scripts')
19 files changed, 706 insertions, 634 deletions
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 5d6cdb3fb63..ccd82aa3ef9 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -299,7 +299,7 @@ public: else if (commentToken[1] == '/') { std::string str; - getline(ifs, str); + std::getline(ifs, str); continue; } // regular data diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index 3db0e1092fd..326360428d2 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -174,7 +174,7 @@ public: anchor->GetContactPoint(me, anchorX, anchorY, z, 1.0f); playerGUID = target->GetGUID(); - Talk(SAY_EVENT_START); + Talk(SAY_EVENT_START, target); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp index ea56494f0f9..421f3d771a0 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp @@ -207,7 +207,7 @@ public: void DamageTaken(Unit* /*done_by*/, uint32 &damage) override { - if (damage > me->GetHealth() && events.IsInPhase(PHASE_ONE)) + if (damage >= me->GetHealth() && events.IsInPhase(PHASE_ONE)) { damage = 0; me->RemoveAllAuras(); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index 01ac3920082..1a98c081570 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -689,54 +689,57 @@ class boss_alyson_antille : public CreatureScript } }; -struct boss_gazakrothAI : public boss_hexlord_addAI +class boss_gazakroth : public CreatureScript { - boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature) - { - Initialize(); - } - - void Initialize() - { - firebolt_timer = 2000; - } + public: - uint32 firebolt_timer; + boss_gazakroth() : CreatureScript("boss_gazakroth") { } + + struct boss_gazakrothAI : public boss_hexlord_addAI + { + boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature) + { + Initialize(); + } - void Reset() override - { - Initialize(); - boss_hexlord_addAI::Reset(); - } + void Initialize() + { + firebolt_timer = 2 * IN_MILLISECONDS; + } + + void Reset() override + { + Initialize(); + boss_hexlord_addAI::Reset(); + } - void AttackStart(Unit* who) override - { - if (!who) - return; + void AttackStart(Unit* who) override + { + AttackStartCaster(who, 20.0f); + } - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) + void UpdateAI(uint32 diff) override { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); + if (!UpdateVictim()) + return; + + if (firebolt_timer <= diff) + { + DoCastVictim(SPELL_FIREBOLT, false); + firebolt_timer = 0.7 * IN_MILLISECONDS; + } else firebolt_timer -= diff; + + boss_hexlord_addAI::UpdateAI(diff); } - } - } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + private: + uint32 firebolt_timer; + }; - if (firebolt_timer <= diff) + CreatureAI* GetAI(Creature* creature) const override { - DoCastVictim(SPELL_FIREBOLT, false); - firebolt_timer = 700; - } else firebolt_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } + return GetInstanceAI<boss_gazakrothAI>(creature); + } }; class boss_lord_raadan : public CreatureScript @@ -1062,7 +1065,7 @@ void AddSC_boss_hex_lord_malacrass() { new boss_hexlord_malacrass(); new boss_thurg(); - // new boss_gazakroth(); + new boss_gazakroth(); new boss_lord_raadan(); new boss_darkheart(); new boss_slither(); diff --git a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp index 898e3f9a2cb..ecfd705cf4d 100644 --- a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp +++ b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp @@ -92,7 +92,7 @@ public: me->SetWalk(false); break; case 115: - player->AreaExploredOrEventHappens(QUEST_MISSING_IN_ACTION); + player->GroupEventHappens(QUEST_MISSING_IN_ACTION, me); timer = 2000; phase = 4; break; diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index 9a68973b8d1..ce8d0cfbcfd 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -92,7 +92,6 @@ set(scripts_STAT_SRCS Kalimdor/RuinsOfAhnQiraj/boss_moam.cpp Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h Kalimdor/RuinsOfAhnQiraj/boss_kurinnaxx.cpp - Kalimdor/zone_mulgore.cpp Kalimdor/zone_bloodmyst_isle.cpp Kalimdor/zone_thunder_bluff.cpp Kalimdor/zone_azshara.cpp diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp index a7c17a9df3e..f4a7e1f4185 100644 --- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp +++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp @@ -136,131 +136,7 @@ public: } }; -enum SnufflenoseGopher -{ - NPC_SNUFFLENOSE_GOPHER = 4781, - GO_BLUELEAF_TUBBER = 20920, - ACTION_FIND_NEW_TUBBER = 0, - POINT_TUBBER = 0 -}; - -struct npc_snufflenose_gopher : public CreatureScript -{ -public: - npc_snufflenose_gopher() : CreatureScript("npc_snufflenose_gopher") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_snufflenose_gopherAI(creature); - } - - struct npc_snufflenose_gopherAI : public PetAI - { - npc_snufflenose_gopherAI(Creature* creature) : PetAI(creature) - { - IsMovementActive = false; - } - - void Reset() override - { - IsMovementActive = false; - TargetTubberGUID.Clear(); - } - - void MovementInform(uint32 type, uint32 id) override - { - if (type == POINT_MOTION_TYPE && id == POINT_TUBBER) - { - if (GameObject* go = me->GetMap()->GetGameObject(TargetTubberGUID)) - { - go->SetRespawnTime(5 * MINUTE); - go->Refresh(); - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - } - - IsMovementActive = false; - } - else - PetAI::MovementInform(type, id); - } - - void DoFindNewTubber() - { - std::list<GameObject*> tubbersInRange; - GetGameObjectListWithEntryInGrid(tubbersInRange, me, GO_BLUELEAF_TUBBER, 40.0f); - - if (tubbersInRange.empty()) - return; - - tubbersInRange.remove_if([](GameObject* go) - { - return go->isSpawned() || !go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - }); - - tubbersInRange.sort(Trinity::ObjectDistanceOrderPred(me)); - - GameObject* nearestTubber = tubbersInRange.front(); - if (!nearestTubber) - return; - - TargetTubberGUID = nearestTubber->GetGUID(); - - // XFurry was wrong... - me->GetMotionMaster()->MovePoint(POINT_TUBBER, nearestTubber->GetPositionX(), - nearestTubber->GetPositionY(), - nearestTubber->GetPositionZ()); - IsMovementActive = true; - } - - void UpdateAI(uint32 diff) override - { - if (!IsMovementActive) - PetAI::UpdateAI(diff); - } - - void DoAction(int32 action) override - { - if (action == ACTION_FIND_NEW_TUBBER) - DoFindNewTubber(); - } - - - bool IsMovementActive; - ObjectGuid TargetTubberGUID; - }; -}; - -class spell_snufflenose_command : public SpellScriptLoader -{ - public: - spell_snufflenose_command() : SpellScriptLoader("spell_snufflenose_command") { } - - class spell_snufflenose_commandSpellScript : public SpellScript - { - PrepareSpellScript(spell_snufflenose_commandSpellScript); - - void HandleEffect(SpellEffIndex /*effIndex*/) - { - if (Creature* target = GetHitCreature()) - if (target->GetEntry() == NPC_SNUFFLENOSE_GOPHER) - target->AI()->DoAction(ACTION_FIND_NEW_TUBBER); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_snufflenose_commandSpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_snufflenose_commandSpellScript(); - } -}; - void AddSC_razorfen_kraul() { - new npc_snufflenose_gopher(); new npc_willix(); - new spell_snufflenose_command(); } diff --git a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp index 390fd3e529f..ca5e4697c35 100644 --- a/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp +++ b/src/server/scripts/Kalimdor/zone_bloodmyst_isle.cpp @@ -29,6 +29,7 @@ EndContentData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "PassiveAI.h" #include "Player.h" /*###### @@ -48,14 +49,18 @@ class npc_webbed_creature : public CreatureScript public: npc_webbed_creature() : CreatureScript("npc_webbed_creature") { } - struct npc_webbed_creatureAI : public ScriptedAI + struct npc_webbed_creatureAI : public NullCreatureAI { - npc_webbed_creatureAI(Creature* creature) : ScriptedAI(creature) { } + npc_webbed_creatureAI(Creature* creature) : NullCreatureAI(creature) { } void Reset() override { } void EnterCombat(Unit* /*who*/) override { } + void AttackStart(Unit* /*who*/) override { } + + void MoveInLineOfSight(Unit* /*who*/) override { } + void JustDied(Unit* killer) override { uint32 spawnCreatureID = 0; diff --git a/src/server/scripts/Kalimdor/zone_felwood.cpp b/src/server/scripts/Kalimdor/zone_felwood.cpp index cdf04b1d4cc..91b9ce08010 100644 --- a/src/server/scripts/Kalimdor/zone_felwood.cpp +++ b/src/server/scripts/Kalimdor/zone_felwood.cpp @@ -100,7 +100,44 @@ public: } }; +/*###### +## at_ancient_leaf +######*/ + +enum AncientMisc +{ + QUEST_ANCIENT_LEAF = 7632, + NPC_VARTRUS = 14524, + NPC_STOMA = 14525, + NPC_HASTAT = 14526, + CREATURE_GROUP_ANCIENTS = 1 +}; + +class at_ancient_leaf : public AreaTriggerScript +{ + public: + at_ancient_leaf() : AreaTriggerScript("at_ancient_leaf") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override + { + if (player->IsGameMaster() || !player->IsAlive()) + return false; + + // Handle Call Ancients event start - The area trigger summons 3 ancients + if ((player->GetQuestStatus(QUEST_ANCIENT_LEAF) == QUEST_STATUS_COMPLETE) || (player->GetQuestStatus(QUEST_ANCIENT_LEAF) == QUEST_STATUS_REWARDED)) + { + // If ancients are already spawned, skip the rest + if (GetClosestCreatureWithEntry(player, NPC_VARTRUS, 50.0f) || GetClosestCreatureWithEntry(player, NPC_STOMA, 50.0f) || GetClosestCreatureWithEntry(player, NPC_HASTAT, 50.0f)) + return true; + + player->GetMap()->SummonCreatureGroup(CREATURE_GROUP_ANCIENTS); + } + return false; + } +}; + void AddSC_felwood() { new npcs_riverbreeze_and_silversky(); + new at_ancient_leaf(); } diff --git a/src/server/scripts/Kalimdor/zone_mulgore.cpp b/src/server/scripts/Kalimdor/zone_mulgore.cpp deleted file mode 100644 index 0d0ef218885..00000000000 --- a/src/server/scripts/Kalimdor/zone_mulgore.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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 <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -SDName: Mulgore -SD%Complete: 100 -SDComment: Support for quest: 11129, 772 -SDCategory: Mulgore -EndScriptData */ - -/* ContentData -npc_kyle_frenzied -npc_plains_vision -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "Player.h" -#include "SpellInfo.h" - -/*##### -# 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 override - { - return new npc_kyle_frenziedAI(creature); - } - - struct npc_kyle_frenziedAI : public ScriptedAI - { - npc_kyle_frenziedAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - EventActive = false; - IsMovingToLunch = false; - PlayerGUID.Clear(); - EventTimer = 5000; - EventPhase = 0; - } - - bool EventActive; - bool IsMovingToLunch; - ObjectGuid PlayerGUID; - uint32 EventTimer; - uint8 EventPhase; - - void Reset() override - { - Initialize(); - - if (me->GetEntry() == NPC_KYLE_FRIENDLY) - me->UpdateEntry(NPC_KYLE_FRENZIED); - } - - void SpellHit(Unit* Caster, SpellInfo const* Spell) override - { - 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) override - { - if (Type != POINT_MOTION_TYPE || !EventActive) - return; - - if (PointId == POINT_ID) - IsMovingToLunch = false; - } - - void UpdateAI(uint32 diff) override - { - if (EventActive) - { - if (IsMovingToLunch) - return; - - if (EventTimer <= diff) - { - EventTimer = 5000; - ++EventPhase; - - switch (EventPhase) - { - case 1: - if (Unit* unit = ObjectAccessor::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 = ObjectAccessor::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 override - { - return new npc_plains_visionAI(creature); - } - - struct npc_plains_visionAI : public ScriptedAI - { - npc_plains_visionAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } - - void Initialize() - { - WayPointId = 0; - newWaypoint = true; - amountWP = 49; - } - - bool newWaypoint; - uint8 WayPointId; - uint8 amountWP; - - void Reset() override - { - Initialize(); - } - - void EnterCombat(Unit* /*who*/) override { } - - void MovementInform(uint32 type, uint32 id) override - { - if (type != POINT_MOTION_TYPE) - return; - - if (id < amountWP) - { - ++WayPointId; - newWaypoint = true; - } - else - { - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); - } - } - - void UpdateAI(uint32 /*diff*/) override - { - if (newWaypoint) - { - me->GetMotionMaster()->MovePoint(WayPointId, wpPlainVision[WayPointId]); - newWaypoint = false; - } - } - }; - -}; - -/*##### -# -######*/ - -void AddSC_mulgore() -{ - new npc_kyle_frenzied(); - new npc_plains_vision(); -} diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index 97c4372f0e6..0b829c2c6dd 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -27,7 +27,7 @@ enum Yells SAY_SLAY = 1, SAY_DEATH = 2, SAY_SOUL_STORM = 3, - SAY_CORRUPT_SOUL = 4, + SAY_CORRUPT_SOUL = 4 }; enum Spells @@ -39,9 +39,9 @@ enum Spells SPELL_TELEPORT = 68988, SPELL_FEAR = 68950, SPELL_SOULSTORM = 68872, - SPELL_SOULSTORM_CHANNEL = 69008, // pre-fight - SPELL_SOULSTORM_VISUAL = 68870, // pre-cast soulstorm - SPELL_PURPLE_BANISH_VISUAL = 68862 // Used by Soul Fragment (Aura) + SPELL_SOULSTORM_CHANNEL = 69008, // Pre-fight + SPELL_SOULSTORM_VISUAL = 68870, // Pre-cast Soulstorm + SPELL_PURPLE_BANISH_VISUAL = 68862 // Used by Soul Fragment (Aura) }; enum Events @@ -50,7 +50,7 @@ enum Events EVENT_SHADOW_BOLT = 2, EVENT_CORRUPT_SOUL = 3, EVENT_SOULSTORM = 4, - EVENT_FEAR = 5, + EVENT_FEAR = 5 }; enum CombatPhases @@ -59,6 +59,11 @@ enum CombatPhases PHASE_2 = 2 }; +enum Misc +{ + DATA_SOUL_POWER = 1 +}; + class boss_bronjahm : public CreatureScript { public: @@ -73,33 +78,30 @@ class boss_bronjahm : public CreatureScript void Reset() override { - events.Reset(); + _Reset(); events.SetPhase(PHASE_1); events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000); events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000)); events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000, 35000), 0, PHASE_1); - - instance->SetBossState(DATA_BRONJAHM, NOT_STARTED); } - void JustReachedHome() override - { - DoCast(me, SPELL_SOULSTORM_CHANNEL, true); - } + void JustReachedHome() override + { + _JustReachedHome(); + DoCast(me, SPELL_SOULSTORM_CHANNEL, true); + } void EnterCombat(Unit* /*who*/) override { + _EnterCombat(); Talk(SAY_AGGRO); me->RemoveAurasDueToSpell(SPELL_SOULSTORM_CHANNEL); - - instance->SetBossState(DATA_BRONJAHM, IN_PROGRESS); } void JustDied(Unit* /*killer*/) override { + _JustDied(); Talk(SAY_DEATH); - - instance->SetBossState(DATA_BRONJAHM, DONE); } void KilledUnit(Unit* who) override @@ -128,6 +130,23 @@ class boss_bronjahm : public CreatureScript summon->CastSpell(summon, SPELL_PURPLE_BANISH_VISUAL, true); } + uint32 GetData(uint32 type) const override + { + if (type == DATA_SOUL_POWER) + { + uint32 count = 0; + for (ObjectGuid const& guid : summons) + { + if (Creature* summon = ObjectAccessor::GetCreature(*me, guid)) + if (summon->GetEntry() == NPC_CORRUPTED_SOUL_FRAGMENT && summon->IsAlive()) + ++count; + } + return count; + } + + return 0; + } + void UpdateAI(uint32 diff) override { if (!UpdateVictim()) @@ -143,13 +162,21 @@ class boss_bronjahm : public CreatureScript switch (eventId) { case EVENT_MAGIC_BANE: - DoCastVictim(SPELL_MAGIC_S_BANE); + DoCastAOE(SPELL_MAGIC_S_BANE); events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000)); break; case EVENT_SHADOW_BOLT: - if (!me->IsWithinMeleeRange(me->GetVictim())) + if (events.IsInPhase(PHASE_2)) + { DoCastVictim(SPELL_SHADOW_BOLT); - events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000); + events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(1, 2) * IN_MILLISECONDS); + } + else + { + if (!me->IsWithinMeleeRange(me->GetVictim())) + DoCastVictim(SPELL_SHADOW_BOLT); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 2 * IN_MILLISECONDS); + } break; case EVENT_CORRUPT_SOUL: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) @@ -165,8 +192,7 @@ class boss_bronjahm : public CreatureScript me->CastSpell(me, SPELL_SOULSTORM, false); break; case EVENT_FEAR: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) - me->CastCustomSpell(SPELL_FEAR, SPELLVALUE_MAX_TARGETS, 1, target, false); + me->CastCustomSpell(SPELL_FEAR, SPELLVALUE_MAX_TARGETS, 1, nullptr, false); events.ScheduleEvent(EVENT_FEAR, urand(8000, 12000), 0, PHASE_2); break; default: @@ -174,7 +200,8 @@ class boss_bronjahm : public CreatureScript } } - DoMeleeAttackIfReady(); + if (!events.IsInPhase(PHASE_2)) + DoMeleeAttackIfReady(); } }; @@ -201,17 +228,11 @@ class npc_corrupted_soul_fragment : public CreatureScript if (type != CHASE_MOTION_TYPE) return; - if (TempSummon* summ = me->ToTempSummon()) - { - ObjectGuid BronjahmGUID(instance->GetGuidData(DATA_BRONJAHM)); - if (BronjahmGUID.GetCounter() != id) - return; - - if (Creature* bronjahm = ObjectAccessor::GetCreature(*me, BronjahmGUID)) - me->CastSpell(bronjahm, SPELL_CONSUME_SOUL, true); + if (instance->GetGuidData(DATA_BRONJAHM).GetCounter() != id) + return; - summ->UnSummon(); - } + me->CastSpell((Unit*)nullptr, SPELL_CONSUME_SOUL, true); + me->DespawnOrUnsummon(); } private: @@ -220,7 +241,7 @@ class npc_corrupted_soul_fragment : public CreatureScript CreatureAI* GetAI(Creature* creature) const override { - return GetInstanceAI<npc_corrupted_soul_fragmentAI>(creature); + return GetInstanceAI<npc_corrupted_soul_fragmentAI>(creature, FoSScriptName); } }; @@ -238,12 +259,10 @@ class spell_bronjahm_magic_bane : public SpellScriptLoader if (GetHitUnit()->getPowerType() != POWER_MANA) return; - const int32 maxDamage = GetCaster()->GetMap()->GetSpawnMode() == 1 ? 15000 : 10000; - int32 newDamage = GetHitDamage(); - newDamage += GetHitUnit()->GetMaxPower(POWER_MANA)/2; - newDamage = std::min<int32>(maxDamage, newDamage); + int32 const maxDamage = GetCaster()->GetMap()->IsHeroic() ? 15000 : 10000; + int32 newDamage = GetHitDamage() + (GetHitUnit()->GetMaxPower(POWER_MANA) / 2); - SetHitDamage(newDamage); + SetHitDamage(std::min<int32>(maxDamage, newDamage)); } void Register() override @@ -261,7 +280,7 @@ class spell_bronjahm_magic_bane : public SpellScriptLoader class spell_bronjahm_consume_soul : public SpellScriptLoader { public: - spell_bronjahm_consume_soul() : SpellScriptLoader("spell_bronjahm_consume_soul") { } + spell_bronjahm_consume_soul() : SpellScriptLoader("spell_bronjahm_consume_soul") { } class spell_bronjahm_consume_soul_SpellScript : public SpellScript { @@ -285,38 +304,22 @@ class spell_bronjahm_consume_soul : public SpellScriptLoader } }; -class spell_bronjahm_soulstorm_channel : public SpellScriptLoader +static uint32 const SoulstormVisualSpells[] = { - public: - spell_bronjahm_soulstorm_channel() : SpellScriptLoader("spell_bronjahm_soulstorm_channel") { } - - class spell_bronjahm_soulstorm_channel_AuraScript : public AuraScript - { - PrepareAuraScript(spell_bronjahm_soulstorm_channel_AuraScript); - - void HandlePeriodicTick(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - for (uint32 i = 68904; i <= 68907; ++i) - GetTarget()->CastSpell(GetTarget(), i, true); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_bronjahm_soulstorm_channel_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_bronjahm_soulstorm_channel_AuraScript(); - } + 68904, + 68886, + 68905, + 68896, + 68906, + 68897, + 68907, + 68898 }; class spell_bronjahm_soulstorm_visual : public SpellScriptLoader { public: - spell_bronjahm_soulstorm_visual() : SpellScriptLoader("spell_bronjahm_soulstorm_visual") { } + spell_bronjahm_soulstorm_visual(char const* scriptName) : SpellScriptLoader(scriptName) { } class spell_bronjahm_soulstorm_visual_AuraScript : public AuraScript { @@ -325,11 +328,7 @@ class spell_bronjahm_soulstorm_visual : public SpellScriptLoader void HandlePeriodicTick(AuraEffect const* aurEff) { PreventDefaultAction(); - if (aurEff->GetTickNumber()%5) - return; - GetTarget()->CastSpell(GetTarget(), 68886, true); - for (uint32 i = 68896; i <= 68898; ++i) - GetTarget()->CastSpell(GetTarget(), i, true); + GetTarget()->CastSpell(GetTarget(), SoulstormVisualSpells[aurEff->GetTickNumber() % 8], true); } void Register() override @@ -344,21 +343,6 @@ class spell_bronjahm_soulstorm_visual : public SpellScriptLoader } }; -class DistanceCheck -{ - public: - explicit DistanceCheck(Unit* _caster) : caster(_caster) { } - - bool operator() (WorldObject* unit) const - { - if (caster->GetExactDist2d(unit) <= 10.0f) - return true; - return false; - } - - Unit* caster; -}; - class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader { public: @@ -368,25 +352,19 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader { PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript); - void FilterTargetsInitial(std::list<WorldObject*>& targets) - { - targets.remove_if(DistanceCheck(GetCaster())); - sharedTargets = targets; - } - - // use the same target for first and second effect - void FilterTargetsSubsequent(std::list<WorldObject*>& targets) + void FilterTargets(std::list<WorldObject*>& targets) { - targets = sharedTargets; + Unit* caster = GetCaster(); + targets.remove_if([caster](WorldObject* target) + { + return caster->GetExactDist2d(target) <= 10.0f; + }); } void Register() override { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_DEST_AREA_ENEMY); } - - std::list<WorldObject*> sharedTargets; }; SpellScript* GetSpellScript() const override @@ -395,13 +373,25 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader } }; +class achievement_bronjahm_soul_power : public AchievementCriteriaScript +{ + public: + achievement_bronjahm_soul_power() : AchievementCriteriaScript("achievement_bronjahm_soul_power") { } + + bool OnCheck(Player* /*source*/, Unit* target) override + { + return target && target->GetAI()->GetData(DATA_SOUL_POWER) >= 4; + } +}; + void AddSC_boss_bronjahm() { new boss_bronjahm(); new npc_corrupted_soul_fragment(); new spell_bronjahm_magic_bane(); new spell_bronjahm_consume_soul(); - new spell_bronjahm_soulstorm_channel(); - new spell_bronjahm_soulstorm_visual(); + new spell_bronjahm_soulstorm_visual("spell_bronjahm_soulstorm_channel"); + new spell_bronjahm_soulstorm_visual("spell_bronjahm_soulstorm_visual"); new spell_bronjahm_soulstorm_targeting(); + new achievement_bronjahm_soul_power(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp index 2f1d4943019..d5f00757039 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp @@ -128,7 +128,7 @@ class boss_devourer_of_souls : public CreatureScript struct boss_devourer_of_soulsAI : public BossAI { - boss_devourer_of_soulsAI(Creature* creature) : BossAI(creature, DATA_DEVOURER_EVENT) + boss_devourer_of_soulsAI(Creature* creature) : BossAI(creature, DATA_DEVOURER_OF_SOULS) { Initialize(); beamAngle = 0.f; @@ -143,20 +143,17 @@ class boss_devourer_of_souls : public CreatureScript void Reset() override { + _Reset(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); me->SetDisplayId(DISPLAY_ANGER); me->SetReactState(REACT_AGGRESSIVE); - events.Reset(); - summons.DespawnAll(); - Initialize(); - - instance->SetData(DATA_DEVOURER_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) override { + _EnterCombat(); Talk(SAY_FACE_AGGRO); if (!me->FindNearestCreature(NPC_CRUCIBLE_OF_SOULS, 60)) // Prevent double spawn @@ -166,8 +163,6 @@ class boss_devourer_of_souls : public CreatureScript events.ScheduleEvent(EVENT_WELL_OF_SOULS, 30000); events.ScheduleEvent(EVENT_UNLEASHED_SOULS, 20000); events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000, 70000)); - - instance->SetData(DATA_DEVOURER_EVENT, IN_PROGRESS); } void KilledUnit(Unit* victim) override @@ -175,7 +170,7 @@ class boss_devourer_of_souls : public CreatureScript if (victim->GetTypeId() != TYPEID_PLAYER) return; - int32 textId = 0; + uint8 textId = 0; switch (me->GetDisplayId()) { case DISPLAY_ANGER: @@ -197,14 +192,12 @@ class boss_devourer_of_souls : public CreatureScript void JustDied(Unit* /*killer*/) override { - summons.DespawnAll(); + _JustDied(); Position spawnPoint = {5618.139f, 2451.873f, 705.854f, 0}; Talk(SAY_FACE_DEATH); - instance->SetData(DATA_DEVOURER_EVENT, DONE); - int32 entryIndex; if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) entryIndex = 0; @@ -402,11 +395,6 @@ class spell_devourer_of_souls_mirrored_soul_proc : public SpellScriptLoader return true; } - bool Load() override - { - return true; - } - bool CheckProc(ProcEventInfo& /*eventInfo*/) { return GetCaster() && GetCaster()->IsAlive(); diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h index 054e5d5a7bd..ddbc117e7fd 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/forge_of_souls.h @@ -15,38 +15,44 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_FORGE_OF_SOULS_H -#define DEF_FORGE_OF_SOULS_H +#ifndef FORGE_OF_SOULS_H_ +#define FORGE_OF_SOULS_H_ #define FoSScriptName "instance_forge_of_souls" #define DataHeader "FOS" +uint32 const EncounterCount = 2; + enum Data { - DATA_BRONJAHM = 0, - DATA_DEVOURER = 1, - DATA_DEVOURER_EVENT = 2, - DATA_TEAM_IN_INSTANCE = 3, + // Encounter states and GUIDs + DATA_BRONJAHM = 0, + DATA_DEVOURER_OF_SOULS = 1, + + // Additional Data + DATA_TEAM_IN_INSTANCE = 2 }; enum Creatures { - CREATURE_BRONJAHM = 36497, - CREATURE_DEVOURER = 36502, - - NPC_SYLVANAS_PART1 = 37596, - NPC_SYLVANAS_PART2 = 38161, - NPC_JAINA_PART1 = 37597, - NPC_JAINA_PART2 = 38160, - NPC_KALIRA = 37583, - NPC_ELANDRA = 37774, - NPC_LORALEN = 37779, - NPC_KORELN = 37582, - NPC_CHAMPION_1_HORDE = 37584, - NPC_CHAMPION_2_HORDE = 37587, - NPC_CHAMPION_3_HORDE = 37588, - NPC_CHAMPION_1_ALLIANCE = 37496, - NPC_CHAMPION_2_ALLIANCE = 37497, - NPC_CRUCIBLE_OF_SOULS = 37094, + NPC_BRONJAHM = 36497, + NPC_DEVOURER = 36502, + NPC_CORRUPTED_SOUL_FRAGMENT = 36535, + + NPC_SYLVANAS_PART1 = 37596, + NPC_SYLVANAS_PART2 = 38161, + NPC_JAINA_PART1 = 37597, + NPC_JAINA_PART2 = 38160, + NPC_KALIRA = 37583, + NPC_ELANDRA = 37774, + NPC_LORALEN = 37779, + NPC_KORELN = 37582, + NPC_CHAMPION_1_HORDE = 37584, + NPC_CHAMPION_2_HORDE = 37587, + NPC_CHAMPION_3_HORDE = 37588, + NPC_CHAMPION_1_ALLIANCE = 37496, + NPC_CHAMPION_2_ALLIANCE = 37497, + NPC_CRUCIBLE_OF_SOULS = 37094 }; -#endif + +#endif // FORGE_OF_SOULS_H_ diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp index 8b586ea7fc2..db7628ebada 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp @@ -20,13 +20,6 @@ #include "forge_of_souls.h" #include "Player.h" -#define MAX_ENCOUNTER 2 - -/* Forge of Souls encounters: -0- Bronjahm, The Godfather of Souls -1- The Devourer of Souls -*/ - class instance_forge_of_souls : public InstanceMapScript { public: @@ -37,7 +30,7 @@ class instance_forge_of_souls : public InstanceMapScript instance_forge_of_souls_InstanceScript(Map* map) : InstanceScript(map) { SetHeaders(DataHeader); - SetBossNumber(MAX_ENCOUNTER); + SetBossNumber(EncounterCount); teamInInstance = 0; } @@ -60,10 +53,10 @@ class instance_forge_of_souls : public InstanceMapScript switch (creature->GetEntry()) { - case CREATURE_BRONJAHM: + case NPC_BRONJAHM: bronjahm = creature->GetGUID(); break; - case CREATURE_DEVOURER: + case NPC_DEVOURER: devourerOfSouls = creature->GetGUID(); break; case NPC_SYLVANAS_PART1: @@ -100,7 +93,7 @@ class instance_forge_of_souls : public InstanceMapScript { case DATA_BRONJAHM: return bronjahm; - case DATA_DEVOURER: + case DATA_DEVOURER_OF_SOULS: return devourerOfSouls; default: break; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 7b80db7dd39..9edde447f32 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -21,6 +21,7 @@ #include "SpellScript.h" #include "Transport.h" #include "Player.h" +#include "MoveSplineInit.h" #include "halls_of_reflection.h" enum Text @@ -342,6 +343,20 @@ class npc_jaina_or_sylvanas_intro_hor : public CreatureScript public: npc_jaina_or_sylvanas_intro_hor() : CreatureScript("npc_jaina_or_sylvanas_intro_hor") { } + bool OnGossipHello(Player* player, Creature* creature) override + { + // override default gossip + if (InstanceScript* instance = creature->GetInstanceScript()) + if (instance->GetData(DATA_QUEL_DELAR_EVENT) == IN_PROGRESS || instance->GetData(DATA_QUEL_DELAR_EVENT) == SPECIAL) + { + player->PlayerTalkClass->ClearMenus(); + return true; + } + + // load default gossip + return false; + } + struct npc_jaina_or_sylvanas_intro_horAI : public ScriptedAI { npc_jaina_or_sylvanas_intro_horAI(Creature* creature) : ScriptedAI(creature) @@ -1998,6 +2013,13 @@ class at_hor_intro_start : public AreaTriggerScript if (_instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED) _instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS); + if (player->HasAura(SPELL_QUEL_DELAR_COMPULSION) && (player->GetQuestStatus(QUEST_HALLS_OF_REFLECTION_ALLIANCE) == QUEST_STATUS_INCOMPLETE || + player->GetQuestStatus(QUEST_HALLS_OF_REFLECTION_HORDE) == QUEST_STATUS_INCOMPLETE) && _instance->GetData(DATA_QUEL_DELAR_EVENT) == NOT_STARTED) + { + _instance->SetData(DATA_QUEL_DELAR_EVENT, IN_PROGRESS); + _instance->SetGuidData(DATA_QUEL_DELAR_INVOKER, player->GetGUID()); + } + return true; } }; @@ -2330,6 +2352,395 @@ class npc_lumbering_abomination : public CreatureScript } }; +enum QuelDelarUther +{ + ACTION_UTHER_START_SCREAM = 1, + ACTION_UTHER_OUTRO = 2, + + EVENT_UTHER_1 = 1, + EVENT_UTHER_2 = 2, + EVENT_UTHER_3 = 3, + EVENT_UTHER_4 = 4, + EVENT_UTHER_5 = 5, + EVENT_UTHER_6 = 6, + EVENT_UTHER_7 = 7, + EVENT_UTHER_8 = 8, + EVENT_UTHER_9 = 9, + EVENT_UTHER_10 = 10, + EVENT_UTHER_11 = 11, + EVENT_UTHER_FACING = 12, + EVENT_UTHER_KNEEL = 13, + + SAY_UTHER_QUEL_DELAR_1 = 16, + SAY_UTHER_QUEL_DELAR_2 = 17, + SAY_UTHER_QUEL_DELAR_3 = 18, + SAY_UTHER_QUEL_DELAR_4 = 19, + SAY_UTHER_QUEL_DELAR_5 = 20, + SAY_UTHER_QUEL_DELAR_6 = 21, + + SPELL_ESSENCE_OF_CAPTURED_1 = 73036 +}; + +enum QuelDelarSword +{ + SPELL_WHIRLWIND_VISUAL = 70300, + SPELL_HEROIC_STRIKE = 29426, + SPELL_WHIRLWIND = 67716, + SPELL_BLADESTORM = 67541, + + NPC_QUEL_DELAR = 37158, + POINT_TAKE_OFF = 1, + + EVENT_QUEL_DELAR_INIT = 1, + EVENT_QUEL_DELAR_FLIGHT_INIT = 2, + EVENT_QUEL_DELAR_FLIGHT = 3, + EVENT_QUEL_DELAR_LAND = 4, + EVENT_QUEL_DELAR_FIGHT = 5, + EVENT_QUEL_DELAR_BLADESTORM = 6, + EVENT_QUEL_DELAR_HEROIC_STRIKE = 7, + EVENT_QUEL_DELAR_WHIRLWIND = 8, + + SAY_QUEL_DELAR_SWORD = 0 +}; + +enum QuelDelarMisc +{ + SAY_FROSTMOURNE_BUNNY = 0, + SPELL_QUEL_DELAR_WILL = 70698 +}; + +Position const QuelDelarCenterPos = { 5309.259f, 2006.390f, 718.046f, 0.0f }; +Position const QuelDelarSummonPos = { 5298.473f, 1994.852f, 709.424f, 3.979351f }; +Position const QuelDelarMovement[] = +{ + { 5292.870f, 1998.950f, 718.046f, 0.0f }, + { 5295.819f, 1991.912f, 707.707f, 0.0f }, + { 5295.301f, 1989.782f, 708.696f, 0.0f } +}; + +Position const UtherQuelDelarMovement[] = +{ + { 5336.830f, 1981.700f, 709.319f, 0.0f }, + { 5314.350f, 1993.440f, 707.726f, 0.0f } +}; + +class npc_uther_quel_delar : public CreatureScript +{ + public: + npc_uther_quel_delar() : CreatureScript("npc_uther_quel_delar") { } + + struct npc_uther_quel_delarAI : public ScriptedAI + { + npc_uther_quel_delarAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + void Reset() override + { + // Prevent to break Uther in intro event during instance encounter + if (_instance->GetData(DATA_QUEL_DELAR_EVENT) != IN_PROGRESS && _instance->GetData(DATA_QUEL_DELAR_EVENT) != SPECIAL) + return; + + _events.Reset(); + _events.ScheduleEvent(EVENT_UTHER_1, 1); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_UTHER_START_SCREAM: + _instance->SetData(DATA_QUEL_DELAR_EVENT, SPECIAL); + _events.ScheduleEvent(EVENT_UTHER_2, 0); + break; + case ACTION_UTHER_OUTRO: + _events.ScheduleEvent(EVENT_UTHER_6, 0); + break; + default: + break; + } + } + + void MovementInform(uint32 /*type*/, uint32 pointId) override + { + switch (pointId) + { + case 1: + _events.ScheduleEvent(EVENT_UTHER_FACING, 1000); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + // Prevent to break Uther in intro event during instance encounter + if (_instance->GetData(DATA_QUEL_DELAR_EVENT) != IN_PROGRESS && _instance->GetData(DATA_QUEL_DELAR_EVENT) != SPECIAL) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_UTHER_1: + Talk(SAY_UTHER_QUEL_DELAR_1); + break; + case EVENT_UTHER_2: + if (Creature* bunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FROSTMOURNE_ALTAR_BUNNY))) + if (Unit* target = ObjectAccessor::GetPlayer(*me, _instance->GetGuidData(DATA_QUEL_DELAR_INVOKER))) + bunny->CastSpell(target, SPELL_QUEL_DELAR_WILL, true); + _events.ScheduleEvent(EVENT_UTHER_3, 2000); + break; + case EVENT_UTHER_3: + me->SummonCreature(NPC_QUEL_DELAR, QuelDelarSummonPos); + _events.ScheduleEvent(EVENT_UTHER_4, 2000); + break; + case EVENT_UTHER_4: + Talk(SAY_UTHER_QUEL_DELAR_2); + _events.ScheduleEvent(EVENT_UTHER_5, 8000); + break; + case EVENT_UTHER_5: + me->GetMotionMaster()->MovePoint(1, UtherQuelDelarMovement[0]); + break; + case EVENT_UTHER_6: + me->SetWalk(true); + me->GetMotionMaster()->MovePoint(0, UtherQuelDelarMovement[1]); + _events.ScheduleEvent(EVENT_UTHER_7, 5000); + break; + case EVENT_UTHER_7: + Talk(SAY_UTHER_QUEL_DELAR_3); + _events.ScheduleEvent(EVENT_UTHER_8, 12000); + break; + case EVENT_UTHER_8: + Talk(SAY_UTHER_QUEL_DELAR_4); + _events.ScheduleEvent(EVENT_UTHER_9, 7000); + break; + case EVENT_UTHER_9: + Talk(SAY_UTHER_QUEL_DELAR_5); + _events.ScheduleEvent(EVENT_UTHER_10, 10000); + break; + case EVENT_UTHER_10: + Talk(SAY_UTHER_QUEL_DELAR_6); + _events.ScheduleEvent(EVENT_UTHER_11, 5000); + break; + case EVENT_UTHER_11: + DoCast(me, SPELL_ESSENCE_OF_CAPTURED_1, true); + me->DespawnOrUnsummon(3000); + _instance->SetData(DATA_QUEL_DELAR_EVENT, DONE); + break; + case EVENT_UTHER_FACING: + if (Creature* bunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FROSTMOURNE_ALTAR_BUNNY))) + me->SetFacingToObject(bunny); + _events.ScheduleEvent(EVENT_UTHER_KNEEL, 1000); + break; + case EVENT_UTHER_KNEEL: + me->HandleEmoteCommand(EMOTE_STATE_KNEEL); + break; + default: + break; + } + } + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI<npc_uther_quel_delarAI>(creature); + } +}; + +class npc_quel_delar_sword : public CreatureScript +{ + public: + npc_quel_delar_sword() : CreatureScript("npc_quel_delar_sword") { } + + struct npc_quel_delar_swordAI : public ScriptedAI + { + npc_quel_delar_swordAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); + _intro = true; + } + + void Reset() override + { + _events.Reset(); + me->SetSpeed(MOVE_FLIGHT, 4.5f, true); + DoCast(SPELL_WHIRLWIND_VISUAL); + if (_intro) + _events.ScheduleEvent(EVENT_QUEL_DELAR_INIT, 0); + else + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + } + + void EnterCombat(Unit* /*victim*/) override + { + _events.ScheduleEvent(EVENT_QUEL_DELAR_HEROIC_STRIKE, 4000); + _events.ScheduleEvent(EVENT_QUEL_DELAR_BLADESTORM, 6000); + _events.ScheduleEvent(EVENT_QUEL_DELAR_WHIRLWIND, 6000); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* uther = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_UTHER_QUEL_DELAR))) + uther->AI()->DoAction(ACTION_UTHER_OUTRO); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != EFFECT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_TAKE_OFF: + _events.ScheduleEvent(EVENT_QUEL_DELAR_FLIGHT, 0); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + if (!UpdateVictim()) + { + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_QUEL_DELAR_INIT: + if (Creature* bunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FROSTMOURNE_ALTAR_BUNNY))) + bunny->AI()->Talk(SAY_FROSTMOURNE_BUNNY); + _intro = false; + _events.ScheduleEvent(EVENT_QUEL_DELAR_FLIGHT_INIT, 2500); + break; + case EVENT_QUEL_DELAR_FLIGHT_INIT: + me->GetMotionMaster()->MoveTakeoff(POINT_TAKE_OFF, QuelDelarMovement[0]); + break; + case EVENT_QUEL_DELAR_FLIGHT: + { + Movement::MoveSplineInit init(me); + FillCirclePath(QuelDelarCenterPos, 18.0f, 718.046f, init.Path(), true); + init.SetFly(); + init.SetCyclic(); + init.SetAnimation(Movement::ToFly); + init.Launch(); + + _events.ScheduleEvent(EVENT_QUEL_DELAR_LAND, 15000); + break; + } + case EVENT_QUEL_DELAR_LAND: + me->StopMoving(); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveLand(0, QuelDelarMovement[1]); + _events.ScheduleEvent(EVENT_QUEL_DELAR_FIGHT, 6000); + break; + case EVENT_QUEL_DELAR_FIGHT: + Talk(SAY_QUEL_DELAR_SWORD); + me->GetMotionMaster()->MovePoint(0, QuelDelarMovement[2]); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); + break; + default: + break; + } + } + } + else + { + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_QUEL_DELAR_BLADESTORM: + DoCast(me, SPELL_BLADESTORM); + _events.ScheduleEvent(EVENT_QUEL_DELAR_BLADESTORM, 10000); + break; + case EVENT_QUEL_DELAR_HEROIC_STRIKE: + DoCastVictim(SPELL_HEROIC_STRIKE); + _events.ScheduleEvent(EVENT_QUEL_DELAR_HEROIC_STRIKE, 6000); + break; + case EVENT_QUEL_DELAR_WHIRLWIND: + DoCastAOE(SPELL_WHIRLWIND); + _events.ScheduleEvent(EVENT_QUEL_DELAR_WHIRLWIND, 1000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + } + + private: + void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise) + { + float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f; + float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY()); + + for (uint8 i = 0; i < 16; angle += step, ++i) + { + G3D::Vector3 point; + point.x = centerPos.GetPositionX() + radius * cosf(angle); + point.y = centerPos.GetPositionY() + radius * sinf(angle); + point.z = z; + path.push_back(point); + } + } + + EventMap _events; + InstanceScript* _instance; + bool _intro; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI<npc_quel_delar_swordAI>(creature); + } +}; + +// 5660 +class at_hor_uther_quel_delar_start : public AreaTriggerScript +{ + public: + at_hor_uther_quel_delar_start() : AreaTriggerScript("at_hor_uther_quel_delar_start") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override + { + if (player->IsGameMaster()) + return true; + + InstanceScript* _instance = player->GetInstanceScript(); + + if (_instance->GetData(DATA_QUEL_DELAR_EVENT) == IN_PROGRESS) + if (Creature* uther = ObjectAccessor::GetCreature(*player, _instance->GetGuidData(DATA_UTHER_QUEL_DELAR))) + uther->AI()->DoAction(ACTION_UTHER_START_SCREAM); + + return true; + } +}; + // 72900 - Start Halls of Reflection Quest AE class spell_hor_start_halls_of_reflection_quest_ae : public SpellScriptLoader { @@ -2447,6 +2858,7 @@ void AddSC_halls_of_reflection() new at_hor_waves_restarter(); new at_hor_impenetrable_door(); new at_hor_shadow_throne(); + new at_hor_uther_quel_delar_start(); new npc_jaina_or_sylvanas_intro_hor(); new npc_jaina_or_sylvanas_escape_hor(); new npc_the_lich_king_escape_hor(); @@ -2461,6 +2873,8 @@ void AddSC_halls_of_reflection() new npc_raging_ghoul(); new npc_risen_witch_doctor(); new npc_lumbering_abomination(); + new npc_uther_quel_delar(); + new npc_quel_delar_sword(); new spell_hor_start_halls_of_reflection_quest_ae(); new spell_hor_evasion(); new spell_hor_gunship_cannon_fire(); diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index 9594617fa9a..d2f9ab5d262 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -46,7 +46,13 @@ enum DataTypes DATA_ESCAPE_LEADER = 10, DATA_ICEWALL = 11, DATA_ICEWALL_TARGET = 12, - DATA_GUNSHIP = 13 + DATA_GUNSHIP = 13, + + // Quest stuff + DATA_QUEL_DELAR_EVENT = 14, + DATA_FROSTMOURNE_ALTAR_BUNNY = 15, + DATA_UTHER_QUEL_DELAR = 16, + DATA_QUEL_DELAR_INVOKER = 17 }; enum CreatureIds @@ -131,7 +137,8 @@ enum InstanceEvents EVENT_NEXT_WAVE = 2, EVENT_DO_WIPE = 3, EVENT_ADD_WAVE = 4, - EVENT_SPAWN_ESCAPE_EVENT = 5 + EVENT_SPAWN_ESCAPE_EVENT = 5, + EVENT_QUEL_DELAR_SUMMON_UTHER = 6 }; enum InstanceEventIds @@ -160,7 +167,17 @@ enum InstanceSpells // Gunship SPELL_GUNSHIP_CANNON_FIRE = 70017, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_ALLIANCE = 70021, - SPELL_GUNSHIP_CANNON_FIRE_MISSILE_HORDE = 70246 + SPELL_GUNSHIP_CANNON_FIRE_MISSILE_HORDE = 70246, + + // Halls of Reflection quest + SPELL_QUEL_DELAR_COMPULSION = 70013, + SPELL_ESSENCE_OF_CAPTURED = 70720 +}; + +enum InstanceQuests +{ + QUEST_HALLS_OF_REFLECTION_ALLIANCE = 24480, + QUEST_HALLS_OF_REFLECTION_HORDE = 24561 }; enum InstanceWorldStates diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index ea2a1539f1c..660a639487f 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -73,6 +73,8 @@ Position const SpawnPos[] = { 5299.250f, 2035.998f, 707.7781f, 5.026548f } }; +Position const UtherQuelDalarPos = { 5302.001f, 1988.698f, 707.7781f, 3.700098f }; + class instance_halls_of_reflection : public InstanceMapScript { public: @@ -89,6 +91,7 @@ class instance_halls_of_reflection : public InstanceMapScript _waveCount = 0; _introState = NOT_STARTED; _frostswornGeneralState = NOT_STARTED; + _quelDelarState = NOT_STARTED; events.Reset(); } @@ -159,6 +162,9 @@ class instance_halls_of_reflection : public InstanceMapScript case NPC_ICE_WALL_TARGET: IcewallTargetGUID = creature->GetGUID(); break; + case NPC_UTHER: + UtherGUID = creature->GetGUID(); + break; default: break; } @@ -439,6 +445,18 @@ class instance_halls_of_reflection : public InstanceMapScript HandleGameObject(ShadowThroneDoorGUID, true); _frostswornGeneralState = data; break; + case DATA_QUEL_DELAR_EVENT: + if (data == IN_PROGRESS) + { + if (_quelDelarState == NOT_STARTED) + { + if (Creature* bunny = instance->GetCreature(FrostmourneAltarBunnyGUID)) + bunny->CastSpell((Unit*)NULL, SPELL_ESSENCE_OF_CAPTURED); + events.ScheduleEvent(EVENT_QUEL_DELAR_SUMMON_UTHER, 2000); + } + } + _quelDelarState = data; + break; default: break; } @@ -446,6 +464,18 @@ class instance_halls_of_reflection : public InstanceMapScript SaveToDB(); } + void SetGuidData(uint32 type, ObjectGuid data) override + { + switch (type) + { + case DATA_QUEL_DELAR_INVOKER: + QuelDelarInvokerGUID = data; + break; + default: + break; + } + } + // wave scheduling, checked when wave npcs die void OnUnitDeath(Unit* unit) override { @@ -491,6 +521,9 @@ class instance_halls_of_reflection : public InstanceMapScript case EVENT_SPAWN_ESCAPE_EVENT: SpawnEscapeEvent(); break; + case EVENT_QUEL_DELAR_SUMMON_UTHER: + instance->SummonCreature(NPC_UTHER, UtherQuelDalarPos); + break; } } @@ -649,6 +682,8 @@ class instance_halls_of_reflection : public InstanceMapScript return _introState; case DATA_FROSTSWORN_GENERAL: return _frostswornGeneralState; + case DATA_QUEL_DELAR_EVENT: + return _quelDelarState; default: break; } @@ -682,6 +717,12 @@ class instance_halls_of_reflection : public InstanceMapScript return IcewallGUID; case DATA_ICEWALL_TARGET: return IcewallTargetGUID; + case DATA_FROSTMOURNE_ALTAR_BUNNY: + return FrostmourneAltarBunnyGUID; + case DATA_UTHER_QUEL_DELAR: + return UtherGUID; + case DATA_QUEL_DELAR_INVOKER: + return QuelDelarInvokerGUID; default: break; } @@ -691,7 +732,7 @@ class instance_halls_of_reflection : public InstanceMapScript void WriteSaveDataMore(std::ostringstream& data) override { - data << _introState << ' ' << _frostswornGeneralState; + data << _introState << ' ' << _frostswornGeneralState << ' ' << _quelDelarState; } void ReadSaveDataMore(std::istringstream& data) override @@ -708,6 +749,12 @@ class instance_halls_of_reflection : public InstanceMapScript SetData(DATA_FROSTSWORN_GENERAL, DONE); else SetData(DATA_FROSTSWORN_GENERAL, NOT_STARTED); + + data >> temp; + if (temp == DONE) + SetData(DATA_QUEL_DELAR_EVENT, DONE); + else + SetData(DATA_QUEL_DELAR_EVENT, NOT_STARTED); } private: @@ -731,6 +778,7 @@ class instance_halls_of_reflection : public InstanceMapScript uint32 _waveCount; uint32 _introState; uint32 _frostswornGeneralState; + uint32 _quelDelarState; EventMap events; GuidSet waveGuidList[8]; @@ -740,6 +788,8 @@ class instance_halls_of_reflection : public InstanceMapScript ObjectGuid CaptainGUID; ObjectGuid IcewallGUID; ObjectGuid IcewallTargetGUID; + ObjectGuid QuelDelarInvokerGUID; + ObjectGuid UtherGUID; GuidSet GunshipCannonGUIDs; GuidSet GunshipStairGUIDs; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 4c6fd0f2fcc..63082808e03 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -1259,7 +1259,7 @@ class spell_putricide_mutated_plague : public SpellScriptLoader return; uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; - SpellInfo const* spell = sSpellMgr->GetSpellInfo(triggerSpell); + SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(triggerSpell); spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, caster); int32 damage = spell->Effects[EFFECT_0].CalcValue(caster); diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp index f73930181f0..91c796a6e69 100644 --- a/src/server/scripts/Northrend/zone_zuldrak.cpp +++ b/src/server/scripts/Northrend/zone_zuldrak.cpp @@ -313,7 +313,7 @@ public: { player->KilledMonsterCredit(gymerDummy->GetEntry(), gymerDummy->GetGUID()); gymerDummy->CastSpell(gymerDummy, SPELL_GYMER_LOCK_EXPLOSION, true); - gymerDummy->DespawnOrUnsummon(); + gymerDummy->DespawnOrUnsummon(4 * IN_MILLISECONDS); } } return true; |
