diff options
| author | Shauren <shauren.trinity@gmail.com> | 2013-05-30 20:57:07 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2013-05-30 20:57:07 +0200 |
| commit | adb78862da66b13984c6494befdffbf5da0cdbe6 (patch) | |
| tree | 1514857a0131189194c251b7045d234a2bf45d86 /src/server/scripts/Northrend | |
| parent | cf23793b4b04cfe12f6fc1441a7d9f8192f7dfa6 (diff) | |
| parent | 3a697d4c9f5e9f2fa9c3b08c8e103d90472a871a (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts:
src/server/game/Achievements/AchievementMgr.cpp
src/server/game/Entities/Unit/Unit.cpp
src/server/game/Entities/Vehicle/Vehicle.cpp
src/server/game/Handlers/ItemHandler.cpp
src/server/game/Handlers/MailHandler.cpp
src/server/game/Server/Protocol/Opcodes.cpp
src/server/game/Server/Protocol/Opcodes.h
src/server/scripts/Commands/cs_misc.cpp
Diffstat (limited to 'src/server/scripts/Northrend')
7 files changed, 1265 insertions, 869 deletions
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp index 58dc74d0f0a..9d266c77b77 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp @@ -19,7 +19,7 @@ #include "ScriptedCreature.h" #include "halls_of_reflection.h" -enum Yells +enum Texts { SAY_AGGRO = 0, SAY_SLAY = 1, @@ -68,14 +68,14 @@ public: uiHopelessnessCount = 0; if (instance) - instance->SetData(DATA_FALRIC_EVENT, NOT_STARTED); + instance->SetBossState(DATA_FALRIC_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) { Talk(SAY_AGGRO); if (instance) - instance->SetData(DATA_FALRIC_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_FALRIC_EVENT, IN_PROGRESS); events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 23000); events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 9000); @@ -87,7 +87,7 @@ public: Talk(SAY_DEATH); if (instance) - instance->SetData(DATA_FALRIC_EVENT, DONE); + instance->SetBossState(DATA_FALRIC_EVENT, DONE); } void KilledUnit(Unit* /*victim*/) diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp index 08d5cf70ee1..e82f0d48ebd 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp @@ -19,7 +19,7 @@ #include "ScriptedCreature.h" #include "halls_of_reflection.h" -enum Yells +enum Texts { SAY_AGGRO = 0, SAY_SLAY = 1, @@ -63,14 +63,14 @@ public: boss_horAI::Reset(); if (instance) - instance->SetData(DATA_MARWYN_EVENT, NOT_STARTED); + instance->SetBossState(DATA_MARWYN_EVENT, NOT_STARTED); } void EnterCombat(Unit* /*who*/) { Talk(SAY_AGGRO); if (instance) - instance->SetData(DATA_MARWYN_EVENT, IN_PROGRESS); + instance->SetBossState(DATA_MARWYN_EVENT, IN_PROGRESS); events.ScheduleEvent(EVENT_OBLITERATE, 30000); /// @todo Check timer events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000); @@ -83,7 +83,7 @@ public: Talk(SAY_DEATH); if (instance) - instance->SetData(DATA_MARWYN_EVENT, DONE); + instance->SetBossState(DATA_MARWYN_EVENT, DONE); } void KilledUnit(Unit* /*victim*/) 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 b140801d8f1..a64f2cf5467 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -18,10 +18,10 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" -#include "halls_of_reflection.h" #include "Player.h" +#include "halls_of_reflection.h" -enum Yells +enum Text { SAY_JAINA_INTRO_1 = 0, SAY_JAINA_INTRO_2 = 1, @@ -66,17 +66,19 @@ enum Yells SAY_LK_INTRO_1 = 0, SAY_LK_INTRO_2 = 1, SAY_LK_INTRO_3 = 2, + SAY_LK_JAINA_INTRO_END = 3, + SAY_LK_SYLVANAS_INTRO_END = 4, SAY_FALRIC_INTRO_1 = 5, SAY_FALRIC_INTRO_2 = 6, - SAY_MARWYN_INTRO_1 = 4 + SAY_MARWYN_INTRO_1 = 4, }; enum Events { - EVENT_NONE, - + EVENT_WALK_INTRO1 = 1, + EVENT_WALK_INTRO2, EVENT_START_INTRO, EVENT_SKIP_INTRO, @@ -125,8 +127,13 @@ enum Events EVENT_INTRO_LK_7, EVENT_INTRO_LK_8, EVENT_INTRO_LK_9, + EVENT_INTRO_LK_10, + EVENT_INTRO_LK_11, EVENT_INTRO_END, + + EVENT_OPEN_FROSTWORN_DOOR, + EVENT_CLOSE_FROSTWORN_DOOR, }; enum eEnum @@ -140,6 +147,17 @@ enum eEnum QUEST_WRATH_OF_THE_LICH_KING_H2 = 24802, }; +enum Spells +{ + SPELL_CAST_VISUAL = 65633, // Jaina/Sylavana + SPELL_BOSS_SPAWN_AURA = 72712, // Falric and Marwyn + SPELL_UTHER_DESPAWN = 70693, + SPELL_TAKE_FROSTMOURNE = 72729, + SPELL_FROSTMOURNE_DESPAWN = 72726, + SPELL_FROSTMOURNE_VISUAL = 73220, + SPELL_FROSTMOURNE_SOUNDS = 70667, +}; + const Position HallsofReflectionLocs[]= { {5283.234863f, 1990.946777f, 707.695679f, 0.929097f}, // 2 Loralen Follows @@ -147,7 +165,7 @@ const Position HallsofReflectionLocs[]= {5401.866699f, 2110.837402f, 707.695251f, 0.800610f}, // 10 Loralen follows }; -const Position SpawnPos = {5262.540527f, 1949.693726f, 707.695007f, 0.808736f}; // Jaina/Sylvanas Beginning Position +const Position IntroPos = {5265.89f, 1952.98f, 707.6978f, 0.0f}; // Jaina/Sylvanas Intro Start Position const Position MoveThronePos = {5306.952148f, 1998.499023f, 709.341431f, 1.277278f}; // Jaina/Sylvanas walks to throne const Position UtherSpawnPos = {5308.310059f, 2003.857178f, 709.341431f, 4.650315f}; const Position LichKingSpawnPos = {5362.917480f, 2062.307129f, 707.695374f, 3.945812f}; @@ -156,58 +174,10 @@ const Position LichKingMoveAwayPos = {5400.069824f, 2102.7131689f, 707.69525f, class npc_jaina_or_sylvanas_hor : public CreatureScript { -private: - bool m_isSylvana; - -public: - npc_jaina_or_sylvanas_hor(bool isSylvana, const char* name) : CreatureScript(name), m_isSylvana(isSylvana) { } - - 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 (creature->AI()) - creature->AI()->DoAction(ACTION_START_INTRO); - creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - break; - case GOSSIP_ACTION_INFO_DEF+2: - player->CLOSE_GOSSIP_MENU(); - if (creature->AI()) - creature->AI()->DoAction(ACTION_SKIP_INTRO); - creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - break; - } + public: + npc_jaina_or_sylvanas_hor() : CreatureScript("npc_jaina_or_sylvanas_hor") { } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - QuestStatus status = player->GetQuestStatus(m_isSylvana ? QUEST_DELIVRANCE_FROM_THE_PIT_H2 : QUEST_DELIVRANCE_FROM_THE_PIT_A2); - if (status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED) - player->ADD_GOSSIP_ITEM( 0, "Can you remove the sword?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - // once last quest is completed, she offers this shortcut of the starting event - status = player->GetQuestStatus(m_isSylvana ? QUEST_WRATH_OF_THE_LICH_KING_H2 : QUEST_WRATH_OF_THE_LICH_KING_A2); - if (status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED) - player->ADD_GOSSIP_ITEM( 0, "Dark Lady, I think I hear Arthas coming. Whatever you're going to do, do it quickly.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); - return true; - } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_jaina_or_sylvanas_horAI(creature); - } - - // AI of Part1: handle the intro till start of gauntlet event. + // AI of Part1 struct npc_jaina_or_sylvanas_horAI : public ScriptedAI { npc_jaina_or_sylvanas_horAI(Creature* creature) : ScriptedAI(creature) @@ -221,6 +191,24 @@ public: EventMap events; + void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + switch (action) + { + case 0: + player->CLOSE_GOSSIP_MENU(); + events.ScheduleEvent(EVENT_START_INTRO, 1000); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); + break; + case 1: + player->CLOSE_GOSSIP_MENU(); + events.ScheduleEvent(EVENT_SKIP_INTRO, 1000); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); + break; + } + } + void Reset() { events.Reset(); @@ -228,22 +216,9 @@ public: utherGUID = 0; lichkingGUID = 0; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); me->SetStandState(UNIT_STAND_STATE_STAND); - me->SetVisible(true); - } - - void DoAction(int32 actionId) - { - switch (actionId) - { - case ACTION_START_INTRO: - events.ScheduleEvent(EVENT_START_INTRO, 0); - break; - case ACTION_SKIP_INTRO: - events.ScheduleEvent(EVENT_SKIP_INTRO, 0); - break; - } + events.ScheduleEvent(EVENT_WALK_INTRO1, 3000); } void UpdateAI(uint32 diff) @@ -251,6 +226,26 @@ public: events.Update(diff); switch (events.ExecuteEvent()) { + case EVENT_WALK_INTRO1: + me->GetMotionMaster()->MovePoint(0, IntroPos); + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + { + Talk(SAY_JAINA_INTRO_1); + events.ScheduleEvent(EVENT_WALK_INTRO2, 7000); + } + else + { + Talk(SAY_SYLVANAS_INTRO_1); + events.ScheduleEvent(EVENT_WALK_INTRO2, 9000); + } + break; + case EVENT_WALK_INTRO2: + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + Talk(SAY_JAINA_INTRO_2); + else + Talk(SAY_SYLVANAS_INTRO_2); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); + break; case EVENT_START_INTRO: me->GetMotionMaster()->MovePoint(0, MoveThronePos); // Begining of intro is differents between fActions as the speech sequence and timers are differents. @@ -259,27 +254,25 @@ public: else events.ScheduleEvent(EVENT_INTRO_H2_1, 0); break; - - // A2 Intro Events + // A2 Intro Events case EVENT_INTRO_A2_1: Talk(SAY_JAINA_INTRO_3); - events.ScheduleEvent(EVENT_INTRO_A2_2, 5000); + events.ScheduleEvent(EVENT_INTRO_A2_2, 7000); break; case EVENT_INTRO_A2_2: Talk(SAY_JAINA_INTRO_4); events.ScheduleEvent(EVENT_INTRO_A2_3, 10000); break; case EVENT_INTRO_A2_3: - /// @todo she's doing some kind of spell casting emote + me->CastSpell(me, SPELL_CAST_VISUAL, false); + me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); instance->HandleGameObject(instance->GetData64(DATA_FROSTMOURNE), true); events.ScheduleEvent(EVENT_INTRO_A2_4, 10000); break; case EVENT_INTRO_A2_4: - // spawn UTHER during speach 2 if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) { uther->GetMotionMaster()->MoveIdle(); - uther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas utherGUID = uther->GetGUID(); } events.ScheduleEvent(EVENT_INTRO_A2_5, 2000); @@ -291,57 +284,57 @@ public: break; case EVENT_INTRO_A2_6: Talk(SAY_JAINA_INTRO_5); - events.ScheduleEvent(EVENT_INTRO_A2_7, 6000); + events.ScheduleEvent(EVENT_INTRO_A2_7, 7000); break; case EVENT_INTRO_A2_7: if (Creature* uther = me->GetCreature(*me, utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_2); - events.ScheduleEvent(EVENT_INTRO_A2_8, 6500); + events.ScheduleEvent(EVENT_INTRO_A2_8, 7000); break; case EVENT_INTRO_A2_8: Talk(SAY_JAINA_INTRO_6); - events.ScheduleEvent(EVENT_INTRO_A2_9, 2000); + events.ScheduleEvent(EVENT_INTRO_A2_9, 1200); break; case EVENT_INTRO_A2_9: if (Creature* uther = me->GetCreature(*me, utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_3); - events.ScheduleEvent(EVENT_INTRO_A2_10, 9000); + events.ScheduleEvent(EVENT_INTRO_A2_10, 11000); break; case EVENT_INTRO_A2_10: Talk(SAY_JAINA_INTRO_7); - events.ScheduleEvent(EVENT_INTRO_A2_11, 5000); + events.ScheduleEvent(EVENT_INTRO_A2_11, 6000); break; case EVENT_INTRO_A2_11: if (Creature* uther = me->GetCreature(*me, utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_4); - events.ScheduleEvent(EVENT_INTRO_A2_12, 11000); + events.ScheduleEvent(EVENT_INTRO_A2_12, 12000); break; case EVENT_INTRO_A2_12: Talk(SAY_JAINA_INTRO_8); - events.ScheduleEvent(EVENT_INTRO_A2_13, 4000); + events.ScheduleEvent(EVENT_INTRO_A2_13, 6000); break; case EVENT_INTRO_A2_13: if (Creature* uther = me->GetCreature(*me, utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_5); - events.ScheduleEvent(EVENT_INTRO_A2_14, 12500); + events.ScheduleEvent(EVENT_INTRO_A2_14, 13000); break; case EVENT_INTRO_A2_14: Talk(SAY_JAINA_INTRO_9); - events.ScheduleEvent(EVENT_INTRO_A2_15, 10000); + events.ScheduleEvent(EVENT_INTRO_A2_15, 12000); break; case EVENT_INTRO_A2_15: if (Creature* uther = me->GetCreature(*me, utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_6); - events.ScheduleEvent(EVENT_INTRO_A2_16, 22000); + events.ScheduleEvent(EVENT_INTRO_A2_16, 25000); break; case EVENT_INTRO_A2_16: if (Creature* uther = me->GetCreature(*me, utherGUID)) uther->AI()->Talk(SAY_UTHER_INTRO_A2_7); - events.ScheduleEvent(EVENT_INTRO_A2_17, 4000); + events.ScheduleEvent(EVENT_INTRO_A2_17, 6000); break; case EVENT_INTRO_A2_17: Talk(SAY_JAINA_INTRO_10); - events.ScheduleEvent(EVENT_INTRO_A2_18, 2000); + events.ScheduleEvent(EVENT_INTRO_A2_18, 5000); break; case EVENT_INTRO_A2_18: if (Creature* uther = me->GetCreature(*me, utherGUID)) @@ -349,14 +342,13 @@ public: uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); uther->AI()->Talk(SAY_UTHER_INTRO_A2_8); } - events.ScheduleEvent(EVENT_INTRO_A2_19, 11000); + events.ScheduleEvent(EVENT_INTRO_A2_19, 12000); break; case EVENT_INTRO_A2_19: Talk(SAY_JAINA_INTRO_11); - events.ScheduleEvent(EVENT_INTRO_LK_1, 2000); + events.ScheduleEvent(EVENT_INTRO_LK_1, 3000); break; - - // H2 Intro Events + // H2 Intro Events case EVENT_INTRO_H2_1: Talk(SAY_SYLVANAS_INTRO_1); events.ScheduleEvent(EVENT_INTRO_H2_2, 8000); @@ -367,7 +359,9 @@ public: break; case EVENT_INTRO_H2_3: Talk(SAY_SYLVANAS_INTRO_3); - /// @todo she's doing some kind of spell casting emote + me->CastSpell(me, SPELL_CAST_VISUAL, false); + me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); + instance->HandleGameObject(instance->GetData64(DATA_FROSTMOURNE), true); events.ScheduleEvent(EVENT_INTRO_H2_4, 6000); break; case EVENT_INTRO_H2_4: @@ -375,7 +369,6 @@ public: if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) { uther->GetMotionMaster()->MoveIdle(); - uther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas utherGUID = uther->GetGUID(); } events.ScheduleEvent(EVENT_INTRO_H2_5, 2000); @@ -433,126 +426,159 @@ public: Talk(SAY_SYLVANAS_INTRO_8); events.ScheduleEvent(EVENT_INTRO_LK_1, 2000); break; - - // Remaining Intro Events common for both faction + // Remaining Intro Events common for both faction case EVENT_INTRO_LK_1: // Spawn LK in front of door, and make him move to the sword. - if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_EVENT, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) + if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) { + lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos); - lichking->SetReactState(REACT_PASSIVE); + //lichking->SetReactState(REACT_PASSIVE); lichkingGUID = lichking->GetGUID(); + events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); + events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); } - if (Creature* uther = me->GetCreature(*me, utherGUID)) { + uther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) uther->AI()->Talk(SAY_UTHER_INTRO_A2_9); else uther->AI()->Talk(SAY_UTHER_INTRO_H2_7); } - - events.ScheduleEvent(EVENT_INTRO_LK_2, 11000); + events.ScheduleEvent(EVENT_INTRO_LK_2, 10000); break; - case EVENT_INTRO_LK_2: - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) - lichking->AI()->Talk(SAY_LK_INTRO_1); - events.ScheduleEvent(EVENT_INTRO_LK_3, 2000); - break; - + if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + lichking->AI()->Talk(SAY_LK_INTRO_1); + events.ScheduleEvent(EVENT_INTRO_LK_3, 1000); + break; case EVENT_INTRO_LK_3: - // The Lich King banishes Uther to the abyss. - if (Creature* uther = me->GetCreature(*me, utherGUID)) - { - uther->DisappearAndDie(); - utherGUID = 0; - } - - // He steps forward and removes the runeblade from the heap of skulls. - - events.ScheduleEvent(EVENT_INTRO_LK_4, 4000); - break; - + // The Lich King banishes Uther to the abyss. + if (Creature* uther = me->GetCreature(*me, utherGUID)) + { + uther->CastSpell(uther, SPELL_UTHER_DESPAWN, true); + uther->DespawnOrUnsummon(5000); + utherGUID = 0; + } + events.ScheduleEvent(EVENT_INTRO_LK_4, 9000); + break; case EVENT_INTRO_LK_4: - if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) - lichking->AI()->Talk(SAY_LK_INTRO_2); - events.ScheduleEvent(EVENT_INTRO_LK_5, 10000); + // He steps forward and removes the runeblade from the heap of skulls. + if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + { + if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTMOURNE))) + frostmourne->SetPhaseMask(2, true); + lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true); + lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true); + } + events.ScheduleEvent(EVENT_INTRO_LK_5, 8000); break; - case EVENT_INTRO_LK_5: + if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + lichking->AI()->Talk(SAY_LK_INTRO_2); + events.ScheduleEvent(EVENT_INTRO_LK_6, 8000); + break; + case EVENT_INTRO_LK_6: // summon Falric and Marwyn. then go back to the door - if (Creature* pFalric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC))) - pFalric->SetVisible(true); - if (Creature* pMarwyn = me->GetCreature(*me, instance->GetData64(DATA_MARWYN))) - pMarwyn->SetVisible(true); - + if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT))) + { + falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); + falric->SetVisible(true); + } + if (Creature* marwyn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MARWYN_EVENT))) + { + marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); + marwyn->SetVisible(true); + } if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) { - lichking->GetMotionMaster()->MovePoint(0, LichKingSpawnPos); lichking->AI()->Talk(SAY_LK_INTRO_3); + lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); + lichking->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); } - - events.ScheduleEvent(EVENT_INTRO_LK_6, 8000); - break; - - case EVENT_INTRO_LK_6: - if (Creature* falric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC))) - falric->AI()->Talk(SAY_FALRIC_INTRO_1); - - events.ScheduleEvent(EVENT_INTRO_LK_7, 2000); + events.ScheduleEvent(EVENT_INTRO_LK_7, 10000); + events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 5000); break; - case EVENT_INTRO_LK_7: - if (Creature* marwyn = me->GetCreature(*me, instance->GetData64(DATA_MARWYN))) + if (Creature* marwyn = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MARWYN_EVENT))) marwyn->AI()->Talk(SAY_MARWYN_INTRO_1); - - events.ScheduleEvent(EVENT_INTRO_LK_8, 2000); + events.ScheduleEvent(EVENT_INTRO_LK_8, 1000); break; - case EVENT_INTRO_LK_8: - if (Creature* falric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC))) - falric->AI()->Talk(SAY_FALRIC_INTRO_2); - + if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT))) + falric->AI()->Talk(SAY_FALRIC_INTRO_1); events.ScheduleEvent(EVENT_INTRO_LK_9, 5000); break; - case EVENT_INTRO_LK_9: + if (Creature* falric = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_FALRIC_EVENT))) + falric->AI()->Talk(SAY_FALRIC_INTRO_2); + events.ScheduleEvent(EVENT_INTRO_LK_10, 7000); + break; + case EVENT_INTRO_LK_10: if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) Talk(SAY_JAINA_INTRO_END); else Talk(SAY_SYLVANAS_INTRO_END); - - me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos); + me->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); /// @todo Loralen/Koreln shall run also - events.ScheduleEvent(EVENT_INTRO_END, 10000); + events.ScheduleEvent(EVENT_INTRO_LK_11, 5000); + break; + case EVENT_INTRO_LK_11: + if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + { + if (instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + lichking->AI()->Talk(SAY_LK_JAINA_INTRO_END); + else + lichking->AI()->Talk(SAY_LK_SYLVANAS_INTRO_END); + } + events.ScheduleEvent(EVENT_INTRO_END, 5000); break; - case EVENT_INTRO_END: if (instance) - instance->SetData(DATA_WAVE_COUNT, SPECIAL); // start first wave - + { + instance->SetData(DATA_INTRO_EVENT, DONE); + instance->ProcessEvent(0, EVENT_SPAWN_WAVES); + } // Loralen or Koreln disappearAndDie() - me->DisappearAndDie(); + if (Creature* lichking = me->GetCreature(*me, lichkingGUID)) + { + lichking->DespawnOrUnsummon(5000); + lichkingGUID = 0; + } + me->DespawnOrUnsummon(10000); + events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 7000); break; - case EVENT_SKIP_INTRO: - /// @todo implement - - if (Creature* pFalric = me->GetCreature(*me, instance->GetData64(DATA_FALRIC))) - pFalric->SetVisible(true); - if (Creature* pMarwyn = me->GetCreature(*me, instance->GetData64(DATA_MARWYN))) - pMarwyn->SetVisible(true); - - me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos); + me->GetMotionMaster()->MovePoint(0, MoveThronePos); /// @todo Loralen/Koreln shall run also - - events.ScheduleEvent(EVENT_INTRO_END, 15000); + if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) + { + lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING); + lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos); + lichking->SetReactState(REACT_PASSIVE); + lichkingGUID = lichking->GetGUID(); + events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); + events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); + } + events.ScheduleEvent(EVENT_INTRO_LK_4, 15000); + break; + case EVENT_OPEN_FROSTWORN_DOOR: + if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTWORN_DOOR))) + instance->HandleGameObject(0 ,true, gate); + break; + case EVENT_CLOSE_FROSTWORN_DOOR: + if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FROSTWORN_DOOR))) + instance->HandleGameObject(0 ,false, gate); break; } } }; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_jaina_or_sylvanas_horAI(creature); + } }; enum TrashSpells @@ -626,27 +652,56 @@ enum TrashEvents EVENT_ICE_SHOT, }; -class npc_ghostly_priest : public CreatureScript +struct npc_gauntlet_trash : public ScriptedAI { -public: - npc_ghostly_priest() : CreatureScript("npc_ghostly_priest") { } + npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), + instance(creature->GetInstanceScript()) + { + } - CreatureAI* GetAI(Creature* creature) const + void Reset() { - return new npc_ghostly_priestAI(creature); + me->CastSpell(me, SPELL_WELL_OF_SOULS, true); + events.Reset(); } - struct npc_ghostly_priestAI: public ScriptedAI + void EnterEvadeMode() { - npc_ghostly_priestAI(Creature* creature) : ScriptedAI(creature) - { - } + if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) + instance->SetData(DATA_WAVE_COUNT, NOT_STARTED); + } - EventMap events; + void SetData(uint32 type, uint32 value) + { + if (type) + return; - void Reset() + InternalWaveId = value; + } + + uint32 GetData(uint32 type) const + { + if (type) + return 0; + + return InternalWaveId; + } + +protected: + EventMap events; + InstanceScript* instance; + uint32 InternalWaveId; +}; + +class npc_ghostly_priest : public CreatureScript +{ +public: + npc_ghostly_priest() : CreatureScript("npc_ghostly_priest") { } + + struct npc_ghostly_priestAI : public npc_gauntlet_trash + { + npc_ghostly_priestAI(Creature* creature) : npc_gauntlet_trash(creature) { - events.Reset(); } void EnterCombat(Unit* /*who*/) @@ -667,45 +722,46 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { - switch (eventId) - { - case EVENT_SHADOW_WORD_PAIN: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_SHADOW_WORD_PAIN); - events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); - return; - case EVENT_CIRCLE_OF_DESTRUCTION: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION); - events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); - return; - case EVENT_COWER_IN_FEAR: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_COWER_IN_FEAR); - events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); - return; - case EVENT_DARK_MENDING: - // find an ally with missing HP - if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000))) - { - DoCast(target, SPELL_DARK_MENDING); - events.ScheduleEvent(EVENT_DARK_MENDING, 20000); - } - else - { - // no friendly unit with missing hp. re-check in just 5 sec. - events.ScheduleEvent(EVENT_DARK_MENDING, 5000); - } - return; - } + case EVENT_SHADOW_WORD_PAIN: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_SHADOW_WORD_PAIN); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); + break; + case EVENT_CIRCLE_OF_DESTRUCTION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION); + events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); + break; + case EVENT_COWER_IN_FEAR: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_COWER_IN_FEAR); + events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); + break; + case EVENT_DARK_MENDING: + // find an ally with missing HP + if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000))) + { + DoCast(target, SPELL_DARK_MENDING); + events.ScheduleEvent(EVENT_DARK_MENDING, 20000); + } + else + { + // no friendly unit with missing hp. re-check in just 5 sec. + events.ScheduleEvent(EVENT_DARK_MENDING, 5000); + } + break; } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_ghostly_priestAI(creature); + } }; class npc_phantom_mage : public CreatureScript @@ -713,22 +769,10 @@ class npc_phantom_mage : public CreatureScript public: npc_phantom_mage() : CreatureScript("npc_phantom_mage") { } - CreatureAI* GetAI(Creature* creature) const - { - return new npc_phantom_mageAI(creature); - } - - struct npc_phantom_mageAI: public ScriptedAI + struct npc_phantom_mageAI : public npc_gauntlet_trash { - npc_phantom_mageAI(Creature* creature) : ScriptedAI(creature) - { - } - - EventMap events; - - void Reset() + npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature) { - events.Reset(); } void EnterCombat(Unit* /*who*/) @@ -750,39 +794,40 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { - switch (eventId) - { - case EVENT_FIREBALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_FIREBALL); - events.ScheduleEvent(EVENT_FIREBALL, 15000); - return; - case EVENT_FLAMESTRIKE: - DoCast(SPELL_FLAMESTRIKE); - events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000); - return; - case EVENT_FROSTBOLT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_FROSTBOLT); - events.ScheduleEvent(EVENT_FROSTBOLT, 15000); - return; - case EVENT_CHAINS_OF_ICE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_CHAINS_OF_ICE); - events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000); - return; - case EVENT_HALLUCINATION: - DoCast(SPELL_HALLUCINATION); - return; - } + case EVENT_FIREBALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_FIREBALL); + events.ScheduleEvent(EVENT_FIREBALL, 15000); + break; + case EVENT_FLAMESTRIKE: + DoCast(SPELL_FLAMESTRIKE); + events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000); + break; + case EVENT_FROSTBOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_FROSTBOLT); + events.ScheduleEvent(EVENT_FROSTBOLT, 15000); + break; + case EVENT_CHAINS_OF_ICE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_CHAINS_OF_ICE); + events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000); + break; + case EVENT_HALLUCINATION: + DoCast(SPELL_HALLUCINATION); + break; } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_phantom_mageAI(creature); + } }; class npc_phantom_hallucination : public CreatureScript @@ -790,16 +835,9 @@ class npc_phantom_hallucination : public CreatureScript public: npc_phantom_hallucination() : CreatureScript("npc_phantom_hallucination") { } - CreatureAI* GetAI(Creature* creature) const - { - return new npc_phantom_hallucinationAI(creature); - } - struct npc_phantom_hallucinationAI : public npc_phantom_mage::npc_phantom_mageAI { - npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature) - { - } + npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature) {} void JustDied(Unit* /*killer*/) { @@ -807,6 +845,10 @@ public: } }; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_phantom_hallucinationAI(creature); + } }; class npc_shadowy_mercenary : public CreatureScript @@ -814,22 +856,10 @@ class npc_shadowy_mercenary : public CreatureScript public: npc_shadowy_mercenary() : CreatureScript("npc_shadowy_mercenary") { } - CreatureAI* GetAI(Creature* creature) const + struct npc_shadowy_mercenaryAI : public npc_gauntlet_trash { - return new npc_shadowy_mercenaryAI(creature); - } - - struct npc_shadowy_mercenaryAI: public ScriptedAI - { - npc_shadowy_mercenaryAI(Creature* creature) : ScriptedAI(creature) - { - } - - EventMap events; - - void Reset() + npc_shadowy_mercenaryAI(Creature* creature) : npc_gauntlet_trash(creature) { - events.Reset(); } void EnterCombat(Unit* /*who*/) @@ -850,34 +880,35 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { - switch (eventId) - { - case EVENT_SHADOW_STEP: - DoCast(SPELL_SHADOW_STEP); - events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); - return; - case EVENT_DEADLY_POISON: - DoCast(me->getVictim(), SPELL_DEADLY_POISON); - events.ScheduleEvent(EVENT_DEADLY_POISON, 10000); - return; - case EVENT_ENVENOMED_DAGGER_THROW: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_ENVENOMED_DAGGER_THROW); - events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); - return; - case EVENT_KIDNEY_SHOT: - DoCast(me->getVictim(), SPELL_KIDNEY_SHOT); - events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000); - return; - } + case EVENT_SHADOW_STEP: + DoCast(SPELL_SHADOW_STEP); + events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); + break; + case EVENT_DEADLY_POISON: + DoCast(me->getVictim(), SPELL_DEADLY_POISON); + events.ScheduleEvent(EVENT_DEADLY_POISON, 10000); + break; + case EVENT_ENVENOMED_DAGGER_THROW: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_ENVENOMED_DAGGER_THROW); + events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); + break; + case EVENT_KIDNEY_SHOT: + DoCast(me->getVictim(), SPELL_KIDNEY_SHOT); + events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000); + break; } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_shadowy_mercenaryAI(creature); + } }; class npc_spectral_footman : public CreatureScript @@ -885,29 +916,176 @@ class npc_spectral_footman : public CreatureScript public: npc_spectral_footman() : CreatureScript("npc_spectral_footman") { } + struct npc_spectral_footmanAI : public npc_gauntlet_trash + { + npc_spectral_footmanAI(Creature* creature) : npc_gauntlet_trash(creature) + { + } + + void EnterCombat(Unit* /*who*/) + { + events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers + events.ScheduleEvent(EVENT_SHIELD_BASH, 10000); + events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + } + + void UpdateAI(uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SPECTRAL_STRIKE: + DoCast(me->getVictim(), SPELL_SPECTRAL_STRIKE); + events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); + break; + case EVENT_SHIELD_BASH: + DoCast(me->getVictim(), SPELL_SHIELD_BASH); + events.ScheduleEvent(EVENT_SHIELD_BASH, 5000); + break; + case EVENT_TORTURED_ENRAGE: + DoCast(SPELL_TORTURED_ENRAGE); + events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + break; + } + + DoMeleeAttackIfReady(); + } + }; + CreatureAI* GetAI(Creature* creature) const { return new npc_spectral_footmanAI(creature); } +}; + +class npc_tortured_rifleman : public CreatureScript +{ +public: + npc_tortured_rifleman() : CreatureScript("npc_tortured_rifleman") { } - struct npc_spectral_footmanAI: public ScriptedAI + struct npc_tortured_riflemanAI : public npc_gauntlet_trash { - npc_spectral_footmanAI(Creature* creature) : ScriptedAI(creature) + npc_tortured_riflemanAI(Creature* creature) : npc_gauntlet_trash(creature) { } + void EnterCombat(Unit* /*who*/) + { + events.ScheduleEvent(EVENT_SHOOT, 2000); /// @todo adjust timers + events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); + events.ScheduleEvent(EVENT_FROST_TRAP, 1000); + events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + } + + void UpdateAI(uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_SHOOT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_SHOOT); + events.ScheduleEvent(EVENT_SHOOT, 2000); + break; + case EVENT_CURSED_ARROW: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_CURSED_ARROW); + events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); + break; + case EVENT_FROST_TRAP: + DoCast(SPELL_FROST_TRAP); + events.ScheduleEvent(EVENT_FROST_TRAP, 30000); + break; + case EVENT_ICE_SHOT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_ICE_SHOT); + events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_tortured_riflemanAI(creature); + } +}; + + +enum GeneralEvents +{ + //General + EVENT_SHIELD = 0, + EVENT_SPIKE = 1, + EVENT_CLONE = 2, + + SAY_AGGRO = 0, + SAY_DEATH = 1, + + SPELL_SHIELD_THROWN = 69222, // 73076 on hc + SPELL_SPIKE = 69184, // 70399 on hc + SPELL_CLONE_NAME = 57507, + SPELL_CLONE_MODEL = 45204, + + // Reflection + EVENT_BALEFUL_STRIKE = 0, + + SPELL_BALEFUL_STRIKE = 69933, // 70400 on hc + SPELL_SPIRIT_BURST = 69900, // 73046 on hc +}; + +class npc_frostworn_general : public CreatureScript +{ +public: + npc_frostworn_general() : CreatureScript("npc_frostworn_general") { } + + struct npc_frostworn_generalAI : public ScriptedAI + { + npc_frostworn_generalAI(Creature* creature) : ScriptedAI(creature) + { + instance = me->GetInstanceScript(); + Reset(); + } + + InstanceScript* instance; + EventMap events; void Reset() { events.Reset(); + instance->SetData(DATA_FROSWORN_EVENT, NOT_STARTED); } - void EnterCombat(Unit* /*who*/) + void JustDied(Unit* /*killer*/) { - events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers - events.ScheduleEvent(EVENT_SHIELD_BASH, 10000); - events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + Talk(SAY_DEATH); + instance->SetData(DATA_FROSWORN_EVENT, DONE); + } + + void EnterCombat(Unit* /*victim*/) + { + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_SHIELD, 5000); + events.ScheduleEvent(EVENT_SPIKE, 14000); + events.ScheduleEvent(EVENT_CLONE, 22000); + instance->SetData(DATA_FROSWORN_EVENT, IN_PROGRESS); } void UpdateAI(uint32 diff) @@ -920,45 +1098,61 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { - switch (eventId) - { - case EVENT_SPECTRAL_STRIKE: - DoCast(me->getVictim(), SPELL_SPECTRAL_STRIKE); - events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); - return; - case EVENT_SHIELD_BASH: - DoCast(me->getVictim(), SPELL_SHIELD_BASH); - events.ScheduleEvent(EVENT_SHIELD_BASH, 5000); - return; - case EVENT_TORTURED_ENRAGE: - DoCast(SPELL_TORTURED_ENRAGE); - events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); - return; - } + case EVENT_SHIELD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SHIELD_THROWN); + events.ScheduleEvent(EVENT_SHIELD, urand(8000, 12000)); + break; + case EVENT_SPIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_SPIKE); + events.ScheduleEvent(EVENT_SPIKE, urand(15000, 20000)); + break; + case EVENT_CLONE: + SummonClones(); + events.ScheduleEvent(EVENT_CLONE, 60000); + break; } DoMeleeAttackIfReady(); } - }; -}; + void SummonClones() + { + std::list<Unit *> playerList; + SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true); + for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) + { + Unit* temp = (*itr); + Creature* reflection = me->SummonCreature(NPC_REFLECTION, temp->GetPositionX(), temp->GetPositionY(), temp->GetPositionZ(), temp->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000); + reflection->SetName(temp->GetName()); + temp->CastSpell(reflection, SPELL_CLONE_NAME, true); + temp->CastSpell(reflection, SPELL_CLONE_MODEL, true); + reflection->setFaction(me->getFaction()); + reflection->AI()->AttackStart(temp); + } -class npc_tortured_rifleman : public CreatureScript -{ -public: - npc_tortured_rifleman() : CreatureScript("npc_tortured_rifleman") { } + } + }; CreatureAI* GetAI(Creature* creature) const { - return new npc_tortured_riflemanAI(creature); + return new npc_frostworn_generalAI(creature); } +}; + +class npc_spiritual_reflection : public CreatureScript +{ +public: + npc_spiritual_reflection() : CreatureScript("npc_spiritual_reflection") { } - struct npc_tortured_riflemanAI : public ScriptedAI + struct npc_spiritual_reflectionAI : public ScriptedAI { - npc_tortured_riflemanAI(Creature* creature) : ScriptedAI(creature) + npc_spiritual_reflectionAI(Creature *creature) : ScriptedAI(creature) { + Reset(); } EventMap events; @@ -968,12 +1162,14 @@ public: events.Reset(); } - void EnterCombat(Unit* /*who*/) + void EnterCombat(Unit* /*victim*/) { - events.ScheduleEvent(EVENT_SHOOT, 2000); /// @todo adjust timers - events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); - events.ScheduleEvent(EVENT_FROST_TRAP, 1000); - events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + events.ScheduleEvent(EVENT_BALEFUL_STRIKE, 3000); + } + + void JustDied(Unit* killer) + { + DoCast(killer, SPELL_SPIRIT_BURST); } void UpdateAI(uint32 diff) @@ -986,46 +1182,90 @@ public: if (me->HasUnitState(UNIT_STATE_CASTING)) return; - while (uint32 eventId = events.ExecuteEvent()) + switch (events.ExecuteEvent()) { - switch (eventId) - { - case EVENT_SHOOT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_SHOOT); - events.ScheduleEvent(EVENT_SHOOT, 2000); - return; - case EVENT_CURSED_ARROW: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_CURSED_ARROW); - events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); - return; - case EVENT_FROST_TRAP: - DoCast(SPELL_FROST_TRAP); - events.ScheduleEvent(EVENT_FROST_TRAP, 30000); - return; - case EVENT_ICE_SHOT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_ICE_SHOT); - events.ScheduleEvent(EVENT_ICE_SHOT, 15000); - return; - } + case EVENT_BALEFUL_STRIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_BALEFUL_STRIKE); + events.ScheduleEvent(EVENT_BALEFUL_STRIKE, urand(3000, 8000)); } DoMeleeAttackIfReady(); } }; + CreatureAI* GetAI(Creature* creature) const + { + return new npc_spiritual_reflectionAI(creature); + } +}; + +class at_hor_intro_start : public AreaTriggerScript +{ +public: + at_hor_intro_start() : AreaTriggerScript("at_hor_intro_start") {} + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) + { + InstanceScript* instance = player->GetInstanceScript(); + + if (player->isGameMaster()) + return true; + + if (instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED) + { + instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS); + } + + return true; + } +}; + +class at_hor_waves_restarter : public AreaTriggerScript +{ +public: + at_hor_waves_restarter() : AreaTriggerScript("at_hor_waves_restarter") {} + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) + { + InstanceScript* instance = player->GetInstanceScript(); + + if (player->isGameMaster()) + return true; + + if (instance->GetData(DATA_WAVE_COUNT)) + return true; + + if (instance->GetData(DATA_INTRO_EVENT) == DONE && instance->GetBossState(DATA_MARWYN_EVENT) != DONE) + { + instance->ProcessEvent(0, EVENT_SPAWN_WAVES); + + if (Creature* falric = player->GetCreature(*player, instance->GetData64(DATA_FALRIC_EVENT))) + { + falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); + falric->SetVisible(true); + } + if (Creature* marwyn = player->GetCreature(*player, instance->GetData64(DATA_MARWYN_EVENT))) + { + marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); + marwyn->SetVisible(true); + } + } + return true; + } }; void AddSC_halls_of_reflection() { - new npc_jaina_or_sylvanas_hor(true, "npc_sylvanas_hor_part1"); - new npc_jaina_or_sylvanas_hor(false, "npc_jaina_hor_part1"); + new npc_jaina_or_sylvanas_hor(); new npc_ghostly_priest(); new npc_phantom_mage(); new npc_phantom_hallucination(); new npc_shadowy_mercenary(); new npc_spectral_footman(); new npc_tortured_rifleman(); + new at_hor_intro_start(); + new at_hor_waves_restarter(); + new npc_frostworn_general(); + new npc_spiritual_reflection(); } 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 2cab1cca214..4787a6b9fdc 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -18,54 +18,83 @@ #ifndef DEF_HALLS_OF_REFLECTION_H #define DEF_HALLS_OF_REFLECTION_H -enum Data -{ - DATA_FALRIC_EVENT, - DATA_MARWYN_EVENT, - DATA_LICHKING_EVENT, - DATA_WAVE_COUNT, - DATA_TEAM_IN_INSTANCE, -}; +#define HoRScriptName "instance_halls_of_reflection" +#define MAX_ENCOUNTER 3 -enum Data64 +/* Halls of Reflection encounters: +0- Falric +1- Marwyn +2- The Lich King +*/ + +enum Data { - DATA_FALRIC, - DATA_MARWYN, - DATA_LICHKING, - DATA_FROSTMOURNE, + DATA_FALRIC_EVENT = 0, + DATA_MARWYN_EVENT = 1, + DATA_LICHKING_EVENT = 2, + DATA_INTRO_EVENT = 3, + DATA_FROSWORN_EVENT = 4, + + DATA_WAVE_COUNT = 5, + DATA_TEAM_IN_INSTANCE = 6, + DATA_FROSTMOURNE = 7, + DATA_FROSTWORN_DOOR = 8, }; enum Creatures { - NPC_FALRIC = 38112, - NPC_MARWYN = 38113, - NPC_LICH_KING_EVENT = 37226, - NPC_LICH_KING_BOSS = 36954, - - NPC_UTHER = 37225, NPC_JAINA_PART1 = 37221, - NPC_JAINA_PART2 = 36955, NPC_SYLVANAS_PART1 = 37223, - NPC_SYLVANAS_PART2 = 37554, + NPC_UTHER = 37225, + NPC_LICH_KING_PART1 = 37226, + NPC_LORALEN = 37779, + NPC_KORELN = 37582, + NPC_FALRIC = 38112, + NPC_MARWYN = 38113, NPC_WAVE_MERCENARY = 38177, NPC_WAVE_FOOTMAN = 38173, NPC_WAVE_RIFLEMAN = 38176, NPC_WAVE_PRIEST = 38175, NPC_WAVE_MAGE = 38172, + + NPC_FROSTWORN_GENERAL = 36723, + NPC_REFLECTION = 37068, // 37107 for tank only? + + NPC_JAINA_PART2 = 36955, + NPC_SYLVANAS_PART2 = 37554, + NPC_LICH_KING_PART2 = 36954, + NPC_BARTLETT = 37182, // High Captain Justin Bartlett + NPC_KORM = 37833, // Sky-Reaver Korm Blackscar + NPC_ICE_WALL = 37014, // Ice Wall Target }; enum GameObjects { GO_FROSTMOURNE = 202302, - GO_FROSTMOURNE_ALTAR = 202236, - GO_FRONT_DOOR = 201976, - GO_ARTHAS_DOOR = 197341, + GO_ENTRANCE_DOOR = 201976, + GO_FROSTWORN_DOOR = 197341, + GO_ARTHAS_DOOR = 197342, + //GO_ESCAPE_DOOR = 197343, // always open ? + + GO_ICE_WALL = 201385, + GO_CAVE = 201596, + + GO_STAIRS_SKYBREAKER = 201709, + GO_SKYBREAKER = 201598, + GO_STAIRS_ORGRIM_HAMMER = 202211, + GO_ORGRIM_HAMMER = 201599, + GO_PORTAL = 202079, + + GO_CAPTAIN_CHEST_1 = 202212, //3145 + GO_CAPTAIN_CHEST_2 = 201710, //30357 + GO_CAPTAIN_CHEST_3 = 202337, //3246 + GO_CAPTAIN_CHEST_4 = 202336, //3333 }; enum HorWorldStates { - WORLD_STATE_HOR = 4884, + WORLD_STATE_HOR_WAVES_ENABLED = 4884, WORLD_STATE_HOR_WAVE_COUNT = 4882, }; @@ -75,6 +104,21 @@ enum Actions ACTION_ENTER_COMBAT, }; +enum TrashGeneralSpells +{ + // General spells + SPELL_WELL_OF_SOULS = 72630, // cast when spawn(become visible) + SPELL_SPIRIT_ACTIVATE = 72130, // cast when unit activates +}; + +enum InstanceEvents +{ + EVENT_SPAWN_WAVES = 1, + EVENT_NEXT_WAVE = 2, + EVENT_DO_WIPE = 3, + EVENT_ADD_WAVE = 4, +}; + // Base class for FALRIC and MARWYN // handled the summonList and the notification events to/from the InstanceScript struct boss_horAI : ScriptedAI @@ -92,14 +136,10 @@ struct boss_horAI : ScriptedAI { events.Reset(); me->SetVisible(false); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_PASSIVE); - } - - void DamageTaken(Unit* /*who*/, uint32 &uiDamage) - { - if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - uiDamage = 0; + if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) + instance->ProcessEvent(0, EVENT_DO_WIPE); } void DoAction(int32 actionID) @@ -107,11 +147,7 @@ struct boss_horAI : ScriptedAI switch (actionID) { case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat. - // Just in case. Should have been done by InstanceScript - me->SetVisible(true); - - // Reset flags - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_AGGRESSIVE); if (Unit* unit = me->SelectNearestTarget()) @@ -125,32 +161,6 @@ struct boss_horAI : ScriptedAI void JustSummoned(Creature* summoned) { summons.Summon(summoned); - - if (Unit* target = summoned->SelectNearestTarget()) - { - if (summoned->AI()) - summoned->AI()->AttackStart(target); - else - { - summoned->GetMotionMaster()->MoveChase(target); - summoned->Attack(target, true); - } - } - - if (summoned->AI()) - summoned->AI()->DoZoneInCombat(); - } - - void SummonedCreatureDespawn(Creature* summoned) - { - summons.Despawn(summoned); - if (summons.empty()) - { - if (summoned->isAlive()) - instance->SetData(DATA_WAVE_COUNT, NOT_STARTED); - else - instance->SetData(DATA_WAVE_COUNT, SPECIAL); - } } }; 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 dde3f7acc67..bff18b508d5 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 @@ -18,85 +18,50 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "InstanceScript.h" -#include "halls_of_reflection.h" #include "Player.h" +#include "WorldPacket.h" +#include "halls_of_reflection.h" -#define MAX_ENCOUNTER 3 - -/* Halls of Reflection encounters: -0- Falric -1- Marwyn -2- The Lich King -*/ - -enum eEnum -{ - ENCOUNTER_WAVE_MERCENARY = 6, - ENCOUNTER_WAVE_FOOTMAN = 10, - ENCOUNTER_WAVE_RIFLEMAN = 6, - ENCOUNTER_WAVE_PRIEST = 6, - ENCOUNTER_WAVE_MAGE = 6, -}; - -enum Events -{ - EVENT_NONE, - EVENT_NEXT_WAVE, - EVENT_START_LICH_KING, -}; - -static Position PriestSpawnPos[ENCOUNTER_WAVE_PRIEST] = -{ - {5277.74f, 2016.88f, 707.778f, 5.96903f}, - {5295.88f, 2040.34f, 707.778f, 5.07891f}, - {5320.37f, 1980.13f, 707.778f, 2.00713f}, - {5280.51f, 1997.84f, 707.778f, 0.296706f}, - {5302.45f, 2042.22f, 707.778f, 4.90438f}, - {5306.57f, 1977.47f, 707.778f, 1.50098f}, -}; - -static Position MageSpawnPos[ENCOUNTER_WAVE_MAGE] = -{ - {5312.75f, 2037.12f, 707.778f, 4.59022f}, - {5309.58f, 2042.67f, 707.778f, 4.69494f}, - {5275.08f, 2008.72f, 707.778f, 6.21337f}, - {5279.65f, 2004.66f, 707.778f, 0.069813f}, - {5275.48f, 2001.14f, 707.778f, 0.174533f}, - {5316.7f, 2041.55f, 707.778f, 4.50295f}, -}; - -static Position MercenarySpawnPos[ENCOUNTER_WAVE_MERCENARY] = -{ - {5302.25f, 1972.41f, 707.778f, 1.37881f}, - {5311.03f, 1972.23f, 707.778f, 1.64061f}, - {5277.36f, 1993.23f, 707.778f, 0.401426f}, - {5318.7f, 2036.11f, 707.778f, 4.2237f}, - {5335.72f, 1996.86f, 707.778f, 2.74017f}, - {5299.43f, 1979.01f, 707.778f, 1.23918f}, -}; +Position const JainaSpawnPos = {5236.659f, 1929.894f, 707.7781f, 0.8726646f}; // Jaina Spawn Position +Position const SylvanasSpawnPos = {5236.667f, 1929.906f, 707.7781f, 0.8377581f}; // Sylvanas Spawn Position +Position const GeneralSpawnPos = {5415.538f, 2117.842f, 707.7781f, 3.944444f}; // Frostsworn General -static Position FootmenSpawnPos[ENCOUNTER_WAVE_FOOTMAN] = +Position const SpawnPos[] = { - {5306.06f, 2037, 707.778f, 4.81711f}, - {5344.15f, 2007.17f, 707.778f, 3.15905f}, - {5337.83f, 2010.06f, 707.778f, 3.22886f}, - {5343.29f, 1999.38f, 707.778f, 2.9147f}, - {5340.84f, 1992.46f, 707.778f, 2.75762f}, - {5325.07f, 1977.6f, 707.778f, 2.07694f}, - {5336.6f, 2017.28f, 707.778f, 3.47321f}, - {5313.82f, 1978.15f, 707.778f, 1.74533f}, - {5280.63f, 2012.16f, 707.778f, 6.05629f}, - {5322.96f, 2040.29f, 707.778f, 4.34587f}, -}; - -static Position RiflemanSpawnPos[ENCOUNTER_WAVE_RIFLEMAN] = -{ - {5343.47f, 2015.95f, 707.778f, 3.49066f}, - {5337.86f, 2003.4f, 707.778f, 2.98451f}, - {5319.16f, 1974, 707.778f, 1.91986f}, - {5299.25f, 2036, 707.778f, 5.02655f}, - {5295.64f, 1973.76f, 707.778f, 1.18682f}, - {5282.9f, 2019.6f, 707.778f, 5.88176f}, + {5309.577f, 2042.668f, 707.7781f, 4.694936f}, + {5295.885f, 2040.342f, 707.7781f, 5.078908f}, + {5340.836f, 1992.458f, 707.7781f, 2.757620f}, + {5325.072f, 1977.597f, 707.7781f, 2.076942f}, + {5277.365f, 1993.229f, 707.7781f, 0.401426f}, + {5275.479f, 2001.135f, 707.7781f, 0.174533f}, + {5302.448f, 2042.222f, 707.7781f, 4.904375f}, + {5343.293f, 1999.384f, 707.7781f, 2.914700f}, + {5295.635f, 1973.757f, 707.7781f, 1.186824f}, + {5311.031f, 1972.229f, 707.7781f, 1.640610f}, + {5275.076f, 2008.724f, 707.7781f, 6.213372f}, + {5316.701f, 2041.550f, 707.7781f, 4.502949f}, + {5344.150f, 2007.168f, 707.7781f, 3.159046f}, + {5319.158f, 1973.998f, 707.7781f, 1.919862f}, + {5302.247f, 1972.415f, 707.7781f, 1.378810f}, + {5277.739f, 2016.882f, 707.7781f, 5.969026f}, + {5322.964f, 2040.288f, 707.7781f, 4.345870f}, + {5343.467f, 2015.951f, 707.7781f, 3.490659f}, + {5313.820f, 1978.146f, 707.7781f, 1.745329f}, + {5279.649f, 2004.656f, 707.7781f, 0.069814f}, + {5306.057f, 2037.002f, 707.7781f, 4.817109f}, + {5337.865f, 2003.403f, 707.7781f, 2.984513f}, + {5299.434f, 1979.009f, 707.7781f, 1.239184f}, + {5312.752f, 2037.122f, 707.7781f, 4.590216f}, + {5335.724f, 1996.859f, 707.7781f, 2.740167f}, + {5280.632f, 2012.156f, 707.7781f, 6.056293f}, + {5320.369f, 1980.125f, 707.7781f, 2.007129f}, + {5306.572f, 1977.474f, 707.7781f, 1.500983f}, + {5336.599f, 2017.278f, 707.7781f, 3.473205f}, + {5282.897f, 2019.597f, 707.7781f, 5.881760f}, + {5318.704f, 2036.108f, 707.7781f, 4.223697f}, + {5280.513f, 1997.842f, 707.7781f, 0.296706f}, + {5337.833f, 2010.057f, 707.7781f, 3.228859f}, + {5299.250f, 2035.998f, 707.7781f, 5.026548f}, }; class instance_halls_of_reflection : public InstanceMapScript @@ -104,107 +69,107 @@ class instance_halls_of_reflection : public InstanceMapScript public: instance_halls_of_reflection() : InstanceMapScript("instance_halls_of_reflection", 668) { } - InstanceScript* GetInstanceScript(InstanceMap* map) const - { - return new instance_halls_of_reflection_InstanceMapScript(map); - } - struct instance_halls_of_reflection_InstanceMapScript : public InstanceScript { - instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) {}; - - uint64 uiFalric; - uint64 uiMarwyn; - uint64 uiLichKingEvent; - uint64 uiJainaPart1; - uint64 uiSylvanasPart1; - - uint64 uiFrostmourne; - uint64 uiFrostmourneAltar; - uint64 uiArthasDoor; - uint64 uiFrontDoor; - - uint32 uiEncounter[MAX_ENCOUNTER]; - uint32 uiTeamInInstance; - uint32 uiWaveCount; - bool bIntroDone; - - EventMap events; + instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) {} void Initialize() { + SetBossNumber(MAX_ENCOUNTER); events.Reset(); + _falricGUID = 0; + _marwynGUID = 0; + _jainaOrSylvanasPart1GUID = 0; + _frostwornGeneralGUID = 0; + _frostmourneGUID = 0; + _entranceDoorGUID = 0; + _frostwornDoorGUID = 0; + _arthasDoorGUID = 0; + _teamInInstance = 0; + _waveCount = 0; + _introEvent = NOT_STARTED; + _frostwornGeneral = NOT_STARTED; + } - uiFalric = 0; - uiMarwyn = 0; - uiLichKingEvent = 0; - uiJainaPart1 = 0; - uiSylvanasPart1 = 0; - - uiFrostmourne = 0; - uiFrostmourneAltar = 0; - uiArthasDoor = 0; - uiFrontDoor = 0; - uiTeamInInstance = 0; - uiWaveCount = 0; - bIntroDone = false; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - uiEncounter[i] = NOT_STARTED; + void OnPlayerEnter(Player* player) + { + if (!_teamInInstance) + _teamInInstance = player->GetTeam(); } void OnCreatureCreate(Creature* creature) { - Map::PlayerList const &players = instance->GetPlayers(); + Map::PlayerList const& players = instance->GetPlayers(); if (!players.isEmpty()) if (Player* player = players.begin()->getSource()) - uiTeamInInstance = player->GetTeam(); + _teamInInstance = player->GetTeam(); switch (creature->GetEntry()) { + case NPC_JAINA_PART1: + case NPC_SYLVANAS_PART1: + _jainaOrSylvanasPart1GUID = creature->GetGUID(); + break; case NPC_FALRIC: - uiFalric = creature->GetGUID(); + _falricGUID = creature->GetGUID(); break; case NPC_MARWYN: - uiMarwyn = creature->GetGUID(); - break; - case NPC_LICH_KING_EVENT: - uiLichKingEvent = creature->GetGUID(); + _marwynGUID = creature->GetGUID(); break; - case NPC_JAINA_PART1: - uiJainaPart1 = creature->GetGUID(); + case NPC_FROSTWORN_GENERAL: + _frostwornGeneralGUID = creature->GetGUID(); + if (GetBossState(DATA_MARWYN_EVENT) == DONE) + if (Creature* general = instance->GetCreature(_frostwornGeneralGUID)) + general->SetPhaseMask(1, true); break; - case NPC_SYLVANAS_PART1: - uiSylvanasPart1 = creature->GetGUID(); + } + } + + void OnCreatureRemove(Creature* creature) + { + switch (creature->GetEntry()) + { + case NPC_WAVE_MERCENARY: + case NPC_WAVE_FOOTMAN: + case NPC_WAVE_RIFLEMAN: + case NPC_WAVE_PRIEST: + case NPC_WAVE_MAGE: + { + uint32 internalWaveId = creature->AI()->GetData(0); + waveGuidList[internalWaveId].erase(creature->GetGUID()); break; + } } } void OnGameObjectCreate(GameObject* go) { - /// @todo init state depending on encounters switch (go->GetEntry()) { case GO_FROSTMOURNE: - uiFrostmourne = go->GetGUID(); + _frostmourneGUID = go->GetGUID(); go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); HandleGameObject(0, false, go); + if (GetData(DATA_INTRO_EVENT) == DONE) + go->SetPhaseMask(2, true); break; - case GO_FROSTMOURNE_ALTAR: - uiFrostmourneAltar = go->GetGUID(); + case GO_ENTRANCE_DOOR: + _entranceDoorGUID = go->GetGUID(); go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); HandleGameObject(0, true, go); break; - case GO_FRONT_DOOR: - uiFrontDoor = go->GetGUID(); + case GO_FROSTWORN_DOOR: + _frostwornDoorGUID = go->GetGUID(); go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - HandleGameObject(0, true, go); + if (GetBossState(DATA_MARWYN_EVENT) == DONE) + HandleGameObject(0, true, go); + else + HandleGameObject(0, false, go); break; case GO_ARTHAS_DOOR: - uiArthasDoor = go->GetGUID(); + _arthasDoorGUID = go->GetGUID(); go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - - if (uiEncounter[1] == DONE) + if (GetBossState(DATA_FROSWORN_EVENT) == DONE) HandleGameObject(0, true, go); else HandleGameObject(0, false, go); @@ -212,61 +177,273 @@ public: } } - void SetData(uint32 type, uint32 data) + void FillInitialWorldStates(WorldPacket& data) { - if (type == DATA_WAVE_COUNT && data == SPECIAL) - { - bIntroDone = true; - events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); - return; - } + data << uint32(WORLD_STATE_HOR_WAVES_ENABLED) << uint32(0); + data << uint32(WORLD_STATE_HOR_WAVE_COUNT) << uint32(0); + } - if (uiWaveCount && data == NOT_STARTED) - DoWipe(); + bool SetBossState(uint32 type, EncounterState state) + { + if (!InstanceScript::SetBossState(type, state)) + return false; switch (type) { case DATA_FALRIC_EVENT: - uiEncounter[0] = data; - if (data == DONE) + if (state == DONE) + { + ++_waveCount; events.ScheduleEvent(EVENT_NEXT_WAVE, 60000); + } break; case DATA_MARWYN_EVENT: - uiEncounter[1] = data; - if (data == DONE) - HandleGameObject(uiArthasDoor, true); + if (state == DONE) + { + HandleGameObject(_entranceDoorGUID, true); + HandleGameObject(_frostwornDoorGUID, true); + if (Creature* general = instance->GetCreature(_frostwornGeneralGUID)) + general->SetPhaseMask(1, true); + } break; case DATA_LICHKING_EVENT: - uiEncounter[2] = data; break; + default: + break; + } + + return true; + } + + void SetData(uint32 type, uint32 data) + { + switch (type) + { + case DATA_INTRO_EVENT: + if (data == IN_PROGRESS) + { + if (!_introEvent) + { + if (_teamInInstance == ALLIANCE) + instance->SummonCreature(NPC_JAINA_PART1, JainaSpawnPos); + else + instance->SummonCreature(NPC_SYLVANAS_PART1, SylvanasSpawnPos); + } + } + _introEvent = data; + break; + case DATA_WAVE_COUNT: + if (_waveCount && data == NOT_STARTED) + ProcessEvent(NULL, EVENT_DO_WIPE); + break; + case DATA_FROSWORN_EVENT: + if (data == DONE) + { + HandleGameObject(_arthasDoorGUID, true); + // spawn Jaina part 2 + // spawn LK part 2 + } + _frostwornGeneral = data; + break; + } + + SaveToDB(); + } + + + // wave scheduling,checked when wave npcs die + void OnUnitDeath(Unit* unit) + { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + + switch (creature->GetEntry()) + { + case NPC_WAVE_MERCENARY: + case NPC_WAVE_FOOTMAN: + case NPC_WAVE_RIFLEMAN: + case NPC_WAVE_PRIEST: + case NPC_WAVE_MAGE: + { + uint32 deadNpcs = 0; + uint32 waveId = creature->AI()->GetData(0); + for (std::set<uint64>::const_iterator itr = waveGuidList[waveId].begin(); itr != waveGuidList[waveId].end(); ++itr) + { + Creature* npc = instance->GetCreature(*itr); + if (!npc || !npc->isAlive()) + ++deadNpcs; + } + + // because the current npc returns isAlive when OnUnitDeath happens + // we check if the number of dead npcs is equal to the list-1 + if (deadNpcs == waveGuidList[waveId].size() - 1) + { + ++_waveCount; + events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); + } + break; + } } + } + + void Update(uint32 diff) + { + if (!instance->HavePlayers()) + return; - if (data == DONE) - SaveToDB(); + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_NEXT_WAVE: + ProcessEvent(NULL, EVENT_ADD_WAVE); + break; + } + } + + void ProcessEvent(WorldObject* /*go*/, uint32 eventId) + { + switch (eventId) + { + // spawning all wave npcs at once + case EVENT_SPAWN_WAVES: + _waveCount = 1; + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); + { + std::list<uint32> possibilityList, tempList; + uint32 posIndex = 0; + + possibilityList.push_back(NPC_WAVE_MERCENARY); + possibilityList.push_back(NPC_WAVE_FOOTMAN); + possibilityList.push_back(NPC_WAVE_RIFLEMAN); + possibilityList.push_back(NPC_WAVE_PRIEST); + possibilityList.push_back(NPC_WAVE_MAGE); + + // iterate each wave + for (uint8 i = 0; i < 8; ++i) + { + tempList = possibilityList; + + uint64 bossGuid = i <= 3 ? _falricGUID : _marwynGUID; + + if (!i) + Trinity::Containers::RandomResizeList(tempList, 3); + else if (i < 6 && i != 3) + Trinity::Containers::RandomResizeList(tempList, 4); + + for (std::list<uint32>::const_iterator itr = tempList.begin(); itr != tempList.end(); ++itr) + { + if (Creature* boss = instance->GetCreature(bossGuid)) + { + if (Creature* temp = boss->SummonCreature(*itr, SpawnPos[posIndex], TEMPSUMMON_DEAD_DESPAWN)) + { + temp->AI()->SetData(0, i); + waveGuidList[i].insert(temp->GetGUID()); + } + } + + ++posIndex; + } + } + } + events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); + break; + case EVENT_ADD_WAVE: + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); + HandleGameObject(_entranceDoorGUID, false); + + if (_waveCount % 5) + { + uint32 internalWaveId = _waveCount - ((_waveCount < 5) ? 1 : 2); + for (std::set<uint64>::const_iterator itr = waveGuidList[internalWaveId].begin(); itr != waveGuidList[internalWaveId].end(); ++itr) + { + if (Creature* temp = instance->GetCreature(*itr)) + { + temp->CastSpell(temp, SPELL_SPIRIT_ACTIVATE, true); + temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_NOT_SELECTABLE); + temp->AI()->DoZoneInCombat(); + } + } + } + else + { + uint32 bossIndex = (_waveCount / 5) - 1; + if (GetBossState(DATA_FALRIC_EVENT + bossIndex) != DONE) + { + if (Creature* boss = instance->GetCreature(bossIndex ? _marwynGUID : _falricGUID)) + if (boss->AI()) + boss->AI()->DoAction(ACTION_ENTER_COMBAT); + } + else if (_waveCount != 10) + { + ++_waveCount; + events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); + } + } + break; + case EVENT_DO_WIPE: + _waveCount = 0; + events.Reset(); + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); + HandleGameObject(_entranceDoorGUID, true); + + if (Creature* falric = instance->GetCreature(_falricGUID)) + falric->SetVisible(false); + if (Creature* marwyn = instance->GetCreature(_marwynGUID)) + marwyn->SetVisible(false); + + //despawn wave npcs + for (uint8 i = 0; i < 8; ++i) + { + for (std::set<uint64>::const_iterator itr = waveGuidList[i].begin(); itr != waveGuidList[i].end(); ++itr) + if (Creature* creature = instance->GetCreature(*itr)) + creature->DespawnOrUnsummon(1); + + waveGuidList[i].clear(); + } + break; + } } uint32 GetData(uint32 type) const { switch (type) { - case DATA_FALRIC_EVENT: return uiEncounter[0]; - case DATA_MARWYN_EVENT: return uiEncounter[1]; - case DATA_LICHKING_EVENT: return uiEncounter[2]; - case DATA_WAVE_COUNT: return uiWaveCount; - case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance; + case DATA_WAVE_COUNT: + return _waveCount; + case DATA_TEAM_IN_INSTANCE: + return _teamInInstance; + case DATA_INTRO_EVENT: + return _introEvent; + case DATA_FROSWORN_EVENT: + return _frostwornGeneral; + default: + break; } return 0; } - uint64 GetData64(uint32 identifier) const + uint64 GetData64(uint32 type) const { - switch (identifier) + switch (type) { - case DATA_FALRIC: return uiFalric; - case DATA_MARWYN: return uiMarwyn; - case DATA_LICHKING: return uiLichKingEvent; - case DATA_FROSTMOURNE: return uiFrostmourne; + case DATA_FALRIC_EVENT: + return _falricGUID; + case DATA_MARWYN_EVENT: + return _marwynGUID; + case DATA_FROSWORN_EVENT: + return _frostwornGeneralGUID; + case DATA_FROSTWORN_DOOR: + return _frostwornDoorGUID; + case DATA_FROSTMOURNE: + return _frostmourneGUID; + default: + break; } return 0; @@ -277,13 +454,13 @@ public: OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << "H R 1 " << uiEncounter[0] << ' ' << uiEncounter[1] << ' ' << uiEncounter[2]; + saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral; OUT_SAVE_INST_DATA_COMPLETE; return saveStream.str(); } - void Load(const char* in) + void Load(char const* in) { if (!in) { @@ -294,135 +471,67 @@ public: OUT_LOAD_INST_DATA(in); char dataHead1, dataHead2; - uint16 version; - uint16 data0, data1, data2; std::istringstream loadStream(in); - loadStream >> dataHead1 >> dataHead2 >> version >> data0 >> data1 >> data2; + loadStream >> dataHead1 >> dataHead2; if (dataHead1 == 'H' && dataHead2 == 'R') { - uiEncounter[0] = data0; - uiEncounter[1] = data1; - uiEncounter[2] = data2; - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (uiEncounter[i] == IN_PROGRESS) - uiEncounter[i] = NOT_STARTED; - - } else OUT_LOAD_INST_DATA_FAIL; - - if (uiEncounter[0] == DONE || uiEncounter[1] == DONE) - bIntroDone = true; - - OUT_LOAD_INST_DATA_COMPLETE; - } - - void AddWave() - { - DoUpdateWorldState(WORLD_STATE_HOR, 1); - DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount); - - switch (uiWaveCount) - { - case 1: - case 2: - case 3: - case 4: - if (Creature* pFalric = instance->GetCreature(uiFalric)) - SpawnWave(pFalric); - break; - case 5: - if (GetData(DATA_FALRIC_EVENT) == DONE) - events.ScheduleEvent(EVENT_NEXT_WAVE, 10000); - else if (Creature* pFalric = instance->GetCreature(uiFalric)) - if (pFalric->AI()) - pFalric->AI()->DoAction(ACTION_ENTER_COMBAT); - break; - case 6: - case 7: - case 8: - case 9: - if (Creature* pMarwyn = instance->GetCreature(uiMarwyn)) - SpawnWave(pMarwyn); - break; - case 10: - if (GetData(DATA_MARWYN_EVENT) != DONE) // wave should not have been started if DONE. Check anyway to avoid bug exploit! - if (Creature* pMarwyn = instance->GetCreature(uiMarwyn)) - if (pMarwyn->AI()) - pMarwyn->AI()->DoAction(ACTION_ENTER_COMBAT); - break; + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + + SetBossState(i, EncounterState(tmpState)); + } + + uint32 temp = 0; + loadStream >> temp; + if (temp == DONE) + SetData(DATA_INTRO_EVENT, DONE); + else + SetData(DATA_INTRO_EVENT, NOT_STARTED); + + loadStream >> temp; + if (temp == DONE) + SetData(DATA_FROSWORN_EVENT, DONE); + else + SetData(DATA_FROSWORN_EVENT, NOT_STARTED); } - } + else + OUT_LOAD_INST_DATA_FAIL; - // Wipe has been detected. Perform cleanup and reset. - void DoWipe() - { - uiWaveCount = 0; - events.Reset(); - DoUpdateWorldState(WORLD_STATE_HOR, 1); - DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount); - HandleGameObject(uiFrontDoor, true); - - /// @todo - // in case of wipe, the event is normally restarted by jumping into the center of the room. - // As I can't find a trigger area there, just respawn Jaina/Sylvanas so the event may be restarted. - if (Creature* pJaina = instance->GetCreature(uiJainaPart1)) - pJaina->Respawn(); - if (Creature* pSylvanas = instance->GetCreature(uiSylvanasPart1)) - pSylvanas->Respawn(); - - if (Creature* pFalric = instance->GetCreature(uiFalric)) - pFalric->SetVisible(false); - if (Creature* pMarwyn = instance->GetCreature(uiMarwyn)) - pMarwyn->SetVisible(false); + OUT_LOAD_INST_DATA_COMPLETE; } - // spawn a wave on behalf of the summoner. - void SpawnWave(Creature* summoner) - { - uint32 index; - - summoner->SetVisible(true); - - /// @todo do composition at random. # of spawn also depends on uiWaveCount - // As of now, it is just one of each. - index = urand(0, ENCOUNTER_WAVE_MERCENARY-1); - summoner->SummonCreature(NPC_WAVE_MERCENARY, MercenarySpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); - - index = urand(0, ENCOUNTER_WAVE_FOOTMAN-1); - summoner->SummonCreature(NPC_WAVE_FOOTMAN, FootmenSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); - - index = urand(0, ENCOUNTER_WAVE_RIFLEMAN-1); - summoner->SummonCreature(NPC_WAVE_RIFLEMAN, RiflemanSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); + private: + uint64 _falricGUID; + uint64 _marwynGUID; + uint64 _jainaOrSylvanasPart1GUID; + uint64 _frostwornGeneralGUID; - index = urand(0, ENCOUNTER_WAVE_PRIEST-1); - summoner->SummonCreature(NPC_WAVE_PRIEST, PriestSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); + uint64 _frostmourneGUID; + uint64 _entranceDoorGUID; + uint64 _frostwornDoorGUID; + uint64 _arthasDoorGUID; + uint64 _escapeDoorGUID; - index = urand(0, ENCOUNTER_WAVE_MAGE-1); - summoner->SummonCreature(NPC_WAVE_MAGE, MageSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); - } - - void Update(uint32 diff) - { - if (!instance->HavePlayers()) - return; + uint32 _teamInInstance; + uint32 _waveCount; + uint32 _introEvent; + uint32 _frostwornGeneral; - events.Update(diff); + EventMap events; - switch (events.ExecuteEvent()) - { - case EVENT_NEXT_WAVE: - uiWaveCount++; - AddWave(); - break; - case EVENT_START_LICH_KING: - /// @todo - break; - } - } + std::set<uint64> waveGuidList[8]; }; + InstanceScript* GetInstanceScript(InstanceMap* map) const + { + return new instance_halls_of_reflection_InstanceMapScript(map); + } }; void AddSC_instance_halls_of_reflection() diff --git a/src/server/scripts/Northrend/Gundrak/gundrak.h b/src/server/scripts/Northrend/Gundrak/gundrak.h index 0c65b4d16de..a43edb4fcd7 100644 --- a/src/server/scripts/Northrend/Gundrak/gundrak.h +++ b/src/server/scripts/Northrend/Gundrak/gundrak.h @@ -43,12 +43,31 @@ enum Data64 enum mainCreatures { - CREATURE_RUIN_DWELLER = 29920, - CREATURE_SLAD_RAN = 29304, - CREATURE_MOORABI = 29305, - CREATURE_GALDARAH = 29306, - CREATURE_DRAKKARICOLOSSUS = 29307, - CREATURE_ECK = 29932 + CREATURE_RUIN_DWELLER = 29920, + CREATURE_SLAD_RAN = 29304, + CREATURE_MOORABI = 29305, + CREATURE_GALDARAH = 29306, + CREATURE_DRAKKARICOLOSSUS = 29307, + CREATURE_ECK = 29932 +}; + +enum Gameobjects { + + GO_SLADRAN_ALTAR = 192518, + GO_MOORABI_ALTAR = 192519, + GO_DRAKKARI_COLOSSUS_ALTAR = 192520, + GO_SLADRAN_STATUE = 192564, + GO_MOORABI_STATUE = 192565, + GO_GALDARAH_STATUE = 192566, + GO_DRAKKARI_COLOSSUS_STATUE = 192567, + GO_ECK_THE_FEROCIOUS_DOOR = 192632, + GO_ECK_THE_FEROCIOUS_DOOR_BEHIND = 192569, + GO_GALDARAH_DOOR1 = 193208, + GO_GALDARAH_DOOR2 = 193209, + GO_GALDARAH_DOOR3 = 192568, + GO_BRIDGE = 193188, + GO_COLLISION = 192633 + }; #endif diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp index a9bbffa5fb0..d17198b0c92 100644 --- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp +++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp @@ -45,44 +45,45 @@ public: { instance_gundrak_InstanceMapScript(Map* map) : InstanceScript(map) { - bHeroicMode = map->IsHeroic(); + isHeroic = map->IsHeroic(); } - bool bHeroicMode; + bool isHeroic; bool spawnSupport; uint32 timer; uint32 phase; uint64 toActivate; - uint64 uiSladRan; - uint64 uiMoorabi; - uint64 uiDrakkariColossus; - uint64 uiGalDarah; - uint64 uiEckTheFerocious; - - uint64 uiSladRanAltar; - uint64 uiMoorabiAltar; - uint64 uiDrakkariColossusAltar; - uint64 uiSladRanStatue; - uint64 uiMoorabiStatue; - uint64 uiDrakkariColossusStatue; - uint64 uiGalDarahStatue; - uint64 uiEckTheFerociousDoor; - uint64 uiEckTheFerociousDoorBehind; - uint64 uiGalDarahDoor1; - uint64 uiGalDarahDoor2; - uint64 uiBridge; - uint64 uiCollision; + uint64 sladRanGUID; + uint64 moorabiGUID; + uint64 drakkariColossusGUID; + uint64 galDarahGUID; + uint64 eckTheFerociousGUID; + + uint64 sladRanAltarGUID; + uint64 moorabiAltarGUID; + uint64 drakkariColossusAltarGUID; + uint64 sladRanStatueGUID; + uint64 moorabiStatueGUID; + uint64 drakkariColossusStatueGUID; + uint64 galDarahStatueGUID; + uint64 eckTheFerociousDoorGUID; + uint64 eckTheFerociousDoorBehindGUID; + uint64 galDarahDoor1GUID; + uint64 galDarahDoor2GUID; + uint64 galDarahDoor3GUID; + uint64 bridgeGUID; + uint64 collisionGUID; uint32 m_auiEncounter[MAX_ENCOUNTER]; - GOState uiSladRanStatueState; - GOState uiMoorabiStatueState; - GOState uiDrakkariColossusStatueState; - GOState uiGalDarahStatueState; - GOState uiBridgeState; - GOState uiCollisionState; + GOState sladRanStatueState; + GOState moorabiStatueState; + GOState drakkariColossusStatueState; + GOState galDarahStatueState; + GOState bridgeState; + GOState collisionState; std::set<uint64> DwellerGUIDs; @@ -96,35 +97,36 @@ public: phase = 0; toActivate = 0; - uiSladRan = 0; - uiMoorabi = 0; - uiDrakkariColossus = 0; - uiGalDarah = 0; - uiEckTheFerocious = 0; - - uiSladRanAltar = 0; - uiMoorabiAltar = 0; - uiDrakkariColossusAltar = 0; - - uiSladRanStatue = 0; - uiMoorabiStatue = 0; - uiDrakkariColossusStatue = 0; - uiGalDarahStatue = 0; - - uiEckTheFerociousDoor = 0; - uiEckTheFerociousDoorBehind = 0; - uiGalDarahDoor1 = 0; - uiGalDarahDoor2 = 0; - - uiBridge = 0; - uiCollision = 0; - - uiSladRanStatueState = GO_STATE_ACTIVE; - uiMoorabiStatueState = GO_STATE_ACTIVE; - uiDrakkariColossusStatueState = GO_STATE_ACTIVE; - uiGalDarahStatueState = GO_STATE_READY; - uiBridgeState = GO_STATE_ACTIVE; - uiCollisionState = GO_STATE_READY; + sladRanGUID = 0; + moorabiGUID = 0; + drakkariColossusGUID = 0; + galDarahGUID = 0; + eckTheFerociousGUID = 0; + + sladRanAltarGUID = 0; + moorabiAltarGUID = 0; + drakkariColossusAltarGUID = 0; + + sladRanStatueGUID = 0; + moorabiStatueGUID = 0; + drakkariColossusStatueGUID = 0; + galDarahStatueGUID = 0; + + eckTheFerociousDoorGUID = 0; + eckTheFerociousDoorBehindGUID = 0; + galDarahDoor1GUID = 0; + galDarahDoor2GUID = 0; + galDarahDoor3GUID = 0; + + bridgeGUID = 0; + collisionGUID = 0; + + sladRanStatueState = GO_STATE_ACTIVE; + moorabiStatueState = GO_STATE_ACTIVE; + drakkariColossusStatueState = GO_STATE_ACTIVE; + galDarahStatueState = GO_STATE_READY; + bridgeState = GO_STATE_ACTIVE; + collisionState = GO_STATE_READY; DwellerGUIDs.clear(); @@ -144,11 +146,21 @@ public: { switch (creature->GetEntry()) { - case CREATURE_SLAD_RAN: uiSladRan = creature->GetGUID(); break; - case CREATURE_MOORABI: uiMoorabi = creature->GetGUID(); break; - case CREATURE_GALDARAH: uiGalDarah = creature->GetGUID(); break; - case CREATURE_DRAKKARICOLOSSUS: uiDrakkariColossus = creature->GetGUID(); break; - case CREATURE_ECK: uiEckTheFerocious = creature->GetGUID(); break; + case CREATURE_SLAD_RAN: + sladRanGUID = creature->GetGUID(); + break; + case CREATURE_MOORABI: + moorabiGUID = creature->GetGUID(); + break; + case CREATURE_GALDARAH: + galDarahGUID = creature->GetGUID(); + break; + case CREATURE_DRAKKARICOLOSSUS: + drakkariColossusGUID = creature->GetGUID(); + break; + case CREATURE_ECK: + eckTheFerociousGUID = creature->GetGUID(); + break; case CREATURE_RUIN_DWELLER: if (creature->isAlive()) DwellerGUIDs.insert(creature->GetGUID()); @@ -160,13 +172,13 @@ public: { switch (go->GetEntry()) { - case 192518: - uiSladRanAltar = go->GetGUID(); + case GO_SLADRAN_ALTAR: + sladRanAltarGUID = go->GetGUID(); // Make sure that they start out as unusuable go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (m_auiEncounter[0] == DONE) { - if (uiSladRanStatueState == GO_STATE_ACTIVE) + if (sladRanStatueState == GO_STATE_ACTIVE) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); else { @@ -175,13 +187,13 @@ public: } } break; - case 192519: - uiMoorabiAltar = go->GetGUID(); + case GO_MOORABI_ALTAR: + moorabiAltarGUID = go->GetGUID(); // Make sure that they start out as unusuable go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (m_auiEncounter[0] == DONE) { - if (uiMoorabiStatueState == GO_STATE_ACTIVE) + if (moorabiStatueState == GO_STATE_ACTIVE) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); else { @@ -190,13 +202,13 @@ public: } } break; - case 192520: - uiDrakkariColossusAltar = go->GetGUID(); + case GO_DRAKKARI_COLOSSUS_ALTAR: + drakkariColossusAltarGUID = go->GetGUID(); // Make sure that they start out as unusuable go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (m_auiEncounter[0] == DONE) { - if (uiDrakkariColossusStatueState == GO_STATE_ACTIVE) + if (drakkariColossusStatueState == GO_STATE_ACTIVE) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); else { @@ -205,53 +217,58 @@ public: } } break; - case 192564: - uiSladRanStatue = go->GetGUID(); - go->SetGoState(uiSladRanStatueState); + case GO_SLADRAN_STATUE: + sladRanStatueGUID = go->GetGUID(); + go->SetGoState(sladRanStatueState); break; - case 192565: - uiMoorabiStatue = go->GetGUID(); - go->SetGoState(uiMoorabiStatueState); + case GO_MOORABI_STATUE: + moorabiStatueGUID = go->GetGUID(); + go->SetGoState(moorabiStatueState); break; - case 192566: - uiGalDarahStatue = go->GetGUID(); - go->SetGoState(uiGalDarahStatueState); + case GO_GALDARAH_STATUE: + galDarahStatueGUID = go->GetGUID(); + go->SetGoState(galDarahStatueState); break; - case 192567: - uiDrakkariColossusStatue = go->GetGUID(); - go->SetGoState(uiDrakkariColossusStatueState); + case GO_DRAKKARI_COLOSSUS_STATUE: + drakkariColossusStatueGUID = go->GetGUID(); + go->SetGoState(drakkariColossusStatueState); break; - case 192632: - uiEckTheFerociousDoor = go->GetGUID(); - if (bHeroicMode && m_auiEncounter[1] == DONE) + case GO_ECK_THE_FEROCIOUS_DOOR: + eckTheFerociousDoorGUID = go->GetGUID(); + if (isHeroic && m_auiEncounter[1] == DONE) HandleGameObject(0, true, go); break; - case 192569: - uiEckTheFerociousDoorBehind = go->GetGUID(); - if (bHeroicMode && m_auiEncounter[4] == DONE) + case GO_ECK_THE_FEROCIOUS_DOOR_BEHIND: + eckTheFerociousDoorBehindGUID = go->GetGUID(); + if (isHeroic && m_auiEncounter[4] == DONE) HandleGameObject(0, true, go); - case 193208: - uiGalDarahDoor1 = go->GetGUID(); + case GO_GALDARAH_DOOR1: + galDarahDoor1GUID = go->GetGUID(); if (m_auiEncounter[3] == DONE) HandleGameObject(0, true, go); break; - case 193209: - uiGalDarahDoor2 = go->GetGUID(); + case GO_GALDARAH_DOOR2: + galDarahDoor2GUID = go->GetGUID(); if (m_auiEncounter[3] == DONE) HandleGameObject(0, true, go); break; - case 193188: - uiBridge = go->GetGUID(); - go->SetGoState(uiBridgeState); + case GO_BRIDGE: + bridgeGUID = go->GetGUID(); + go->SetGoState(bridgeState); break; - case 192633: - uiCollision = go->GetGUID(); - go->SetGoState(uiCollisionState); + case GO_COLLISION: + collisionGUID = go->GetGUID(); + go->SetGoState(collisionState); // Can't spawn here with SpawnGameObject because go isn't added to world yet... - if (uiCollisionState == GO_STATE_ACTIVE_ALTERNATIVE) + if (collisionState == GO_STATE_ACTIVE_ALTERNATIVE) spawnSupport = true; break; + case GO_GALDARAH_DOOR3: + galDarahDoor3GUID = go->GetGUID(); + if (m_auiEncounter[3] != IN_PROGRESS) + HandleGameObject(galDarahDoor3GUID, true, go); + break; } } @@ -263,7 +280,7 @@ public: m_auiEncounter[0] = data; if (data == DONE) { - GameObject* go = instance->GetGameObject(uiSladRanAltar); + GameObject* go = instance->GetGameObject(sladRanAltarGUID); if (go) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } @@ -272,18 +289,18 @@ public: m_auiEncounter[1] = data; if (data == DONE) { - GameObject* go = instance->GetGameObject(uiMoorabiAltar); + GameObject* go = instance->GetGameObject(moorabiAltarGUID); if (go) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - if (bHeroicMode) - HandleGameObject(uiEckTheFerociousDoor, true); + if (isHeroic) + HandleGameObject(eckTheFerociousDoorGUID, true); } break; case DATA_DRAKKARI_COLOSSUS_EVENT: m_auiEncounter[2] = data; if (data == DONE) { - GameObject* go = instance->GetGameObject(uiDrakkariColossusAltar); + GameObject* go = instance->GetGameObject(drakkariColossusAltarGUID); if (go) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); } @@ -292,14 +309,15 @@ public: m_auiEncounter[3] = data; if (data == DONE) { - HandleGameObject(uiGalDarahDoor1, true); - HandleGameObject(uiGalDarahDoor2, true); + HandleGameObject(galDarahDoor1GUID, true); + HandleGameObject(galDarahDoor2GUID, true); } + HandleGameObject(galDarahDoor3GUID, data == IN_PROGRESS ? false : true); break; case DATA_ECK_THE_FEROCIOUS_EVENT: m_auiEncounter[4] = data; - if (bHeroicMode && data == DONE) - HandleGameObject(uiEckTheFerociousDoorBehind, true); + if (isHeroic && data == DONE) + HandleGameObject(eckTheFerociousDoorBehindGUID, true); break; } @@ -345,19 +363,19 @@ public: switch (type) { case DATA_SLAD_RAN_ALTAR: - return uiSladRanAltar; + return sladRanAltarGUID; case DATA_MOORABI_ALTAR: - return uiMoorabiAltar; + return moorabiAltarGUID; case DATA_DRAKKARI_COLOSSUS_ALTAR: - return uiDrakkariColossusAltar; + return drakkariColossusAltarGUID; case DATA_SLAD_RAN_STATUE: - return uiSladRanStatue; + return sladRanStatueGUID; case DATA_MOORABI_STATUE: - return uiMoorabiStatue; + return moorabiStatueGUID; case DATA_DRAKKARI_COLOSSUS_STATUE: - return uiDrakkariColossusStatue; + return drakkariColossusStatueGUID; case DATA_DRAKKARI_COLOSSUS: - return uiDrakkariColossus; + return drakkariColossusGUID; case DATA_STATUE_ACTIVATE: return toActivate; } @@ -372,9 +390,9 @@ public: std::ostringstream saveStream; saveStream << "G D " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4] << ' ' - << (uiSladRanStatue ? GetObjState(uiSladRanStatue) : GO_STATE_ACTIVE) << ' ' << (uiMoorabiStatue ? GetObjState(uiMoorabiStatue) : GO_STATE_ACTIVE) << ' ' - << (uiDrakkariColossusStatue ? GetObjState(uiDrakkariColossusStatue) : GO_STATE_ACTIVE) << ' ' << (uiGalDarahStatue ? GetObjState(uiGalDarahStatue) : GO_STATE_READY) << ' ' - << (uiBridge ? GetObjState(uiBridge) : GO_STATE_ACTIVE) << ' ' << (uiCollision ? GetObjState(uiCollision) : GO_STATE_READY); + << (sladRanStatueGUID ? GetObjState(sladRanStatueGUID) : GO_STATE_ACTIVE) << ' ' << (moorabiStatueGUID ? GetObjState(moorabiStatueGUID) : GO_STATE_ACTIVE) << ' ' + << (drakkariColossusStatueGUID ? GetObjState(drakkariColossusStatueGUID) : GO_STATE_ACTIVE) << ' ' << (galDarahStatueGUID ? GetObjState(galDarahStatueGUID) : GO_STATE_READY) << ' ' + << (bridgeGUID ? GetObjState(bridgeGUID) : GO_STATE_ACTIVE) << ' ' << (collisionGUID ? GetObjState(collisionGUID) : GO_STATE_READY); str_data = saveStream.str(); @@ -406,12 +424,12 @@ public: m_auiEncounter[2] = data2; m_auiEncounter[3] = data3; m_auiEncounter[4] = data4; - uiSladRanStatueState = GOState(data5); - uiMoorabiStatueState = GOState(data6); - uiDrakkariColossusStatueState = GOState(data7); - uiGalDarahStatueState = GOState(data8); - uiBridgeState = GOState(data9); - uiCollisionState = GOState(data10); + sladRanStatueState = GOState(data5); + moorabiStatueState = GOState(data6); + drakkariColossusStatueState = GOState(data7); + galDarahStatueState = GOState(data8); + bridgeState = GOState(data9); + collisionState = GOState(data10); for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) if (m_auiEncounter[i] == IN_PROGRESS) @@ -426,8 +444,8 @@ public: // Spawn the support for the bridge if necessary if (spawnSupport) { - if (GameObject* pCollision = instance->GetGameObject(uiCollision)) - pCollision->SummonGameObject(192743, pCollision->GetPositionX(), pCollision->GetPositionY(), pCollision->GetPositionZ(), pCollision->GetOrientation(), 0, 0, 0, 0, 0); + if (GameObject* collision = instance->GetGameObject(collisionGUID)) + collision->SummonGameObject(192743, collision->GetPositionX(), collision->GetPositionY(), collision->GetPositionZ(), collision->GetOrientation(), 0, 0, 0, 0, 0); spawnSupport = false; } @@ -438,25 +456,25 @@ public: if (timer < diff) { timer = 0; - if (toActivate == uiBridge) + if (toActivate == bridgeGUID) { - GameObject* pBridge = instance->GetGameObject(uiBridge); - GameObject* pCollision = instance->GetGameObject(uiCollision); - GameObject* pSladRanStatue = instance->GetGameObject(uiSladRanStatue); - GameObject* pMoorabiStatue = instance->GetGameObject(uiMoorabiStatue); - GameObject* pDrakkariColossusStatue = instance->GetGameObject(uiDrakkariColossusStatue); - GameObject* pGalDarahStatue = instance->GetGameObject(uiGalDarahStatue); + GameObject* bridge = instance->GetGameObject(bridgeGUID); + GameObject* collision = instance->GetGameObject(collisionGUID); + GameObject* sladRanStatue = instance->GetGameObject(sladRanStatueGUID); + GameObject* moorabiStatue = instance->GetGameObject(moorabiStatueGUID); + GameObject* drakkariColossusStatue = instance->GetGameObject(drakkariColossusStatueGUID); + GameObject* galDarahStatue = instance->GetGameObject(galDarahStatueGUID); toActivate = 0; - if (pBridge && pCollision && pSladRanStatue && pMoorabiStatue && pDrakkariColossusStatue && pGalDarahStatue) + if (bridge && collision && sladRanStatue && moorabiStatue && drakkariColossusStatue && galDarahStatue) { - pBridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - pCollision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - pSladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - pMoorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - pDrakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); - pGalDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + bridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + collision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + sladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + moorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + drakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); + galDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); // Add the GO that solidifies the bridge so you can walk on it spawnSupport = true; @@ -466,27 +484,27 @@ public: else { uint32 spell = 0; - GameObject* pAltar = NULL; - if (toActivate == uiSladRanStatue) + GameObject* altar = NULL; + if (toActivate == sladRanStatueGUID) { spell = 57071; - pAltar = instance->GetGameObject(uiSladRanAltar); + altar = instance->GetGameObject(sladRanAltarGUID); } - else if (toActivate == uiMoorabiStatue) + else if (toActivate == moorabiStatueGUID) { spell = 57068; - pAltar = instance->GetGameObject(uiMoorabiAltar); + altar = instance->GetGameObject(moorabiAltarGUID); } - else if (toActivate == uiDrakkariColossusStatue) + else if (toActivate == drakkariColossusStatueGUID) { spell = 57072; - pAltar = instance->GetGameObject(uiDrakkariColossusAltar); + altar = instance->GetGameObject(drakkariColossusAltarGUID); } // This is a workaround to make the beam cast properly. The caster should be ID 30298 but since the spells // all are with scripted target for that same ID, it will hit itself. - if (pAltar) - if (Creature* trigger = pAltar->SummonCreature(18721, pAltar->GetPositionX(), pAltar->GetPositionY(), pAltar->GetPositionZ() + 3, pAltar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000)) + if (altar) + if (Creature* trigger = altar->SummonCreature(18721, altar->GetPositionX(), altar->GetPositionY(), altar->GetPositionZ() + 3, altar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000)) { // Set the trigger model to invisible trigger->SetDisplayId(11686); @@ -499,7 +517,7 @@ public: toActivate = 0; if (phase == 3) - SetData64(DATA_STATUE_ACTIVATE, uiBridge); + SetData64(DATA_STATUE_ACTIVATE, bridgeGUID); else SaveToDB(); // Don't save in between last statue and bridge turning in case of crash leading to stuck instance } @@ -526,7 +544,7 @@ public: bool OnGossipHello(Player* /*player*/, GameObject* go) { InstanceScript* instance = go->GetInstanceScript(); - uint64 uiStatue = 0; + uint64 statueGUID = 0; go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); go->SetGoState(GO_STATE_ACTIVE); @@ -535,20 +553,20 @@ public: { switch (go->GetEntry()) { - case 192518: - uiStatue = instance->GetData64(DATA_SLAD_RAN_STATUE); + case GO_SLADRAN_ALTAR: + statueGUID = instance->GetData64(DATA_SLAD_RAN_STATUE); break; - case 192519: - uiStatue = instance->GetData64(DATA_MOORABI_STATUE); + case GO_MOORABI_ALTAR: + statueGUID = instance->GetData64(DATA_MOORABI_STATUE); break; - case 192520: - uiStatue = instance->GetData64(DATA_DRAKKARI_COLOSSUS_STATUE); + case GO_DRAKKARI_COLOSSUS_ALTAR: + statueGUID = instance->GetData64(DATA_DRAKKARI_COLOSSUS_STATUE); break; } if (!instance->GetData64(DATA_STATUE_ACTIVATE)) { - instance->SetData64(DATA_STATUE_ACTIVATE, uiStatue); + instance->SetData64(DATA_STATUE_ACTIVATE, statueGUID); go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); go->SetGoState(GO_STATE_ACTIVE); } |
