/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 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 Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include "CreatureScript.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "WorldStateDefines.h"
/*######
## npc_lady_sylvanas_windrunner
######*/
enum Sylvanas
{
QUEST_JOURNEY_TO_UNDERCITY = 9180,
EMOTE_LAMENT_END = 0,
SAY_LAMENT_END = 1,
EMOTE_LAMENT = 2,
// Ambassador Sunsorrow
SAY_SUNSORROW_WHISPER = 0,
SOUND_CREDIT = 10896,
NPC_HIGHBORNE_LAMENTER = 21628,
NPC_HIGHBORNE_BUNNY = 21641,
NPC_AMBASSADOR_SUNSORROW = 16287,
SPELL_HIGHBORNE_AURA = 37090,
SPELL_SYLVANAS_CAST = 36568,
//SPELL_RIBBON_OF_SOULS = 34432, the real one to use might be 37099
SPELL_RIBBON_OF_SOULS = 37099,
// Combat spells
SPELL_BLACK_ARROW = 59712,
SPELL_FADE = 20672,
SPELL_FADE_BLINK = 29211,
SPELL_MULTI_SHOT = 59713,
SPELL_SHOT = 59710,
SPELL_SUMMON_SKELETON = 59711,
// Events
EVENT_FADE = 1,
EVENT_SUMMON_SKELETON = 2,
EVENT_BLACK_ARROW = 3,
EVENT_SHOOT = 4,
EVENT_MULTI_SHOT = 5,
EVENT_LAMENT_OF_THE_HIGHBORN = 6,
EVENT_SUNSORROW_WHISPER = 7,
GUID_EVENT_INVOKER = 1,
};
float HighborneLoc[4][3] =
{
{1285.41f, 312.47f, 0.51f},
{1286.96f, 310.40f, 1.00f},
{1289.66f, 309.66f, 1.52f},
{1292.51f, 310.50f, 1.99f},
};
#define HIGHBORNE_LOC_Y -61.00f
#define HIGHBORNE_LOC_Y_NEW -55.50f
class npc_lady_sylvanas_windrunner : public CreatureScript
{
public:
npc_lady_sylvanas_windrunner() : CreatureScript("npc_lady_sylvanas_windrunner") { }
bool OnQuestReward(Player* player, Creature* creature, const Quest* _Quest, uint32 /*slot*/) override
{
if (_Quest->GetQuestId() == QUEST_JOURNEY_TO_UNDERCITY)
creature->AI()->SetGUID(player->GetGUID(), GUID_EVENT_INVOKER);
return true;
}
struct npc_lady_sylvanas_windrunnerAI : public ScriptedAI
{
npc_lady_sylvanas_windrunnerAI(Creature* creature) : ScriptedAI(creature)
{
}
void Reset() override
{
LamentEvent = false;
playerGUID.Clear();
_events.Reset();
}
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_FADE, 30s);
_events.ScheduleEvent(EVENT_SUMMON_SKELETON, 20s);
_events.ScheduleEvent(EVENT_BLACK_ARROW, 15s);
_events.ScheduleEvent(EVENT_SHOOT, 8s);
_events.ScheduleEvent(EVENT_MULTI_SHOT, 10s);
}
void SetGUID(ObjectGuid guid, int32 type) override
{
if (type == GUID_EVENT_INVOKER)
{
Talk(EMOTE_LAMENT);
DoPlayMusic(SOUND_CREDIT, true);
DoCast(me, SPELL_SYLVANAS_CAST, false);
playerGUID = guid;
LamentEvent = true;
for (uint8 i = 0; i < 4; ++i)
me->SummonCreature(NPC_HIGHBORNE_LAMENTER, HighborneLoc[i][0], HighborneLoc[i][1], HIGHBORNE_LOC_Y, HighborneLoc[i][2], TEMPSUMMON_TIMED_DESPAWN, 160000);
_events.ScheduleEvent(EVENT_LAMENT_OF_THE_HIGHBORN, 2s);
_events.ScheduleEvent(EVENT_SUNSORROW_WHISPER, 10s);
}
}
void JustSummoned(Creature* summoned) override
{
if (summoned->GetEntry() == NPC_HIGHBORNE_BUNNY)
{
summoned->SetDisableGravity(true);
float speed = summoned->GetDistance(summoned->GetPositionX(), summoned->GetPositionY(), me->GetPositionZ() + 15.0f) / (1000.0f * 0.001f);
summoned->MonsterMoveWithSpeed(summoned->GetPositionX(), summoned->GetPositionY(), me->GetPositionZ() + 15.0f, speed);
summoned->CastSpell(summoned, SPELL_RIBBON_OF_SOULS, false);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() && !LamentEvent)
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_FADE:
DoCast(me, SPELL_FADE);
// add a blink to simulate a stealthed movement and reappearing elsewhere
DoCast(me, SPELL_FADE_BLINK);
// if the victim is out of melee range she cast multi shot
if (Unit* victim = me->GetVictim())
if (me->GetDistance(victim) > 10.0f)
DoCast(victim, SPELL_MULTI_SHOT);
_events.ScheduleEvent(EVENT_FADE, 30s, 35s);
break;
case EVENT_SUMMON_SKELETON:
DoCast(me, SPELL_SUMMON_SKELETON);
_events.ScheduleEvent(EVENT_SUMMON_SKELETON, 20s, 30s);
break;
case EVENT_BLACK_ARROW:
if (Unit* victim = me->GetVictim())
DoCast(victim, SPELL_BLACK_ARROW);
_events.ScheduleEvent(EVENT_BLACK_ARROW, 15s, 20s);
break;
case EVENT_SHOOT:
if (Unit* victim = me->GetVictim())
DoCast(victim, SPELL_SHOT);
_events.ScheduleEvent(EVENT_SHOOT, 8s, 10s);
break;
case EVENT_MULTI_SHOT:
if (Unit* victim = me->GetVictim())
DoCast(victim, SPELL_MULTI_SHOT);
_events.ScheduleEvent(EVENT_MULTI_SHOT, 10s, 13s);
break;
case EVENT_LAMENT_OF_THE_HIGHBORN:
if (!me->HasAura(SPELL_SYLVANAS_CAST))
{
Talk(SAY_LAMENT_END);
Talk(EMOTE_LAMENT_END);
LamentEvent = false;
me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
Reset();
}
else
{
DoSummon(NPC_HIGHBORNE_BUNNY, me, 10.0f, 3000, TEMPSUMMON_TIMED_DESPAWN);
_events.ScheduleEvent(EVENT_LAMENT_OF_THE_HIGHBORN, 2s);
}
break;
case EVENT_SUNSORROW_WHISPER:
if (Creature* ambassador = me->FindNearestCreature(NPC_AMBASSADOR_SUNSORROW, 20.0f))
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
ambassador->AI()->Talk(SAY_SUNSORROW_WHISPER, player);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
bool LamentEvent;
ObjectGuid playerGUID;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_lady_sylvanas_windrunnerAI(creature);
}
};
/*######
## npc_highborne_lamenter
######*/
class npc_highborne_lamenter : public CreatureScript
{
public:
npc_highborne_lamenter() : CreatureScript("npc_highborne_lamenter") { }
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_highborne_lamenterAI(creature);
}
struct npc_highborne_lamenterAI : public ScriptedAI
{
npc_highborne_lamenterAI(Creature* creature) : ScriptedAI(creature) { }
uint32 EventMoveTimer;
uint32 EventCastTimer;
bool EventMove;
bool EventCast;
void Reset() override
{
EventMoveTimer = 10000;
EventCastTimer = 17500;
EventMove = true;
EventCast = true;
}
void JustEngagedWith(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override
{
if (EventMove)
{
if (EventMoveTimer <= diff)
{
me->SetDisableGravity(true);
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetDistance(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW) / (5000 * 0.001f));
me->SetPosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation());
EventMove = false;
}
else EventMoveTimer -= diff;
}
if (EventCast)
{
if (EventCastTimer <= diff)
{
DoCast(me, SPELL_HIGHBORNE_AURA);
EventCast = false;
}
else EventCastTimer -= diff;
}
}
};
};
/*######
## npc_parqual_fintallas
######*/
enum ParqualFintallas
{
SPELL_MARK_OF_SHAME = 6767,
QUEST_ID_TEST_OF_LORE = 6628,
GOSSIP_MENU_ID_TEST_OF_LORE = 4764,
GOSSIP_TEXTID_PARQUAL_FINTALLAS = 5821,
GOSSIP_TEXTID_TEST_OF_LORE = 5822,
};
class npc_parqual_fintallas : public CreatureScript
{
public:
npc_parqual_fintallas() : CreatureScript("npc_parqual_fintallas") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
CloseGossipMenuFor(player);
creature->CastSpell(player, SPELL_MARK_OF_SHAME, false);
}
if (action == GOSSIP_ACTION_INFO_DEF + 2)
{
CloseGossipMenuFor(player);
player->AreaExploredOrEventHappens(6628);
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
{
player->PrepareQuestMenu(creature->GetGUID());
}
if (player->GetQuestStatus(QUEST_ID_TEST_OF_LORE) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_MARK_OF_SHAME))
{
AddGossipItemFor(player, GOSSIP_MENU_ID_TEST_OF_LORE, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
AddGossipItemFor(player, GOSSIP_MENU_ID_TEST_OF_LORE, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
AddGossipItemFor(player, GOSSIP_MENU_ID_TEST_OF_LORE, 3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, GOSSIP_TEXTID_TEST_OF_LORE, creature->GetGUID());
}
else
{
SendGossipMenuFor(player, GOSSIP_TEXTID_PARQUAL_FINTALLAS, creature->GetGUID());
}
return true;
}
};
/*######
## ALLIANCE
#######*/
enum WrynnMisc
{
// Creatures
NPC_WRYNN = 32401,
// Texts
WRYNN_SAY_PREP_1 = 0,
WRYNN_SAY_PREP_2 = 1,
WRYNN_SAY_PREP_3 = 2,
WRYNN_SAY_PREP_4 = 3,
WRYNN_SAY_PREP_5 = 4,
WRYNN_SAY_PREP_6 = 5,
WRYNN_SAY_SEWERS_1 = 6,
WRYNN_SAY_SEWERS_2 = 7,
WRYNN_SAY_SEWERS_3 = 8,
WRYNN_SAY_SEWERS_4 = 9,
WRYNN_SAY_APO_1 = 10,
WRYNN_SAY_APO_2 = 11,
WRYNN_SAY_APO_3 = 12,
WRYNN_SAY_APO_4 = 13,
WRYNN_SAY_APO_5 = 14,
WRYNN_SAY_APO_6 = 15,
WRYNN_SAY_APO_7 = 16,
WRYNN_SAY_APO_8 = 17,
WRYNN_SAY_APO_9 = 18,
WRYNN_SAY_APO_10 = 19,
WRYNN_SAY_APO_11 = 20,
WRYNN_SAY_APO_12 = 21,
WRYNN_SAY_THRONE_1 = 22,
WRYNN_SAY_THRONE_2 = 23,
WRYNN_SAY_THRONE_3 = 24,
WRYNN_SAY_THRONE_4 = 25,
WRYNN_SAY_THRONE_5 = 26,
WRYNN_SAY_THRONE_6 = 27,
WRYNN_SAY_THRONE_7 = 28,
WRYNN_SAY_THRONE_8 = 29,
WRYNN_SAY_THRONE_9 = 30,
// Spells
SPELL_WHIRLWIND = 41056,
SPELL_WRYNN_BUFF = 60964,
SPELL_HEROIC_LEAP = 57793,
// Events
EVENT_WHIRLWIND = 1,
EVENT_HEROIC_LEAP = 2,
EVENT_AGGRO_JAINA = 3,
EVENT_WRYNN_BUFF = 4
};
enum JainaMisc
{
// Creatures
NPC_JAINA = 32402,
// Texts
JAINA_SAY_SEWERS_1 = 0,
JAINA_SAY_APO_1 = 1,
JAINA_SAY_THRONE_1 = 2,
JAINA_SAY_THRONE_2 = 3,
JAINA_SAY_THRONE_3 = 4,
// Spells
SPELL_FIREBALL = 20692,
SPELL_BLIZZARD = 20680,
SPELL_ELEMENTALS = 20681,
SPELL_DEEPFREEZE = 61224,
SPELL_JAINA_BUFF = 61011,
// Events
EVENT_FIREBALL = 1,
EVENT_BLIZZARD = 2,
EVENT_ELEMENTAL = 3
};
/*######
## HORDE
#######*/
enum ThrallMisc
{
// Creatures
NPC_THRALL = 32518,
// Gossips
GOSSIP_THRALL = 60193,
// Texts
THRALL_SAY_THRONE_A_1 = 0,
THRALL_SAY_THRONE_A_2 = 1,
THRALL_SAY_PREP_1 = 2,
THRALL_SAY_PREP_2 = 3,
THRALL_SAY_PREP_3 = 4,
THRALL_SAY_PREP_4 = 5,
THRALL_SAY_PREP_5 = 6,
THRALL_SAY_PREP_6 = 7,
THRALL_SAY_PREP_7 = 8,
THRALL_SAY_PREP_8 = 9,
THRALL_SAY_COURTYARD_1 = 10,
THRALL_SAY_COURTYARD_2 = 11,
THRALL_SAY_COURTYARD_3 = 12,
THRALL_SAY_COURTYARD_4 = 13,
THRALL_SAY_COURTYARD_5 = 14,
THRALL_SAY_ELEVATOR_1 = 15,
THRALL_SAY_ELEVATOR_2 = 16,
THRALL_SAY_ELEVATOR_3 = 17,
THRALL_SAY_SANCTUM_1 = 18,
THRALL_SAY_SANCTUM_2 = 19,
THRALL_SAY_SANCTUM_3 = 20,
THRALL_SAY_SANCTUM_4 = 21,
THRALL_SAY_SANCTUM_5 = 22,
THRALL_SAY_SANCTUM_6 = 23,
THRALL_SAY_SANCTUM_7 = 24,
THRALL_SAY_THRONE_1 = 25,
THRALL_SAY_THRONE_2 = 26,
THRALL_SAY_THRONE_3 = 27,
THRALL_SAY_THRONE_4 = 28,
THRALL_SAY_THRONE_5 = 29,
THRALL_SAY_THRONE_6 = 30,
THRALL_SAY_THRONE_7 = 31,
THRALL_SAY_THRONE_8 = 32,
THRALL_SAY_THRONE_9 = 33,
THRALL_SAY_THRONE_10 = 34,
THRALL_SAY_THRONE_11 = 35,
// Sounds
SOUND_THRALL_1 = 16212,
SOUND_THRALL_2 = 16214,
// Spells
SPELL_THRALL_BUFF = 64670,
SPELL_TIDAL_WAVE = 59635,
SPELL_TIDAL_WAVE_SUMMON = 59627,
SPELL_TIDAY_FURY = 59631,
SPELL_TIDAY_FURY_EFFECT = 59629,
SPELL_CALL_OF_AIR = 59898,
SPELL_CYCLONE_FALL = 59892,
SPELL_CALL_OF_EARTH = 60207,
SPELL_PORTAL_COLLAPSE = 60285,
SPELL_TELEPORT_SPAWN_VISUAL = 60427,
SPELL_SUMMONED_DEMON = 7741,
SPELL_DEEP_FREEZE = 60511,
SPELL_GREATER_MASS_TELEPORT = 60516,
SPELL_WATER_REVENANT_ENTRANCE = 55760,
SPELL_TELEPORT_OG = 60699,
// Combatspells
SPELL_CHAIN_LIGHTNING = 59517,
SPELL_LAVA_BURST = 59519,
SPELL_THUNDER = 59507,
SPELL_HEROIC_VANGUARD = 59506,
// Events
EVENT_CHAIN_LIGHTNING = 1,
EVENT_LAVA_BURST = 2,
EVENT_THUNDER = 3,
EVENT_AGGRO_SYLVANAS = 4,
EVENT_THRALL_BUFF = 5,
// Creatures
NPC_WARSONG_BATTLEGUARD = 31739,
NPC_VORTEX = 31782,
NPC_TIDAL_WAVE = 31765,
NPC_WHIRLWIND = 31688,
NPC_CAVE_DUMMY = 32200,
NPC_SLINGER_TRIGGER = 31577,
NPC_OVERLORD_SAURFANG = 32315,
NPC_DISTANT_VOICE = 32277,
NPC_PLAGUE_TRIGGER = 31576,
NPC_BLIGHT_ABBERATION = 31844,
// Gameobjects
GO_BLOCKED_PASSAGE = 194935,
GO_HORDE_BANNER = 194004,
GO_PORTAL_ORGRIMMAR = 193427,
// Mounts
MODEL_WHITE_WULF = 14575
};
enum SlyvanasMisc
{
// Creatures
NPC_SYLVANAS = 32365,
// Texts
SYLVANAS_SAY_COURTYARD_1 = 0,
SYLVANAS_SAY_ELEVATOR_1 = 1,
SYLVANAS_SAY_SANCTUM_1 = 2,
SYLVANAS_SAY_SANCTUM_2 = 3,
SYLVANAS_SAY_SANCTUM_3 = 4,
SYLVANAS_SAY_SANCTUM_4 = 5,
SYLVANAS_SAY_SANCTUM_5 = 6,
SYLVANAS_SAY_THRONE_1 = 7,
// Spells
SPELL_SYLVANAS_BUFF = 59756,
SPELL_SHRIEK_OF_HIGHBORN = 59514,
SPELL_LEAP_TO_PLATFORM = 56347,
// Events
EVENT_SHRIEK_OF_HIGHBORN = 1,
EVENT_SYLVANAS_BUFF = 6,
// Mounts
MODEL_SKELETON_MOUNT = 10721
};
enum SaurfangMisc
{
// Texts
SAY_SAURFANG_ARRIVAL_1 = 0,
SAY_SAURFANG_ARRIVAL_2 = 1,
SAY_SAURFANG_ARRIVAL_3 = 2
};
/*######
## ENEMY
#######*/
enum BlightWormMisc
{
// Creatures
NPC_BLIGHTWORM = 32483,
// Spells
SPELL_INGEST = 61123,
SPELL_INGEST_TRIGGER = 61124,
SPELL_BLIGHT_BREATH = 61125,
// Events
EVENT_INFEST = 1,
EVENT_BLIGHT_BREATH = 2
};
enum PutressMisc
{
// Creatures
NPC_PUTRESS = 31530,
NPC_EXPERIMENT = 32519,
NPC_GENERATOR = 36212,
// Spells
SPELL_BLIGHT_EMPOWERMENT = 59449,
SPELL_BLIGHT_OVERLOAD = 61181,
SPELL_BLIGHT_BARREL = 59460,
SPELL_UNHOLY_FRENZY = 60300,
SPELL_PUTRESS_CASTING_STATE = 59447,
// Texts
PUTRESS_SAY_1 = 0,
PUTRESS_SAY_2 = 1,
PUTRESS_SAY_3 = 2,
PUTRESS_SAY_4 = 3,
PUTRESS_SAY_5 = 4,
PUTRESS_SAY_6 = 5,
PUTRESS_SAY_7 = 6,
PUTRESS_SAY_8 = 7,
// Sounds
SOUND_PUTRESS = 16920,
};
enum KhanokMisc
{
// Creatures
NPC_KHANOK = 32511
};
enum ValimathrasMisc
{
// Creatures
NPC_VARIMATHRAS = 31565,
NPC_VARIMATHRAS_PORTAL = 31811,
// Texts
SAY_VALIMATHRAS_INTRO_0 = 0,
SAY_VALIMATHRAS_INTRO_1 = 1,
SAY_VALIMATHRAS_INTRO_2 = 2,
SAY_VALIMATHRAS_INNER_SANKTUM_0 = 3,
SAY_VALIMATHRAS_INNER_SANKTUM_1 = 4,
SAY_CLOSE_DOOR = 5,
SAY_THRONE_1 = 6,
SAY_THRONE_2 = 7,
SAY_THRONE_3 = 8,
SAY_THRONE_4 = 9,
SAY_THRONE_5 = 10,
SAY_THRONE_6 = 11,
SAY_VALIMATHRAS_ATTACK = 12,
// Spells
SPELL_VALIMATHRAS_PORTAL = 68424,
SPELL_CARION_SWARM = 59434,
SPELL_DRAIN_LIFE = 17238,
SPELL_MIGHT_OF_VARIMATHRAS = 59424,
SPELL_SHADOW_BOLT_VOLLEY = 20741,
SPELL_AURA_OF_VARIMATHRAS = 60289,
SPELL_LEGION_PORTAL = 59680,
SPELL_OPENING_LEGION_PORTALS = 60224,
};
enum TrashMisc
{
// Creatures
NPC_DREADLORD = 32391,
NPC_GUARDIAN = 32390,
NPC_CHEMIST = 32395,
NPC_BETRAYER = 32394,
NPC_FELBEAST = 32392,
NPC_DOCTOR = 32397,
NPC_COLLABORATOR = 32396,
NPC_SW_SOLDIER = 32387,
NPC_HORDE_SOLDIER = 32510,
NPC_HORDE_GUARD = 31739,
// Horde
NPC_TREACHEROUS_GUARDIAN_H = 31532,
NPC_DREADLORD_H = 31531,
NPC_FELBEAST_H = 31528,
NPC_MARAUDER_H = 31527,
NPC_BETRAYER_H = 31529,
NPC_CHEMIST_H = 31482,
NPC_COLLABORATOR_H = 31524,
NPC_DOCTOR_H = 31516,
NPC_DOOMGUARD_PILLARGER = 32159,
NPC_BLIGHT_SLINGER = 31526,
NPC_BLIGHT_SPREADER = 31831,
NPC_FELGUARD_MORADEUR = 32393,
NPC_LEGION_OVERLORD = 32271,
NPC_LEGION_INVADER = 32269,
NPC_LEGION_DREADWHISPER = 32270,
// Texts
SAY_BURN_UC = 0,
SAY_PUTRESS_ANGER = 1,
SAY_FOR_THE_HORDE = 2
};
enum QuestMisc
{
QUEST_BATTLE_A = 13377,
QUEST_BATTLE_H = 13267,
SPELL_PHASING_HORDE = 59062,
NPC_VOICE = 32277,
VOICE_SAY_THRONE = 0,
WAVE_MAXCOUNT = 12,
GENERATOR_MAXCOUNT = 5,
ALLIANCE_FORCE_MAXCOUNT = 6,
HORDE_FORCE_MAXCOUNT = 6,
WAVE_COURTYARD_FIGHT = 9,
ZONE_TIRISFAL = 85,
ZONE_UNDERCITY = 1497
};
struct LocationXYZO {
float x, y, z, o;
};
static LocationXYZO AllianceSpawn[] =
{
{ 1603.97f, 718.02f, 65.10f, 0 }, // guardian // sewers
{ 1604.78f, 657.22f, 40.80f, 0 }, // wave 1
{ 1632.13f, 649.19f, 30.67f, 0 }, // wave 2
{ 1683.66f, 590.37f, -8.59f, 0 }, // wave 3
{ 1665.51f, 543.32f, -13.23f, 0 }, // wave 4
{ 1684.25f, 542.06f, -11.99f, 0 },
{ 1680.86f, 596.73f, -6.37f, 0 },
{ 1676.41f, 558.28f, -18.46f, 0 }, // Blightworm
{ 1685.16f, 620.41f, 5.74f, 0 }, // soldiers
{ 0.0f, 0.0f, 0.0f, 0 }, // trash wave
{ 1500.03f, 409.59f, -62.18f, 0 }, // guardians
{ 1444.25f, 453.86f, -70.48f, 0 }, // dreadlords
{ 1432.43f, 403.20f, -85.26f, 0 }, // putress
{ 1456.51f, 417.55f, -84.95f, 0 }, // experiment
{ 1415.38f, 377.54f, -84.95f, 0 }, // experiment
{ 1422.69f, 446.36f, -76.22f, 0 }, // experiment
{ 1386.19f, 412.01f, -77.17f, 0 }, // experiment
{ 1300.75f, 347.39f, -65.02f, 0 }, // thrall
{ 1296.79f, 348.37f, -65.02f, 0 }, // sylvanas
{ 1293.46f, 351.19f, -65.02f, 0 }, // horde soldier 32510
{ 1293.79f, 347.75f, -65.02f, 0 },
{ 1296.24f, 345.34f, -65.02f, 0 },
{ 1300.41f, 344.47f, -65.02f, 0 },
{ 1303.96f, 345.26f, -65.02f, 0 },
{ 1305.43f, 348.06f, -65.02f, 0 },
{ 1306.92f, 390.59f, -64.33f, 4.472f }, // aliance soldiers
{ 1311.03f, 390.10f, -64.19f, 4.472f },
{ 1315.31f, 388.98f, -64.18f, 4.472f },
{ 1316.38f, 392.82f, -63.32f, 4.472f },
{ 1311.93f, 394.38f, -63.25f, 4.472f },
{ 1307.92f, 395.53f, -63.24f, 4.472f },
};
static LocationXYZO AllianceWP[] =
{
{ 1737.06f, 734.176f, 48.8f, 0 }, // Jaina sewers UNUSED
{ 1682.92f, 730.89f, 76.84f, 0 }, // UNUSED
{ 1662.18f, 540.67f, -11.64f, 0.60f }, // soldiers
{ 1676.45f, 544.81f, -16.45f, 2.23f },
{ 1687.14f, 555.37f, -16.62f, 2.35f },
{ 1666.22f, 477.69f, -11.89f, 2.14f },
{ 1594.92f, 422.44f, -46.38f, 0 }, // jaina balcony
{ 1423.19f, 412.73f, -84.60f, 0 }, // jaina putress
{ 1311.93f, 394.38f, -63.25f, 0 }, // jaina throne room wait
{ 1300.75f, 347.39f, -65.02f, 0 }, // jaina throne room
};
static LocationXYZO HordeSpawn[] =
{
{ 1581.94f, 383.22f, -62.22f, 0 } // Khanok
};
static LocationXYZO ThrallSpawn[] =
{
// Vortex
{ 1880.0001f, 237.8242f, 59.472f, 3.060f },
// NPC_DOCTOR_H
{ 1808.29f, 264.223f, 65.3997f, 5.41411f },
{ 1792.05f, 282.213f, 70.3996f, 5.46674f },
{ 1798.03f, 197.815f, 70.3997f, 0.550926f },
// NPC_CHEMIST_H
{ 1806.59f, 266.874f, 65.3997f, 5.528f },
{ 1808.18f, 211.038f, 65.3996f, 0.799897f },
{ 1803.01f, 213.037f, 65.3996f, 0.496734f },
{ 1803.01f, 213.037f, 65.3996f, 0.496734f },
{ 1809.58f, 197.105f, 70.3999f, 0.593338f },
{ 1816.2f, 196.655f, 70.3999f, 0.820318f },
{ 1791.75f, 197.267f, 70.3999f, 0.584698f },
{ 1814.45f, 279.218f, 70.3998f, 5.52878f },
{ 1793.98f, 280.346f, 70.3996f, 5.50522f },
// NPC_TREACHEROUS_GUARDIAN_H
{ 1806.31f, 213.05f, 65.3998f, 0.52893f },
{ 1813.54f, 197.01f, 70.3999f, 0.807745f },
{ 1789.15f, 197.6f, 70.3999f, 0.367921f },
{ 1804.79f, 263.79f, 65.3998f, 5.49265f },
{ 1818.12f, 280.6f, 70.3997f, 5.59475f },
{ 1790.19f, 279.868f, 70.3997f, 5.77539f },
// NPC_BLIGHT_SLINGER
{ 1827.64f, 196.716f, 70.3996f, 1.61907f },
{ 1778.47f, 195.17f, 70.3996f, 0.989177f },
{ 1826.86f, 280.42f, 70.3997f, 4.69234f },
{ 1779.52f, 280.479f, 70.3996f, 5.37171f },
// NPC_VARIMATHRAS
{ 1810.926f, 236.826f, 62.753f, 0.148f },
// NPC_VARIMATHRAS_PORTAL
{ 1805.194f, 235.725f, 65.173f, 0.334f },
// NPC_TREACHEROUS_GUARDIAN_H
{ 1753.151f, 238.632f, 61.372f, 0.049f },
// NPC_DOCTOR_H
{ 1785.647f, 212.416f, 59.686f, 1.663f },
// NPC_CHEMIST_H
{ 1784.802f, 265.842f, 59.458f, 4.722f },
// NPC_BLIGHT_ABBERATION
{ 1805.753f, 285.499f, 70.399f, 4.691f },
// NPC_WARSONG_BATTLEGUARD
{ 1835.734f, 261.468f, 59.901f, 3.720f },
{ 1821.705f, 256.014f, 60.016f, 3.512f },
{ 1837.801f, 216.490f, 60.105f, 2.381f },
{ 1826.564f, 227.173f, 60.198f, 2.381f },
{ 1804.952f, 199.451f, 70.399f, 1.478f },
{ 1805.011f, 211.147f, 65.399f, 1.607f },
{ 1805.447f, 277.378f, 70.400f, 4.627f },
{ 1805.389f, 265.287f, 65.399f, 4.718f },
// GO_HORDE_BANNER
{ 1750.697f, 232.644f, 64.748f, 6.151f },
{ 1750.706f, 245.729f, 65.585f, 0.009f },
{ 1737.508f, 239.323f, 62.641f, 0.054f },
{ 1634.253f, 226.927f, 62.592f, 0.983f },
{ 1628.978f, 231.074f, 62.592f, 0.411f },
{ 1589.801f, 236.328f, 60.149f, 0.157f },
{ 1589.135f, 243.569f, 60.149f, 5.887f },
// NPC_WARSONG_BATTLEGUARD
{ 1590.156f, 243.612f, 60.151f, 5.159f },
{ 1631.783f, 249.797f, 62.591f, 5.523f },
// NPC_CAVE_BUNNY
{ 1543.961548f, 240.997314f, 52.765247f, 4.885232f },
{ 1543.961548f, 240.997314f, 45.870247f, 4.885232f },
{ 1543.961548f, 240.997314f, 32.318245f, 4.885232f },
{ 1543.961548f, 240.997314f, 18.325245f, 4.885232f },
{ 1543.961548f, 240.997314f, 4.570244f, 4.885232f },
{ 1543.961548f, 240.997314f, -7.679757f, 4.885232f },
{ 1543.961548f, 240.997314f, -20.867758f, 4.885232f },
{ 1543.961548f, 240.997314f, -33.817757f, 4.885232f },
{ 1543.961548f, 240.997314f, -41.360523f, 4.885232f },
// Jumppoint Thrall
{ 1542.196f, 241.254f, -41.360f, 3.276f },
// Jumppoint Sylvanas
{ 1543.511f, 236.552f, -41.360f, 3.050f },
// NPC_WARSONG_BATTLEGUARD
{ 1527.904f, 206.368f, -43.058f, 1.179f },
{ 1534.110f, 216.822f, -43.058f, 4.569f },
// Undercity Top Trashpackspawn
{ 1585.577f, 240.465f, -52.150f, 3.193f },
// Undercity Buttom Trashpackspawn Left
{ 1528.291f, 269.948f, -62.178f, 0.672f },
// Undercity Buttom Trashpackspawn Right
{ 1618.600f, 302.468f, -62.177f, 0.466f },
// NPC_BLIGHT_ABBERATION Jump Location
{ 1805.845f, 251.430f, 60.587f, 4.722f },
// Valimathras Inner Sanctum Spawn
{ 1596.689f, 422.276f, -46.387f, 4.720f },
// Valimathras Inner Sanctum Portal Spawn
{ 1596.665f, 425.150f, -43.357f, 4.704f },
// NPC_KHANOK - Inner Sunktum Spawn Left
{ 1544.917f, 367.955f, -62.182f, 0.243f },
// NPC_KHANOK - Inner Sunktum Spawn Right
{ 1643.633f, 368.598f, -62.156f, 2.873f },
// NPC_KHANOK - Inner Sunktum Spawn Top
{ 1591.325f, 397.874f, -4.130f, 6.191f },
// NPC_KHANOK - Inner Sunktum Middle
{ 1573.400f, 398.450f, -65.862f, 5.618f },
// NPC_WARSONG_BATTLEGUARD - NPC_KHANOK WinSpawn
{ 1590.502f, 375.876f, -62.177f, 3.237f },
// Valimathras Room Preparation
// Stones
{ 1437.063f, 403.759f, -57.818f, 5.517f },
{ 1442.303f, 392.866f, -58.111f, 5.450552f },
{ 1447.207f, 397.880f, -58.102f, 5.403430f },
// Valimathras
{ 1290.323f, 315.996f, -57.320f, 1.322530f },
// Valimathras Portals
{ 1326.634f, 58.580f, -60.661907f, 4.008590f },
{ 1341.374f, 310.516f, -60.661415f, 2.838340f },
{ 1304.504f, 276.763f, -60.661442f, 1.833025f },
{ 1258.071f, 289.268f, -60.661636f, 0.741321f },
{ 1245.688f, 336.614f, -60.661243f, 5.983858f },
{ 1280.382f, 371.556f, -60.661404f, 4.931426f },
// Valimathras Trashspawn
{ 1325.059f, 332.652f, -65.027f, 2.186f },
{ 1270.474f, 350.982f, -65.027f, 0.034f },
{ 1805.753f, 285.499f, 70.399f, 4.691f }
};
#define GOSSIP_WRYNN "Reporting for duty, your majesty! Let the assault begin!"
#define GOSSIP_THRALL "I am ready, Warchief."
/*######
## ALLIANCE
#######*/
/*######
## npc_varian_wrynn
######*/
class npc_varian_wrynn : public CreatureScript
{
public:
npc_varian_wrynn() : CreatureScript("npc_varian_wrynn") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
CloseGossipMenuFor(player);
if (auto ai = CAST_AI(npc_varian_wrynn::npc_varian_wrynnAI, creature->AI()))
{
ai->Start(true, true, player->GetGUID());
if (Creature* jaina = GetClosestCreatureWithEntry(creature, NPC_JAINA, 50.0f))
ai->jainaGUID = jaina->GetGUID();
else
ai->jainaGUID.Clear();
ai->SetDespawnAtEnd(false);
ai->SetDespawnAtFar(false);
}
break;
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestStatus(QUEST_BATTLE_A) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_WRYNN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
struct npc_varian_wrynnAI : public npc_escortAI
{
npc_varian_wrynnAI(Creature* creature) : npc_escortAI(creature)
{
allianceGuardsGUID.clear();
}
bool bStepping;
bool summoned;
uint32 step;
uint32 phaseTimer;
uint32 whirlwindTimer;
ObjectGuid jainaGUID;
ObjectGuid putressGUID;
ObjectGuid blightWormGUID;
ObjectGuid khanokGUID;
ObjectGuid thrallGUID;
ObjectGuid sylvanasGUID;
ObjectGuid generatorGUID[GENERATOR_MAXCOUNT];
ObjectGuid allianceForcesGUID[ALLIANCE_FORCE_MAXCOUNT];
ObjectGuid hordeForcesGUID[HORDE_FORCE_MAXCOUNT];
GuidVector allianceGuardsGUID;
EventMap _events;
void EnterEvadeMode(EvadeReason /*why*/) override
{
me->GetThreatMgr().ClearAllThreat();
me->CombatStop(true);
me->SetLootRecipient(nullptr);
if (HasEscortState(STATE_ESCORT_ESCORTING))
{
AddEscortState(STATE_ESCORT_RETURNING);
ReturnToLastPoint();
}
else
{
me->GetMotionMaster()->MoveTargetedHome();
Reset();
}
}
void Reset() override
{
if (!HasEscortState(STATE_ESCORT_ESCORTING))
{
me->SetCorpseDelay(1);
me->SetRespawnTime(1);
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
bStepping = false;
step = 0;
phaseTimer = 0;
jainaGUID.Clear();
_events.ScheduleEvent(EVENT_WHIRLWIND, 5s);
_events.ScheduleEvent(EVENT_HEROIC_LEAP, 10s);
_events.ScheduleEvent(EVENT_AGGRO_JAINA, 2s);
_events.ScheduleEvent(EVENT_WRYNN_BUFF, 2s);
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
{
putress->DespawnOrUnsummon();
putressGUID.Clear();
}
if (Creature* blightWorm = ObjectAccessor::GetCreature(*me, blightWormGUID))
{
blightWorm->DespawnOrUnsummon();
blightWormGUID.Clear();
}
if (Creature* khanok = ObjectAccessor::GetCreature(*me, khanokGUID))
{
khanok->DespawnOrUnsummon();
khanokGUID.Clear();
}
if (Creature* thrall = ObjectAccessor::GetCreature(*me, thrallGUID))
{
thrall->DespawnOrUnsummon();
thrallGUID.Clear();
}
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasGUID))
{
sylvanas->DespawnOrUnsummon();
sylvanasGUID.Clear();
}
for (uint8 i = 0; i < GENERATOR_MAXCOUNT; ++i)
{
if (Creature* temp = ObjectAccessor::GetCreature(*me, generatorGUID[i]))
{
generatorGUID[i].Clear();
temp->DespawnOrUnsummon();
}
}
for (uint8 i = 0; i < ALLIANCE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = ObjectAccessor::GetCreature(*me, allianceForcesGUID[i]))
{
allianceForcesGUID[i].Clear();
temp->DespawnOrUnsummon();
}
}
for (ObjectGuid const& guid : allianceGuardsGUID)
if (Creature* temp = ObjectAccessor::GetCreature(*me, guid))
temp->DespawnOrUnsummon();
allianceGuardsGUID.clear();
for (uint8 i = 0; i < HORDE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = ObjectAccessor::GetCreature(*me, hordeForcesGUID[i]))
{
hordeForcesGUID[i].Clear();
temp->DespawnOrUnsummon();
}
}
}
}
void JustSummoned(Creature* summonedCreature) override
{
switch (summonedCreature->GetEntry())
{
case NPC_GENERATOR:
summonedCreature->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
summonedCreature->ApplySpellImmune(0, IMMUNITY_ID, SPELL_WRYNN_BUFF, true);
summonedCreature->ApplySpellImmune(0, IMMUNITY_ID, SPELL_THRALL_BUFF, true);
summonedCreature->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
break;
default:
break;
}
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
switch (summon->GetEntry())
{
case NPC_BLIGHTWORM:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_SEWERS_FIGHT_A, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_SEWERS_DONE_A, 1);
bStepping = true;
break;
case NPC_PUTRESS:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_APOTHECARIUM_FIGHT_A, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_APOTHECARIUM_DONE_A, 1);
bStepping = true;
break;
default:
break;
}
}
void UpdateWorldState(Map* map, uint32 id, uint32 state)
{
Map::PlayerList const& players = map->GetPlayers();
if (!players.IsEmpty())
{
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if (Player* player = itr->GetSource())
player->SendUpdateWorldState(id, state);
}
}
}
void SetHoldState(bool bOnHold)
{
SetEscortPaused(bOnHold);
}
void JumpToNextStep(uint32 uiTimer)
{
phaseTimer = uiTimer;
++step;
}
void SpawnWave(uint32 waveId)
{
switch (waveId)
{
case 0:
me->SummonCreature(NPC_GUARDIAN, AllianceSpawn[0].x, AllianceSpawn[0].y, AllianceSpawn[0].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
{
switch (urand(0, 12))
{
case 0:
me->SummonCreature(NPC_DREADLORD, AllianceSpawn[1].x + rand32() % 5, AllianceSpawn[1].y + rand32() % 5, AllianceSpawn[1].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
case 2:
case 3:
me->SummonCreature(NPC_DOCTOR, AllianceSpawn[1].x + rand32() % 5, AllianceSpawn[1].y + rand32() % 5, AllianceSpawn[1].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 4:
case 5:
case 6:
me->SummonCreature(NPC_FELBEAST, AllianceSpawn[1].x + rand32() % 5, AllianceSpawn[1].y + rand32() % 5, AllianceSpawn[1].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 7:
case 8:
case 9:
me->SummonCreature(NPC_BETRAYER, AllianceSpawn[1].x + rand32() % 5, AllianceSpawn[1].y + rand32() % 5, AllianceSpawn[1].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 10:
case 11:
case 12:
me->SummonCreature(NPC_COLLABORATOR, AllianceSpawn[1].x + rand32() % 5, AllianceSpawn[1].y + rand32() % 5, AllianceSpawn[1].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 2:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
{
switch (urand(0, 3))
{
case 0:
me->SummonCreature(NPC_COLLABORATOR, AllianceSpawn[2].x - rand32() % 5, AllianceSpawn[2].y - rand32() % 5, AllianceSpawn[2].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_DOCTOR, AllianceSpawn[2].x - rand32() % 5, AllianceSpawn[2].y - rand32() % 5, AllianceSpawn[2].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 2:
me->SummonCreature(NPC_FELBEAST, AllianceSpawn[2].x - rand32() % 5, AllianceSpawn[2].y - rand32() % 5, AllianceSpawn[2].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 3:
me->SummonCreature(NPC_BETRAYER, AllianceSpawn[2].x - rand32() % 5, AllianceSpawn[2].y - rand32() % 5, AllianceSpawn[2].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 3:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
{
switch (urand(0, 4))
{
case 0:
me->SummonCreature(NPC_GUARDIAN, AllianceSpawn[3].x - rand32() % 5, AllianceSpawn[3].y - rand32() % 5, AllianceSpawn[3].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
case 2:
me->SummonCreature(NPC_CHEMIST, AllianceSpawn[3].x - rand32() % 5, AllianceSpawn[3].y - rand32() % 5, AllianceSpawn[3].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 3:
case 4:
me->SummonCreature(NPC_DOCTOR, AllianceSpawn[3].x - rand32() % 5, AllianceSpawn[3].y - rand32() % 5, AllianceSpawn[3].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 4:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
{
switch (urand(0, 5))
{
case 0:
if (Unit* temp = me->SummonCreature(NPC_DOCTOR, AllianceSpawn[4].x - rand32() % 5, AllianceSpawn[4].y - rand32() % 5, AllianceSpawn[4].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
case 1:
if (Unit* temp = me->SummonCreature(NPC_CHEMIST, AllianceSpawn[4].x - rand32() % 5, AllianceSpawn[4].y - rand32() % 5, AllianceSpawn[4].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
case 2:
if (Unit* temp = me->SummonCreature(NPC_BETRAYER, AllianceSpawn[4].x - rand32() % 5, AllianceSpawn[4].y - rand32() % 5, AllianceSpawn[4].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
case 3:
if (Unit* temp = me->SummonCreature(NPC_DOCTOR, AllianceSpawn[5].x - rand32() % 5, AllianceSpawn[5].y - rand32() % 5, AllianceSpawn[5].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
case 4:
if (Unit* temp = me->SummonCreature(NPC_CHEMIST, AllianceSpawn[5].x - rand32() % 5, AllianceSpawn[5].y - rand32() % 5, AllianceSpawn[5].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
case 5:
if (Unit* temp = me->SummonCreature(NPC_BETRAYER, AllianceSpawn[5].x - rand32() % 5, AllianceSpawn[5].y - rand32() % 5, AllianceSpawn[5].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
}
}
break;
case 5:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
if (Unit* temp = me->SummonCreature(NPC_GUARDIAN, AllianceSpawn[6].x - rand32() % 5, AllianceSpawn[6].y - rand32() % 5, AllianceSpawn[6].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), false);
break;
case 6:
if (Unit* temp = me->SummonCreature(NPC_BLIGHTWORM, AllianceSpawn[7].x, AllianceSpawn[7].y, AllianceSpawn[7].z, TEMPSUMMON_MANUAL_DESPAWN))
{
blightWormGUID = temp->GetGUID();
temp->AddThreat(me, 100.0f);
me->AddThreat(temp, 100.0f);
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
temp->AddThreat(jaina, 100.0f);
jaina->AddThreat(temp, 100.0f);
}
}
if (Unit* temp = me->SummonCreature(NPC_KHANOK, HordeSpawn[0].x, HordeSpawn[0].y, HordeSpawn[0].z, TEMPSUMMON_MANUAL_DESPAWN))
{
khanokGUID = temp->GetGUID();
if (Creature* khanok = ObjectAccessor::GetCreature(*me, khanokGUID))
khanok->setDeathState(DeathState::JustDied);
}
if (Unit* temp = me->SummonCreature(NPC_PUTRESS, AllianceSpawn[12].x, AllianceSpawn[12].y, AllianceSpawn[12].z, TEMPSUMMON_MANUAL_DESPAWN))
{
putressGUID = temp->GetGUID();
temp->CastSpell(temp, SPELL_PUTRESS_CASTING_STATE);
}
for (uint8 i = 0; i < GENERATOR_MAXCOUNT; ++i)
{
switch (i)
{
case 0:
if (Unit* temp = me->SummonCreature(NPC_GENERATOR, 1433.142212f, 402.493835f, -80.515945f, TEMPSUMMON_MANUAL_DESPAWN))
{
generatorGUID[i] = temp->GetGUID();
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
temp->CastSpell(putress, SPELL_BLIGHT_EMPOWERMENT);
}
break;
case 1:
if (Unit* temp = me->SummonCreature(NPC_GENERATOR, 1428.677979f, 399.753418f, -79.141609f, TEMPSUMMON_MANUAL_DESPAWN))
{
generatorGUID[i] = temp->GetGUID();
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
temp->CastSpell(putress, SPELL_BLIGHT_EMPOWERMENT, false, 0, 0, generatorGUID[0]);
}
break;
case 2:
if (Unit* temp = me->SummonCreature(NPC_GENERATOR, 1425.163330f, 402.268951f, -79.299744f, TEMPSUMMON_MANUAL_DESPAWN))
{
generatorGUID[i] = temp->GetGUID();
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
temp->CastSpell(putress, SPELL_BLIGHT_EMPOWERMENT, false, 0, 0, generatorGUID[0]);
}
break;
case 3:
if (Unit* temp = me->SummonCreature(NPC_GENERATOR, 1427.323242f, 406.853088f, -78.195641f, TEMPSUMMON_MANUAL_DESPAWN))
{
generatorGUID[i] = temp->GetGUID();
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
temp->CastSpell(putress, SPELL_BLIGHT_EMPOWERMENT, false, 0, 0, generatorGUID[0]);
}
break;
case 4:
if (Unit* temp = me->SummonCreature(NPC_GENERATOR, 1432.465210f, 407.460022f, -81.689384f, TEMPSUMMON_MANUAL_DESPAWN))
{
generatorGUID[i] = temp->GetGUID();
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
temp->CastSpell(putress, SPELL_BLIGHT_EMPOWERMENT, false, 0, 0, generatorGUID[0]);
}
break;
}
}
break;
case 7:
if (Unit* temp = me->SummonCreature(NPC_SW_SOLDIER, AllianceSpawn[8].x, AllianceSpawn[8].y, AllianceSpawn[8].z, 0, TEMPSUMMON_TIMED_DESPAWN, 90000))
{
allianceGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePath(NPC_SW_SOLDIER * 10, false);
}
if (Unit* temp = me->SummonCreature(NPC_SW_SOLDIER, AllianceSpawn[8].x, AllianceSpawn[8].y, AllianceSpawn[8].z, 0, TEMPSUMMON_TIMED_DESPAWN, 90000))
{
allianceGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePath((NPC_SW_SOLDIER * 10) + 1, false);
}
if (Unit* temp = me->SummonCreature(NPC_SW_SOLDIER, AllianceSpawn[8].x, AllianceSpawn[8].y, AllianceSpawn[8].z, 0, TEMPSUMMON_TIMED_DESPAWN, 90000))
{
allianceGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePath((NPC_SW_SOLDIER * 10) + 2, false);
}
if (Unit* temp = me->SummonCreature(NPC_SW_SOLDIER, AllianceSpawn[8].x, AllianceSpawn[8].y, AllianceSpawn[8].z, 0, TEMPSUMMON_TIMED_DESPAWN, 90000))
{
allianceGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePath((NPC_SW_SOLDIER * 10) + 3, false);
}
break;
case 8:
break;
case 9:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
me->SummonCreature(NPC_GUARDIAN, AllianceSpawn[10].x + rand32() % 13, AllianceSpawn[10].y + rand32() % 13, AllianceSpawn[10].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 10:
if (Unit* temp = me->SummonCreature(NPC_DREADLORD, AllianceSpawn[11].x, AllianceSpawn[11].y, AllianceSpawn[11].z, TEMPSUMMON_DEAD_DESPAWN))
{
temp->GetMotionMaster()->MovePath(NPC_DREADLORD * 10, false);
temp->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
temp->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
}
break;
case 11:
for (uint8 i = 0; i < WAVE_MAXCOUNT; ++i)
{
switch (urand(0, 3))
{
case 0:
if (Unit* temp = me->SummonCreature(NPC_EXPERIMENT, AllianceSpawn[13].x + rand32() % 5, AllianceSpawn[13].y + rand32() % 5, AllianceSpawn[13].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
break;
case 1:
if (Unit* temp = me->SummonCreature(NPC_EXPERIMENT, AllianceSpawn[14].x + rand32() % 5, AllianceSpawn[14].y + rand32() % 5, AllianceSpawn[14].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
break;
case 2:
if (Unit* temp = me->SummonCreature(NPC_EXPERIMENT, AllianceSpawn[15].x + rand32() % 5, AllianceSpawn[15].y + rand32() % 5, AllianceSpawn[15].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
break;
case 3:
if (Unit* temp = me->SummonCreature(NPC_EXPERIMENT, AllianceSpawn[16].x + rand32() % 5, AllianceSpawn[16].y + rand32() % 5, AllianceSpawn[16].z, TEMPSUMMON_DEAD_DESPAWN))
temp->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
break;
}
}
break;
case 12:
if (Creature* temp = me->SummonCreature(NPC_THRALL, AllianceSpawn[17].x, AllianceSpawn[17].y, AllianceSpawn[17].z, TEMPSUMMON_MANUAL_DESPAWN))
{
thrallGUID = temp->GetGUID();
temp->SetReactState(REACT_PASSIVE);
temp->SetImmuneToAll(true);
temp->CastSpell(temp, SPELL_THRALL_BUFF);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
}
if (Creature* temp = me->SummonCreature(NPC_SYLVANAS, AllianceSpawn[18].x, AllianceSpawn[18].y, AllianceSpawn[18].z, TEMPSUMMON_MANUAL_DESPAWN))
{
sylvanasGUID = temp->GetGUID();
temp->SetReactState(REACT_PASSIVE);
temp->SetImmuneToAll(true);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
}
for (uint8 i = 0; i < HORDE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = me->SummonCreature(NPC_HORDE_SOLDIER, AllianceSpawn[i + 19].x, AllianceSpawn[i + 19].y, AllianceSpawn[i + 19].z, TEMPSUMMON_MANUAL_DESPAWN))
{
hordeForcesGUID[i] = temp->GetGUID();
temp->SetReactState(REACT_PASSIVE);
temp->SetImmuneToAll(true);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
}
}
break;
case 13:
for (uint8 i = 0; i < ALLIANCE_FORCE_MAXCOUNT; ++i)
{
if (Unit* temp = me->SummonCreature(NPC_SW_SOLDIER, AllianceSpawn[i + 25].x, AllianceSpawn[i + 25].y, AllianceSpawn[i + 25].z, AllianceSpawn[i + 25].o, TEMPSUMMON_MANUAL_DESPAWN))
{
allianceForcesGUID[i] = temp->GetGUID();
temp->SetImmuneToAll(true);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
}
}
break;
}
}
void WaypointReached(uint32 waypointId) override
{
switch (waypointId)
{
case 0:
SetHoldState(true);
bStepping = true;
break;
case 2:
SetHoldState(true);
bStepping = true;
break;
case 38:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->Clear();
jaina->SetImmuneToNPC(false);
jaina->SetReactState(REACT_AGGRESSIVE);
}
SetHoldState(true);
bStepping = true;
break;
case 45:
SetHoldState(true);
bStepping = true;
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->Clear();
jaina->GetMotionMaster()->MovePoint(0, AllianceWP[6].x, AllianceWP[6].y, AllianceWP[6].z);
}
break;
case 46:
SetHoldState(true);
bStepping = true;
break;
case 48:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_2);
if (Player* player = GetPlayerForEscort())
player->PlayDirectSound(SOUND_PUTRESS, player);
break;
case 50:
SetHoldState(true);
bStepping = true;
break;
case 63:
SetHoldState(true);
bStepping = true;
break;
case 65:
SetHoldState(true);
bStepping = true;
break;
case 66:
SetHoldState(true);
bStepping = true;
break;
case 87:
SetHoldState(true);
bStepping = true;
break;
case 88:
SetHoldState(true);
bStepping = true;
break;
}
}
void UpdateAI(uint32 diff) override
{
npc_escortAI::UpdateAI(diff);
if (bStepping)
{
if (phaseTimer <= diff)
{
switch (step)
{
//Preparation
case 0:
me->setActive(true);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_MANHUNT_COUNTDOWN_A, 1);
Talk(WRYNN_SAY_PREP_1);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 1:
Talk(WRYNN_SAY_PREP_2);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 2:
Talk(WRYNN_SAY_PREP_3);
JumpToNextStep(20 * IN_MILLISECONDS);
break;
case 3:
Talk(WRYNN_SAY_PREP_4);
JumpToNextStep(20 * IN_MILLISECONDS);
break;
case 4:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_MANHUNT_COUNTDOWN_A, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_MANHUNT_STARTS_A, 1);
Talk(WRYNN_SAY_PREP_5);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 5:
DoCast(me, SPELL_WRYNN_BUFF);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 6:
Talk(WRYNN_SAY_PREP_6);
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 7:
SetEscortPaused(false);
JumpToNextStep(1.5 * IN_MILLISECONDS);
break;
case 8:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->MovePath(NPC_JAINA * 10, false);
jaina->setActive(true);
}
bStepping = false;
JumpToNextStep(0);
break;
//Sewers
case 9:
Talk(WRYNN_SAY_SEWERS_1);
SpawnWave(0);
SpawnWave(1);
SpawnWave(2);
SpawnWave(3);
JumpToNextStep(9500);
break;
case 10:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
jaina->AI()->Talk(JAINA_SAY_SEWERS_1);
JumpToNextStep(2 * IN_MILLISECONDS);
break;
case 11:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
jaina->AI()->DoCast(SPELL_JAINA_BUFF);
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 12:
SetEscortPaused(false);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_MANHUNT_STARTS_A, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_SEWERS_FIGHT_A, 1);
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 13:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->MoveFollow(me, 5, PET_FOLLOW_ANGLE);
jaina->SetReactState(REACT_AGGRESSIVE);
jaina->SetFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE);
}
bStepping = false;
JumpToNextStep(0);
break;
case 14:
Talk(WRYNN_SAY_SEWERS_2);
JumpToNextStep(3.5 * IN_MILLISECONDS);
break;
case 15:
SpawnWave(4);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 16:
SpawnWave(5);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 17:
SpawnWave(4);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 18:
SpawnWave(4);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 19:
SpawnWave(5);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 20:
SpawnWave(6);
bStepping = false;
JumpToNextStep(0);
break;
case 21:
Talk(WRYNN_SAY_SEWERS_3);
SpawnWave(7);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 22:
Talk(WRYNN_SAY_SEWERS_4);
SetRun(false);
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->Clear();
jaina->GetMotionMaster()->MoveFollow(me, 1, 0);
}
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 23:
bStepping = false;
SetEscortPaused(false);
JumpToNextStep(0);
break;
//Apothecarium
case 24:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
jaina->AI()->Talk(JAINA_SAY_APO_1);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 25:
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
break;
case 26:
me->SetStandState(UNIT_STAND_STATE_KNEEL);
me->SetTarget(khanokGUID);
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 27:
Talk(WRYNN_SAY_APO_1);
JumpToNextStep(12 * IN_MILLISECONDS);
break;
case 28:
Talk(WRYNN_SAY_APO_2);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 29:
Talk(WRYNN_SAY_APO_3);
JumpToNextStep(1.5 * IN_MILLISECONDS);
break;
case 30:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_APOTHECARIUM_FIGHT_A, 1);
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_1);
if (Player* player = GetPlayerForEscort())
player->PlayDirectSound(SOUND_PUTRESS, player);
SpawnWave(9);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 31:
SetRun(true);
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
jaina->GetMotionMaster()->MoveFollow(me, 1, 0);
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
break;
case 32:
Talk(WRYNN_SAY_APO_4);
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 33:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 34:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 35:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 36:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 37:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 38:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 39:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 40:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 41:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 42:
SpawnWave(10);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 43:
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
break;
case 44:
Talk(WRYNN_SAY_APO_5);
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->Clear();
jaina->GetMotionMaster()->MovePoint(0, AllianceWP[7].x, AllianceWP[7].y, AllianceWP[7].z, false);
}
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 45:
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
break;
case 46:
Talk(WRYNN_SAY_APO_6);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 47:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_3);
SpawnWave(11);
JumpToNextStep(7.5 * IN_MILLISECONDS);
break;
case 48:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_4);
JumpToNextStep(7.5 * IN_MILLISECONDS);
break;
case 49:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_5);
SpawnWave(11);
JumpToNextStep(7.5 * IN_MILLISECONDS);
break;
case 50:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_6);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 51:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
putress->AI()->Talk(PUTRESS_SAY_7);
SpawnWave(11);
JumpToNextStep(7.5 * IN_MILLISECONDS);
break;
case 52:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
{
putress->AI()->Talk(PUTRESS_SAY_8);
putress->AI()->DoCast(SPELL_BLIGHT_OVERLOAD);
}
JumpToNextStep(0.5 * IN_MILLISECONDS);
break;
case 53:
if (Creature* putress = ObjectAccessor::GetCreature(*me, putressGUID))
{
putress->SetImmuneToAll(false);
putress->AddThreat(me, 100.0f);
me->AddThreat(putress, 100.0f);
putress->RemoveAura(SPELL_PUTRESS_CASTING_STATE);
}
bStepping = false;
JumpToNextStep(0);
break;
case 54:
Talk(WRYNN_SAY_APO_7);
SetRun(false);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 55:
if (ObjectAccessor::GetCreature(*me, putressGUID))
me->SetTarget(putressGUID);
Talk(WRYNN_SAY_APO_8);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 56:
Talk(WRYNN_SAY_APO_9);
me->RemoveStandFlags(UNIT_STAND_STATE_KNEEL);
me->SetStandFlags(UNIT_STAND_STATE_STAND);
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
break;
case 57:
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 58:
Talk(WRYNN_SAY_APO_10);
JumpToNextStep(7.5 * IN_MILLISECONDS);
break;
case 59:
Talk(WRYNN_SAY_APO_11);
JumpToNextStep(7.5 * IN_MILLISECONDS);
break;
case 60:
Talk(WRYNN_SAY_APO_12);
SpawnWave(12); // thrall sylvanas horde soldiers
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 61:
if (Creature* thrall = ObjectAccessor::GetCreature(*me, thrallGUID))
thrall->AI()->Talk(THRALL_SAY_THRONE_A_1);
if (Player* player = GetPlayerForEscort())
player->PlayDirectSound(SOUND_THRALL_1, player);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 62:
if (Creature* thrall = ObjectAccessor::GetCreature(*me, thrallGUID))
thrall->AI()->Talk(THRALL_SAY_THRONE_A_2);
if (Player* player = GetPlayerForEscort())
player->PlayDirectSound(SOUND_THRALL_2, player);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 63:
Talk(WRYNN_SAY_THRONE_1);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 64:
Talk(WRYNN_SAY_THRONE_2);
JumpToNextStep(1.5 * IN_MILLISECONDS);
break;
case 65:
SetRun(true);
SetEscortPaused(false);
JumpToNextStep(0.25 * IN_MILLISECONDS);
break;
case 66:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
jaina->AI()->Talk(JAINA_SAY_THRONE_1);
me->SetImmuneToNPC(true);
bStepping = false;
JumpToNextStep(0);
break;
case 67:
Talk(WRYNN_SAY_THRONE_3);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 68:
Talk(WRYNN_SAY_THRONE_4);
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->MovePoint(0, AllianceWP[8].x, AllianceWP[8].y, AllianceWP[8].z);
jaina->SetImmuneToAll(true);
}
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
break;
case 69:
Talk(WRYNN_SAY_THRONE_5);
SpawnWave(13); //alliance soldiers
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 70:
Talk(WRYNN_SAY_THRONE_6);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 71:
Talk(WRYNN_SAY_THRONE_7);
JumpToNextStep(16.5 * IN_MILLISECONDS);
break;
case 72:
Talk(WRYNN_SAY_THRONE_8);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 73:
Talk(WRYNN_SAY_THRONE_9);
me->SetImmuneToAll(false);
if (Creature* thrall = ObjectAccessor::GetCreature(*me, thrallGUID))
{
thrall->SetReactState(REACT_AGGRESSIVE);
thrall->SetImmuneToNPC(false);
thrall->SetImmuneToPC(true);
thrall->AddThreat(me, 100.0f);
me->AddThreat(thrall, 100.0f);
thrall->AI()->AttackStart(me);
}
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasGUID))
{
sylvanas->SetReactState(REACT_AGGRESSIVE);
sylvanas->SetImmuneToNPC(false);
sylvanas->SetImmuneToPC(true);
sylvanas->AddThreat(me, 100.0f);
sylvanas->AI()->AttackStart(me);
me->AddThreat(sylvanas, 100.0f);
}
for (uint8 i = 0; i < HORDE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = ObjectAccessor::GetCreature(*me, hordeForcesGUID[i]))
{
temp->SetReactState(REACT_AGGRESSIVE);
temp->SetImmuneToNPC(false);
temp->SetImmuneToPC(true);
}
}
for (uint8 i = 0; i < ALLIANCE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = ObjectAccessor::GetCreature(*me, allianceForcesGUID[i]))
{
if (Creature* temp2 = ObjectAccessor::GetCreature(*me, hordeForcesGUID[i]))
{
temp->SetReactState(REACT_AGGRESSIVE);
temp2->SetReactState(REACT_AGGRESSIVE);
temp->SetImmuneToAll(false);
temp2->SetImmuneToAll(false);
temp->AddThreat(temp2, 100.0f);
temp->AI()->AttackStart(temp2);
temp2->AddThreat(temp, 100.0f);
}
}
}
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 74:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->GetMotionMaster()->MovePoint(0, AllianceWP[9].x, AllianceWP[9].y, AllianceWP[9].z);
jaina->AI()->Talk(JAINA_SAY_THRONE_2);
}
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 75:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->AI()->DoCastAOE(SPELL_DEEPFREEZE);
jaina->AI()->Talk(JAINA_SAY_THRONE_3);
}
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 76:
std::list HelperList;
me->GetCreatureListWithEntryInGrid(HelperList, NPC_SW_SOLDIER, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_HORDE_SOLDIER, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_JAINA, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_SYLVANAS, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_THRALL, 100.0f);
if (!HelperList.empty())
for (std::list::iterator itr = HelperList.begin(); itr != HelperList.end(); itr++)
(*itr)->DespawnOrUnsummon();
if (Map* map = me->GetMap())
{
Map::PlayerList const& PlayerList = map->GetPlayers();
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (Player* player = i->GetSource())
{
if (me->IsInRange(player, 0.0f, 50.0f))
{
if (player->GetTeamId() == TEAM_ALLIANCE)
{
player->RemoveAura(SPELL_WRYNN_BUFF);
player->RemoveAura(SPELL_JAINA_BUFF);
player->CompleteQuest(QUEST_BATTLE_A);
player->NearTeleportTo(-8445.213867f, 337.384277f, 121.746056f, 5.401534f, false);
}
}
}
}
}
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_MANHUNT_STARTS_A, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_SEWERS_DONE_A, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_APOTHECARIUM_DONE_A, 0);
me->DespawnOrUnsummon();
break;
}
}
else phaseTimer -= diff;
}
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_WHIRLWIND:
DoCast(me, SPELL_WHIRLWIND);
_events.ScheduleEvent(EVENT_WHIRLWIND, 20s);
break;
case EVENT_HEROIC_LEAP:
DoCastVictim(SPELL_HEROIC_LEAP);
_events.ScheduleEvent(EVENT_HEROIC_LEAP, 15s, 30s);
break;
case EVENT_AGGRO_JAINA:
if (me->GetVictim())
{
if (Creature* jaina = ObjectAccessor::GetCreature(*me, jainaGUID))
{
jaina->AI()->AttackStart(me->GetVictim());
}
}
DoCast(me, SPELL_THUNDER);
_events.ScheduleEvent(EVENT_AGGRO_JAINA, 2s);
break;
case EVENT_WRYNN_BUFF:
DoCast(me, SPELL_WRYNN_BUFF);
_events.ScheduleEvent(EVENT_WRYNN_BUFF, 10s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_varian_wrynnAI(creature);
}
};
/*######
## npc_jaina_proudmoore
######*/
class npc_jaina_proudmoore_bfu : public CreatureScript
{
public:
npc_jaina_proudmoore_bfu() : CreatureScript("npc_jaina_proudmoore_bfu") { }
struct npc_jaina_proudmoore_bfuAI : public ScriptedAI
{
npc_jaina_proudmoore_bfuAI(Creature* creature) : ScriptedAI(creature)
{
Reset();
}
void Reset() override
{
me->SetCorpseDelay(1);
me->SetRespawnTime(1);
_events.ScheduleEvent(EVENT_FIREBALL, 1s);
_events.ScheduleEvent(EVENT_BLIZZARD, 8s);
_events.ScheduleEvent(EVENT_ELEMENTAL, 30s);
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_THRALL_BUFF, true);
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
}
void UpdateAI(uint32 diff) override
{
if (!me->GetVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_FIREBALL:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
DoCast(target, SPELL_FIREBALL);
_events.ScheduleEvent(EVENT_FIREBALL, 3s);
break;
case EVENT_BLIZZARD:
DoCast(SPELL_BLIZZARD);
_events.ScheduleEvent(EVENT_BLIZZARD, 15s);
break;
case EVENT_ELEMENTAL:
DoCast(SPELL_ELEMENTALS);
_events.ScheduleEvent(EVENT_ELEMENTAL, 90s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_jaina_proudmoore_bfuAI(creature);
}
};
/*######
## ENEMY
#######*/
/*######
## boss_blight_worm
######*/
class boss_blight_worm : public CreatureScript
{
public:
boss_blight_worm() : CreatureScript("boss_blight_worm") { }
struct boss_blight_wormAI : public ScriptedAI
{
boss_blight_wormAI(Creature* creature) : ScriptedAI(creature)
{
me->SetCombatMovement(false);
}
void Reset() override
{
_events.ScheduleEvent(EVENT_INFEST, 2s);
_events.ScheduleEvent(EVENT_BLIGHT_BREATH, 750ms);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_INFEST:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0, true))
DoCast(target, SPELL_INGEST);
_events.ScheduleEvent(EVENT_INFEST, 20s);
break;
case EVENT_BLIGHT_BREATH:
DoCast(SPELL_BLIGHT_BREATH);
_events.ScheduleEvent(EVENT_BLIGHT_BREATH, 15s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new boss_blight_wormAI(creature);
}
};
/*######
## Spells
######*/
// - 61123 - Ingest
class spell_blight_worm_ingest : public SpellScript
{
PrepareSpellScript(spell_blight_worm_ingest);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_INGEST });
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
if (Unit* caster = GetCaster())
target->CastSpell(caster, SPELL_INGEST_TRIGGER, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_blight_worm_ingest::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
/*######
## HORDE
#######*/
/*######
## npc_thrall_bfu
######*/
class npc_thrall_bfu : public CreatureScript
{
public:
npc_thrall_bfu() : CreatureScript("npc_thrall_bfu") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
switch (action)
{
case GOSSIP_ACTION_INFO_DEF + 1:
{
CloseGossipMenuFor(player);
if (auto thrall_ai = CAST_AI(npc_thrall_bfu::npc_thrall_bfuAI, creature->AI()))
{
if (Creature* sylvannas = GetClosestCreatureWithEntry(creature, NPC_SYLVANAS, 50.0f))
{
thrall_ai->sylvanasfollowGUID = sylvannas->GetGUID();
thrall_ai->Start(true, true, player->GetGUID());
thrall_ai->SetDespawnAtEnd(false);
thrall_ai->SetDespawnAtFar(false);
}
else
thrall_ai->sylvanasfollowGUID.Clear();
}
break;
}
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestStatus(QUEST_BATTLE_H) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_THRALL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
bool OnQuestReward(Player* player, Creature* /*creature*/, Quest const* quest, uint32 /*item*/) override
{
if (quest->GetQuestId() == QUEST_BATTLE_H)
{
player->RemoveAura(SPELL_THRALL_BUFF);
player->RemoveAura(SPELL_SYLVANAS_BUFF);
player->CastSpell(player, SPELL_TELEPORT_OG, true);
}
return true;
}
struct npc_thrall_bfuAI : public npc_escortAI
{
npc_thrall_bfuAI(Creature* creature) : npc_escortAI(creature)
{
hordeGuardsGUID.clear();
}
bool bStepping;
bool EnableAttack;
uint32 step;
uint32 phaseTimer;
ObjectGuid sylvanasfollowGUID;
ObjectGuid allianceForcesGUID[ALLIANCE_FORCE_MAXCOUNT];
ObjectGuid ValimathrasGUID;
ObjectGuid ValimathrasPortalGUID;
ObjectGuid WrynnGUID;
ObjectGuid JainaGUID;
ObjectGuid SaurfangGUID;
GuidVector hordeGuardsGUID;
EventMap _events;
void EnterEvadeMode(EvadeReason /*why*/) override
{
me->RemoveAura(SPELL_HEROIC_VANGUARD);
me->GetThreatMgr().ClearAllThreat();
me->CombatStop(true);
me->SetLootRecipient(nullptr);
if (HasEscortState(STATE_ESCORT_ESCORTING))
{
AddEscortState(STATE_ESCORT_RETURNING);
ReturnToLastPoint();
}
else
{
me->GetMotionMaster()->MoveTargetedHome();
Reset();
}
}
void Reset() override
{
if (!HasEscortState(STATE_ESCORT_ESCORTING))
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->Mount(MODEL_WHITE_WULF);
me->SetCorpseDelay(1);
me->SetRespawnTime(1);
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
bStepping = false;
EnableAttack = false;
step = 0;
phaseTimer = 0;
sylvanasfollowGUID.Clear();
_events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 3s);
_events.ScheduleEvent(EVENT_LAVA_BURST, 5s);
_events.ScheduleEvent(EVENT_THUNDER, 8s);
_events.ScheduleEvent(EVENT_AGGRO_SYLVANAS, 2s);
_events.ScheduleEvent(EVENT_THRALL_BUFF, 2s);
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
{
valimathras->DespawnOrUnsummon();
ValimathrasGUID.Clear();
}
if (Creature* valimathrasportal = ObjectAccessor::GetCreature(*me, ValimathrasPortalGUID))
{
valimathrasportal->DespawnOrUnsummon();
ValimathrasPortalGUID.Clear();
}
if (Creature* wrynn = ObjectAccessor::GetCreature(*me, WrynnGUID))
{
wrynn->DespawnOrUnsummon();
WrynnGUID.Clear();
}
if (Creature* jaina = ObjectAccessor::GetCreature(*me, JainaGUID))
{
jaina->DespawnOrUnsummon();
JainaGUID.Clear();
}
if (Creature* saurfang = ObjectAccessor::GetCreature(*me, SaurfangGUID))
{
saurfang->DespawnOrUnsummon();
SaurfangGUID.Clear();
}
for (ObjectGuid const& guid : hordeGuardsGUID)
if (Creature* temp = ObjectAccessor::GetCreature(*me, guid))
temp->DespawnOrUnsummon();
hordeGuardsGUID.clear();
}
}
void JustSummoned(Creature* summoned) override
{
switch (summoned->GetEntry())
{
case NPC_BLIGHT_ABBERATION:
summoned->SetHomePosition(me->GetPosition());
summoned->AddThreat(me, 100.0f);
break;
case NPC_WARSONG_BATTLEGUARD:
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
summoned->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
break;
case NPC_VARIMATHRAS_PORTAL:
summoned->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_THRALL_BUFF, true);
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
break;
case NPC_CAVE_DUMMY:
summoned->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_THRALL_BUFF, true);
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
summoned->AddAura(SPELL_CYCLONE_FALL, summoned);
break;
case NPC_TREACHEROUS_GUARDIAN_H:
case NPC_DOCTOR_H:
case NPC_CHEMIST_H:
summoned->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
summoned->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_THRALL_BUFF, true);
summoned->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
if (!EnableAttack)
summoned->SetFaction(FACTION_FRIENDLY);
summoned->AddThreat(me, 100.0f);
me->AddThreat(summoned, 100.0f);
summoned->AI()->AttackStart(me);
break;
case NPC_LEGION_INVADER:
case NPC_LEGION_DREADWHISPER:
case NPC_FELGUARD_MORADEUR:
case NPC_DREADLORD:
case NPC_BETRAYER_H:
case NPC_FELBEAST_H:
summoned->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
summoned->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
summoned->AddThreat(me, 100.0f);
me->AddThreat(summoned, 100.0f);
summoned->AI()->AttackStart(me);
break;
case NPC_KHANOK:
summoned->SetHomePosition(me->GetPosition());
summoned->AddThreat(me, 100.0f);
summoned->AI()->AttackStart(me);
default:
break;
}
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
switch (summon->GetEntry())
{
case NPC_BLIGHT_ABBERATION:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_COURTYARD_FIGHT_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_COURTYARD_DONE_H, 1);
bStepping = true;
break;
case NPC_KHANOK:
{
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_INNER_SANCTUM_FIGHT_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_INNER_SANCTUM_DONE_H, 1);
FollowThrall();
SetEscortPaused(false);
std::list SanktumList;
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_FELGUARD_MORADEUR, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_DREADLORD, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_TREACHEROUS_GUARDIAN_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_DOCTOR_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_CHEMIST_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_BETRAYER_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_FELBEAST_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(SanktumList, NPC_DOOMGUARD_PILLARGER, 1000.0f);
if (!SanktumList.empty())
for (std::list::iterator itr = SanktumList.begin(); itr != SanktumList.end(); itr++)
(*itr)->DespawnOrUnsummon();
break;
}
case NPC_VARIMATHRAS:
{
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_ROYAL_QUARTER_FIGHT_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_ROYAL_QUARTER_DONE_H, 1);
std::list ThroneList;
me->GetCreatureListWithEntryInGrid(ThroneList, NPC_LEGION_OVERLORD, 1000.0f);
me->GetCreatureListWithEntryInGrid(ThroneList, NPC_LEGION_INVADER, 1000.0f);
me->GetCreatureListWithEntryInGrid(ThroneList, NPC_LEGION_DREADWHISPER, 1000.0f);
me->GetCreatureListWithEntryInGrid(ThroneList, NPC_VARIMATHRAS_PORTAL, 1000.0f);
if (!ThroneList.empty())
for (std::list::iterator itr = ThroneList.begin(); itr != ThroneList.end(); itr++)
(*itr)->DespawnOrUnsummon();
SetEscortPaused(false);
SetRun(false);
break;
}
default:
break;
}
}
void UpdateWorldState(Map* map, uint32 id, uint32 state)
{
Map::PlayerList const& players = map->GetPlayers();
if (!players.IsEmpty())
{
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if (Player* player = itr->GetSource())
player->SendUpdateWorldState(id, state);
}
}
}
void SetHoldState(bool bOnHold)
{
SetEscortPaused(bOnHold);
}
void JumpToNextStep(uint32 uiTimer)
{
phaseTimer = uiTimer;
++step;
}
void FollowThrall()
{
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
{
sylvanas->GetMotionMaster()->Clear();
sylvanas->SetImmuneToAll(false);
sylvanas->SetReactState(REACT_AGGRESSIVE);
sylvanas->SetFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE);
sylvanas->GetMotionMaster()->MoveFollow(me, 1, M_PI * 0.1f);
}
}
void ActivateValimathrasPortal()
{
if (Creature* portal = me->FindNearestCreature(NPC_VARIMATHRAS_PORTAL, 500.0f))
{
portal->SummonCreature(NPC_LEGION_OVERLORD, ThrallSpawn[81].x + rand32() % 5, ThrallSpawn[81].y + rand32() % 5, ThrallSpawn[81].z, TEMPSUMMON_DEAD_DESPAWN);
portal->DespawnOrUnsummon();
}
}
void SpawnWave(uint32 waveId)
{
switch (waveId)
{
case 0: // Vortex
if (Creature* whirlwind1 = me->SummonCreature(NPC_VORTEX, ThrallSpawn[0].x, ThrallSpawn[0].y, ThrallSpawn[0].z, ThrallSpawn[0].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30 * IN_MILLISECONDS))
whirlwind1->GetMotionMaster()->MovePath(NPC_WHIRLWIND * 10, false);
if (Creature* whirlwind2 = me->SummonCreature(NPC_VORTEX, ThrallSpawn[0].x, ThrallSpawn[0].y, ThrallSpawn[0].z, ThrallSpawn[0].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30 * IN_MILLISECONDS))
whirlwind2->GetMotionMaster()->MovePath(NPC_WHIRLWIND * 100, false);
break;
case 1:
// BATTLING_COURTYARD Initial Spawn
for (uint8 i = 0; i < 3; ++i)
me->SummonCreature(NPC_DOCTOR_H, ThrallSpawn[i + 1].x, ThrallSpawn[i + 1].y, ThrallSpawn[i + 1].z, ThrallSpawn[i + 1].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS);
for (uint8 i = 0; i < 9; ++i)
me->SummonCreature(NPC_CHEMIST_H, ThrallSpawn[i + 4].x, ThrallSpawn[i + 4].y, ThrallSpawn[i + 4].z, ThrallSpawn[i + 4].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS);
for (uint8 i = 0; i < 6; ++i)
me->SummonCreature(NPC_TREACHEROUS_GUARDIAN_H, ThrallSpawn[i + 13].x, ThrallSpawn[i + 13].y, ThrallSpawn[i + 14].z, ThrallSpawn[i + 14].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS);
for (uint8 i = 0; i < 4; ++i)
me->SummonCreature(NPC_BLIGHT_SLINGER, ThrallSpawn[i + 19].x, ThrallSpawn[i + 19].y, ThrallSpawn[i + 19].z, ThrallSpawn[i + 19].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900 * IN_MILLISECONDS);
break;
case 2:
// Valimathras
if (Unit* temp = me->SummonCreature(NPC_VARIMATHRAS, ThrallSpawn[23].x, ThrallSpawn[23].y, ThrallSpawn[23].z, ThrallSpawn[23].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900 * IN_MILLISECONDS))
{
ValimathrasGUID = temp->GetGUID();
temp->SetImmuneToAll(true);
}
break;
case 3:
if (Unit* temp = me->SummonCreature(NPC_VARIMATHRAS_PORTAL, ThrallSpawn[24].x, ThrallSpawn[24].y, ThrallSpawn[24].z, ThrallSpawn[24].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900 * IN_MILLISECONDS))
ValimathrasPortalGUID = temp->GetGUID();
break;
case 4:
// COURTYARD_FIGHT Spawns
for (uint8 i = 0; i < WAVE_COURTYARD_FIGHT; ++i)
{
switch (urand(0, 2))
{
case 0:
me->SummonCreature(NPC_TREACHEROUS_GUARDIAN_H, ThrallSpawn[25].x + rand32() % 5, ThrallSpawn[25].y + rand32() % 5, ThrallSpawn[25].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_DOCTOR_H, ThrallSpawn[26].x + rand32() % 5, ThrallSpawn[26].y + rand32() % 5, ThrallSpawn[26].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 2:
me->SummonCreature(NPC_CHEMIST_H, ThrallSpawn[27].x + rand32() % 5, ThrallSpawn[27].y + rand32() % 5, ThrallSpawn[27].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 5:
// Bossspawn 1
if (Creature* temp = me->SummonCreature(NPC_BLIGHT_ABBERATION, ThrallSpawn[28].x, ThrallSpawn[28].y, ThrallSpawn[28].z, ThrallSpawn[28].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900 * IN_MILLISECONDS))
{
me->AddThreat(temp, 100.0f);
me->AI()->AttackStart(temp);
}
break;
case 6:
// COURTYARD_DONE Spawn
if (Unit* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[29].x, ThrallSpawn[29].y, ThrallSpawn[29].z, ThrallSpawn[29].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
{
hordeGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePoint(0, ThrallSpawn[30].x, ThrallSpawn[30].y, ThrallSpawn[30].z);
}
if (Unit* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[31].x, ThrallSpawn[31].y, ThrallSpawn[31].z, ThrallSpawn[31].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
{
hordeGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePoint(0, ThrallSpawn[32].x, ThrallSpawn[32].y, ThrallSpawn[32].z);
}
if (Unit* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[33].x, ThrallSpawn[33].y, ThrallSpawn[33].z, ThrallSpawn[33].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
{
hordeGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePoint(0, ThrallSpawn[34].x, ThrallSpawn[34].y, ThrallSpawn[34].z);
}
if (Unit* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[35].x, ThrallSpawn[35].y, ThrallSpawn[35].z, ThrallSpawn[35].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
{
hordeGuardsGUID.push_back(temp->GetGUID());
temp->GetMotionMaster()->MovePoint(0, ThrallSpawn[36].x, ThrallSpawn[36].y, ThrallSpawn[36].z);
}
for (uint8 i = 0; i < 2; ++i)
if (Unit* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[i + 44].x, ThrallSpawn[i + 44].y, ThrallSpawn[i + 44].z, ThrallSpawn[i + 44].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
hordeGuardsGUID.push_back(temp->GetGUID());
break;
case 7:
for (uint8 i = 0; i < 9; ++i)
me->SummonCreature(NPC_CAVE_DUMMY, ThrallSpawn[i + 46].x, ThrallSpawn[i + 46].y, ThrallSpawn[i + 46].z, ThrallSpawn[i + 46].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600 * IN_MILLISECONDS);
break;
case 8:
for (uint8 i = 0; i < 2; ++i)
if (Unit* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[i + 57].x, ThrallSpawn[i + 57].y, ThrallSpawn[i + 57].z, ThrallSpawn[i + 57].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
hordeGuardsGUID.push_back(temp->GetGUID());
break;
case 9:
// Top of Undercity - Attacktrashpack
for (uint8 i = 0; i < 3; ++i)
{
switch (urand(0, 2))
{
case 0:
me->SummonCreature(NPC_TREACHEROUS_GUARDIAN_H, ThrallSpawn[59].x + rand32() % 2, ThrallSpawn[59].y + rand32() % 2, ThrallSpawn[59].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_DOCTOR_H, ThrallSpawn[59].x + rand32() % 2, ThrallSpawn[59].y + rand32() % 2, ThrallSpawn[59].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 2:
me->SummonCreature(NPC_CHEMIST_H, ThrallSpawn[59].x + rand32() % 2, ThrallSpawn[59].y + rand32() % 2, ThrallSpawn[59].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 10:
// Top of Undercity - Attacktrashpack
for (uint8 i = 0; i < 3; ++i)
{
switch (urand(0, 1))
{
case 0:
me->SummonCreature(NPC_TREACHEROUS_GUARDIAN_H, ThrallSpawn[60].x + rand32() % 5, ThrallSpawn[60].y + rand32() % 5, ThrallSpawn[60].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_FELGUARD_MORADEUR, ThrallSpawn[60].x + rand32() % 5, ThrallSpawn[60].y + rand32() % 5, ThrallSpawn[60].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 11:
// Bottom of Undercity - Attacktrashpack
for (uint8 i = 0; i < 3; ++i)
{
switch (urand(0, 1))
{
case 0:
me->SummonCreature(NPC_FELGUARD_MORADEUR, ThrallSpawn[61].x + rand32() % 5, ThrallSpawn[61].y + rand32() % 5, ThrallSpawn[61].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_DREADLORD, ThrallSpawn[61].x + rand32() % 5, ThrallSpawn[61].y + rand32() % 5, ThrallSpawn[61].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 12:
// Valimathras 2
if (Unit* temp = me->SummonCreature(NPC_VARIMATHRAS, ThrallSpawn[63].x, ThrallSpawn[63].y, ThrallSpawn[63].z, ThrallSpawn[63].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300 * IN_MILLISECONDS))
{
ValimathrasGUID = temp->GetGUID();
temp->SetImmuneToAll(true);
}
break;
case 13:
if (Unit* temp = me->SummonCreature(NPC_VARIMATHRAS_PORTAL, ThrallSpawn[64].x, ThrallSpawn[64].y, ThrallSpawn[64].z, ThrallSpawn[64].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900 * IN_MILLISECONDS))
ValimathrasPortalGUID = temp->GetGUID();
break;
// NPC_KHANOK - Inner Sunktum Spawn Left
case 14:
for (uint8 i = 0; i < 4; ++i)
{
switch (urand(0, 6))
{
case 0:
me->SummonCreature(NPC_FELGUARD_MORADEUR, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_DREADLORD, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 2:
me->SummonCreature(NPC_TREACHEROUS_GUARDIAN_H, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 3:
me->SummonCreature(NPC_DOCTOR_H, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 4:
me->SummonCreature(NPC_CHEMIST_H, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 5:
me->SummonCreature(NPC_BETRAYER_H, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 6:
me->SummonCreature(NPC_FELBEAST_H, ThrallSpawn[65].x + rand32() % 5, ThrallSpawn[65].y + rand32() % 5, ThrallSpawn[65].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
// NPC_KHANOK - Inner Sunktum Spawn Right
case 15:
for (uint8 i = 0; i < 4; ++i)
{
switch (urand(0, 6))
{
case 0:
me->SummonCreature(NPC_FELGUARD_MORADEUR, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_DREADLORD, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 2:
me->SummonCreature(NPC_TREACHEROUS_GUARDIAN_H, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 3:
me->SummonCreature(NPC_DOCTOR_H, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 4:
me->SummonCreature(NPC_CHEMIST_H, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 5:
me->SummonCreature(NPC_BETRAYER_H, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 6:
me->SummonCreature(NPC_FELBEAST_H, ThrallSpawn[66].x + rand32() % 5, ThrallSpawn[66].y + rand32() % 5, ThrallSpawn[66].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
// NPC_KHANOK - Inner Sunktum Spawn Top
case 16:
me->SummonCreature(NPC_DOOMGUARD_PILLARGER, ThrallSpawn[67].x + rand32() % 15, ThrallSpawn[67].y + rand32() % 15, ThrallSpawn[67].z + rand32() % 5, TEMPSUMMON_DEAD_DESPAWN);
break;
// NPC_KHANOK - Inner Sunktum Spawn Middle
case 17:
if (Creature* temp = me->SummonCreature(NPC_KHANOK, ThrallSpawn[68].x, ThrallSpawn[68].y, ThrallSpawn[68].z, TEMPSUMMON_DEAD_DESPAWN))
{
me->AddThreat(temp, 100.0f);
me->AI()->AttackStart(temp);
}
break;
case 18:
if (Creature* temp = me->SummonCreature(NPC_WARSONG_BATTLEGUARD, ThrallSpawn[69].x, ThrallSpawn[69].y, ThrallSpawn[69].z, ThrallSpawn[69].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 240 * IN_MILLISECONDS))
{
hordeGuardsGUID.push_back(temp->GetGUID());
temp->AI()->Talk(SAY_FOR_THE_HORDE);
temp->GetMotionMaster()->MovePath(NPC_WARSONG_BATTLEGUARD * 100, false);
}
break;
// Valimathras Room Preparation
case 19:
for (uint8 i = 0; i < 3; ++i)
me->SummonGameObject(GO_BLOCKED_PASSAGE, ThrallSpawn[i + 70].x, ThrallSpawn[i + 70].y, ThrallSpawn[70].z, ThrallSpawn[i + 70].o, 0.0f, 0.0f, 0.0f, 0.0f, 120 * IN_MILLISECONDS);
// Valimathras BossSpawn
if (Creature* temp = me->SummonCreature(NPC_VARIMATHRAS, ThrallSpawn[73].x, ThrallSpawn[73].y, ThrallSpawn[73].z, ThrallSpawn[73].o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 1200 * IN_MILLISECONDS))
{
ValimathrasGUID = temp->GetGUID();
temp->SetImmuneToAll(true);
temp->CastSpell(me, SPELL_AURA_OF_VARIMATHRAS);
temp->CastSpell(me, SPELL_OPENING_LEGION_PORTALS);
temp->AI()->Talk(SAY_CLOSE_DOOR);
}
for (uint8 i = 0; i < 6; ++i)
{
if (Unit* temp = me->SummonCreature(NPC_VARIMATHRAS_PORTAL, ThrallSpawn[i + 74].x, ThrallSpawn[i + 74].y, ThrallSpawn[i + 74].z, TEMPSUMMON_MANUAL_DESPAWN))
temp->CastSpell(me, SPELL_VALIMATHRAS_PORTAL);
}
break;
case 20:
for (uint8 i = 0; i < 3; ++i)
{
switch (urand(0, 1))
{
case 0:
me->SummonCreature(NPC_LEGION_INVADER, ThrallSpawn[80].x + rand32() % 5, ThrallSpawn[80].y + rand32() % 5, ThrallSpawn[80].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_LEGION_DREADWHISPER, ThrallSpawn[81].x + rand32() % 5, ThrallSpawn[81].y + rand32() % 5, ThrallSpawn[81].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
case 21:
for (uint8 i = 0; i < 3; ++i)
{
switch (urand(0, 1))
{
case 0:
me->SummonCreature(NPC_LEGION_INVADER, ThrallSpawn[81].x + rand32() % 5, ThrallSpawn[81].y + rand32() % 5, ThrallSpawn[81].z, TEMPSUMMON_DEAD_DESPAWN);
break;
case 1:
me->SummonCreature(NPC_LEGION_DREADWHISPER, ThrallSpawn[80].x + rand32() % 5, ThrallSpawn[80].y + rand32() % 5, ThrallSpawn[80].z, TEMPSUMMON_DEAD_DESPAWN);
break;
}
}
break;
}
}
void WaypointReached(uint32 waypointId) override
{
switch (waypointId)
{
case 1:
SetHoldState(true);
bStepping = true;
break;
case 2:
SetHoldState(true);
bStepping = true;
break;
case 11:
SetHoldState(true);
bStepping = true;
break;
case 13:
SetHoldState(true);
bStepping = true;
break;
case 14:
SetHoldState(true);
bStepping = true;
break;
case 34:
SetHoldState(true);
bStepping = true;
break;
case 36:
Talk(THRALL_SAY_SANCTUM_1);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_ROYAL_QUARTER_FIGHT_H, 1);
break;
case 46:
SetHoldState(true);
bStepping = true;
break;
case 57:
SetHoldState(true);
bStepping = true;
break;
case 61:
SetHoldState(true);
bStepping = true;
break;
case 65:
SetHoldState(true);
bStepping = true;
break;
case 66:
SetHoldState(true);
bStepping = true;
break;
case 75:
SetHoldState(true);
bStepping = true;
break;
case 81:
SetHoldState(true);
bStepping = true;
break;
case 104:
SetHoldState(true);
bStepping = true;
break;
case 109:
SetHoldState(true);
bStepping = true;
break;
case 113:
SetHoldState(true);
bStepping = true;
break;
case 117:
SetHoldState(true);
bStepping = true;
break;
case 118:
Talk(THRALL_SAY_THRONE_8);
break;
case 120:
SetHoldState(true);
bStepping = true;
break;
}
}
bool CanAIAttack(Unit const* victim) const override
{
return victim->GetEntry() != NPC_BLIGHT_SLINGER;
}
void UpdateAI(uint32 diff) override
{
npc_escortAI::UpdateAI(diff);
if (bStepping)
{
if (phaseTimer <= diff)
{
switch (step)
{
//Preparation
case 0:
me->setActive(true);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 1:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_COUNTDOWN_H, 1);
Talk(THRALL_SAY_PREP_1);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 2:
Talk(THRALL_SAY_PREP_2);
JumpToNextStep(14 * IN_MILLISECONDS);
break;
case 3:
if (Creature* guard = me->FindNearestCreature(NPC_HORDE_GUARD, 100.0f))
guard->AI()->Talk(SAY_BURN_UC);
JumpToNextStep(19 * IN_MILLISECONDS);
break;
case 4:
if (Creature* guard = me->FindNearestCreature(NPC_HORDE_GUARD, 100.0f))
guard->AI()->Talk(SAY_PUTRESS_ANGER);
JumpToNextStep(25 * IN_MILLISECONDS);
break;
case 5:
Talk(THRALL_SAY_PREP_3);
JumpToNextStep(14 * IN_MILLISECONDS);
break;
case 6:
Talk(THRALL_SAY_PREP_4);
JumpToNextStep(14 * IN_MILLISECONDS);
break;
case 7:
Talk(THRALL_SAY_PREP_5);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 8:
Talk(THRALL_SAY_PREP_6);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 9:
Talk(THRALL_SAY_PREP_7);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 10:
DoCast(me, SPELL_THRALL_BUFF);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
// Start Event
case 11:
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_COUNTDOWN_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_START_H, 1);
Talk(THRALL_SAY_PREP_8);
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0);
SetRun(true);
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
{
sylvanas->GetMotionMaster()->MovePath(NPC_SYLVANAS * 100, false);
sylvanas->setActive(true);
}
break;
case 12:
me->Dismount();
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 13:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->Dismount();
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 14:
Talk(THRALL_SAY_COURTYARD_1);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 15:
me->CastSpell(me, SPELL_CALL_OF_AIR);
SpawnWave(0);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 16:
{
std::list PlagueList;
me->GetCreatureListWithEntryInGrid(PlagueList, NPC_PLAGUE_TRIGGER, 50.0f);
if (!PlagueList.empty())
for (std::list::iterator itr = PlagueList.begin(); itr != PlagueList.end(); itr++)
(*itr)->DespawnOrUnsummon();
SetEscortPaused(false);
SetRun(false);
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->GetMotionMaster()->MovePath(NPC_SYLVANAS * 1000, false);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
}
case 17:
bStepping = false;
JumpToNextStep(0);
break;
case 18:
SpawnWave(1);
Talk(THRALL_SAY_COURTYARD_2);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 19:
{
SpawnWave(2);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
}
case 20:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_VALIMATHRAS_INTRO_0);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 21:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_VALIMATHRAS_INTRO_1);
JumpToNextStep(9 * IN_MILLISECONDS);
break;
case 22:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_VALIMATHRAS_INTRO_2);
JumpToNextStep(7 * IN_MILLISECONDS);
break;
case 23:
SpawnWave(3);
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 24:
if (Creature* valimathrasportal = ObjectAccessor::GetCreature(*me, ValimathrasPortalGUID))
valimathrasportal->CastSpell(valimathrasportal, SPELL_VALIMATHRAS_PORTAL);
JumpToNextStep(12 * IN_MILLISECONDS);
break;
case 25:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
{
valimathras->GetMotionMaster()->MovePoint(0, 1804.559f, 235.504f, 62.753f);
valimathras->DespawnOrUnsummon(3 * IN_MILLISECONDS);
}
if (Creature* valimathrasportal = ObjectAccessor::GetCreature(*me, ValimathrasPortalGUID))
valimathrasportal->DespawnOrUnsummon(6 * IN_MILLISECONDS);
JumpToNextStep(1 * IN_MILLISECONDS);
break;
case 26:
{
Talk(THRALL_SAY_COURTYARD_3);
me->CastSpell(me, SPELL_TIDAL_WAVE_SUMMON);
std::list HelperList;
me->GetCreatureListWithEntryInGrid(HelperList, NPC_SLINGER_TRIGGER, 1000.0f);
if (!HelperList.empty())
for (std::list::iterator itr = HelperList.begin(); itr != HelperList.end(); itr++)
(*itr)->DespawnOrUnsummon();
JumpToNextStep(5 * IN_MILLISECONDS);
break;
}
// Start COURTYARD_FIGHT
case 27:
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(true);
Talk(THRALL_SAY_COURTYARD_4);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_START_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_COURTYARD_FIGHT_H, 1);
JumpToNextStep(0);
break;
case 28:
{
EnableAttack = true;
DoCast(me, SPELL_HEROIC_VANGUARD, true);
std::list HostileEndList;
me->GetCreatureListWithEntryInGrid(HostileEndList, NPC_TREACHEROUS_GUARDIAN_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(HostileEndList, NPC_DOCTOR_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(HostileEndList, NPC_CHEMIST_H, 1000.0f);
if (!HostileEndList.empty())
for (std::list::iterator itr = HostileEndList.begin(); itr != HostileEndList.end(); itr++) (*itr)->SetFaction(FACTION_MONSTER);
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
}
case 29:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 30:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 31:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 32:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 33:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 34:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 35:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 36:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 37:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 38:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 39:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 40:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 41:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 42:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 43:
SpawnWave(4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 44:
SpawnWave(4);
JumpToNextStep(2 * IN_MILLISECONDS);
break;
case 45:
SpawnWave(5);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
// End COURTYARD_FIGHT
case 46:
{
FollowThrall();
std::list HostileList;
me->GetCreatureListWithEntryInGrid(HostileList, NPC_TREACHEROUS_GUARDIAN_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(HostileList, NPC_DOCTOR_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(HostileList, NPC_CHEMIST_H, 1000.0f);
me->GetCreatureListWithEntryInGrid(HostileList, NPC_BLIGHT_SLINGER, 1000.0f);
for (auto& creature : HostileList)
creature->DespawnOrUnsummon();
for (uint8 i = 0; i < 7; ++i)
me->SummonGameObject(GO_HORDE_BANNER, ThrallSpawn[i + 37].x, ThrallSpawn[i + 37].y, ThrallSpawn[i + 37].z, ThrallSpawn[i + 37].o, 0.0f, 0.0f, 0.0f, 0.0f, 120 * IN_MILLISECONDS);
SpawnWave(6);
SetEscortPaused(false);
bStepping = false;
SetRun(false);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
}
case 47:
Talk(THRALL_SAY_COURTYARD_5);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 48:
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
// Elevator Event
case 49:
Talk(THRALL_SAY_ELEVATOR_1);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 50:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->Talk(SYLVANAS_SAY_ELEVATOR_1);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 51:
Talk(THRALL_SAY_ELEVATOR_2);
DoCast(me, SPELL_CALL_OF_AIR);
SpawnWave(7);
JumpToNextStep(16 * IN_MILLISECONDS);
break;
case 52:
Talk(THRALL_SAY_ELEVATOR_3);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 53:
SpawnWave(8);
me->GetMotionMaster()->MoveJump(ThrallSpawn[55].x, ThrallSpawn[55].y, ThrallSpawn[55].z, 40.0f, 40.0f, 0);
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->GetMotionMaster()->MoveJump(ThrallSpawn[56].x, ThrallSpawn[56].y, ThrallSpawn[56].z, 40.0f, 40.0f, 0);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 54:
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(false);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
// Top of Undercity Discussion
case 55:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->Talk(SYLVANAS_SAY_SANCTUM_1);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 56:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->Talk(SYLVANAS_SAY_SANCTUM_2);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 57:
Talk(THRALL_SAY_SANCTUM_2);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 58:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->Talk(SYLVANAS_SAY_SANCTUM_3);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
// Top of Undercity - Fight
case 59:
SpawnWave(9);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 60:
SpawnWave(9);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 61:
SpawnWave(9);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 62:
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(false);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 63:
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 64:
SpawnWave(10);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 65:
SpawnWave(10);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 66:
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(false);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 67:
SpawnWave(11);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 68:
SpawnWave(11);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 69:
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(false);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
// KHANOK - Valimathtas Intro
case 70:
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 71:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->Talk(SYLVANAS_SAY_SANCTUM_4);
SpawnWave(12);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 72:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_VALIMATHRAS_INNER_SANKTUM_0);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 73:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_VALIMATHRAS_INNER_SANKTUM_1);
SpawnWave(13);
JumpToNextStep(2 * IN_MILLISECONDS);
break;
case 74:
if (Creature* valimathrasportal = ObjectAccessor::GetCreature(*me, ValimathrasPortalGUID))
valimathrasportal->CastSpell(valimathrasportal, SPELL_VALIMATHRAS_PORTAL);
JumpToNextStep(4 * IN_MILLISECONDS);
break;
case 75:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
{
valimathras->GetMotionMaster()->MovePoint(0, 1596.642f, 429.811f, -46.3429f);
valimathras->DespawnOrUnsummon(3 * IN_MILLISECONDS);
}
if (Creature* valimathrasportal = ObjectAccessor::GetCreature(*me, ValimathrasPortalGUID))
valimathrasportal->DespawnOrUnsummon(3 * IN_MILLISECONDS);
JumpToNextStep(2 * IN_MILLISECONDS);
break;
// KHANOK - Trashspawn
case 76:
SpawnWave(14);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 77:
SpawnWave(15);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 78:
SpawnWave(16);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 79:
SpawnWave(14);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 80:
SpawnWave(15);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 81:
SpawnWave(16);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 82:
SpawnWave(14);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 83:
SpawnWave(15);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 84:
SpawnWave(16);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 85:
SpawnWave(14);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 86:
SpawnWave(15);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 87:
SpawnWave(16);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 88:
SpawnWave(14);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 89:
SpawnWave(15);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 90:
SpawnWave(16);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 91:
SpawnWave(14);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 92:
SpawnWave(15);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 93:
SpawnWave(16);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 94:
// Spawn Boss 2 KHANOK
SpawnWave(17);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 95:
SpawnWave(14);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 96:
SpawnWave(15);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 97:
SpawnWave(16);
JumpToNextStep(0 * IN_MILLISECONDS);
bStepping = false;
break;
case 98:
// KHANOK - Won
Talk(THRALL_SAY_SANCTUM_3);
JumpToNextStep(7 * IN_MILLISECONDS);
break;
case 99:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 100:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 101:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 102:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 103:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 104:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 105:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 106:
SpawnWave(18);
JumpToNextStep(0.35 * IN_MILLISECONDS);
break;
case 107:
SpawnWave(18);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 108:
Talk(THRALL_SAY_SANCTUM_4);
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(false);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 109:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->Talk(SYLVANAS_SAY_SANCTUM_5);
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 110:
SpawnWave(19);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 111:
FollowThrall();
SetEscortPaused(false);
bStepping = false;
SetRun(true);
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 112:
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 113:
Talk(THRALL_SAY_SANCTUM_5);
JumpToNextStep(12 * IN_MILLISECONDS);
break;
case 114:
Talk(THRALL_SAY_SANCTUM_6);
DoCast(me, SPELL_CALL_OF_EARTH);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 115:
{
std::list SaronitList;
GetGameObjectListWithEntryInGrid(SaronitList, me, GO_BLOCKED_PASSAGE, 80.0f);
for (std::list::const_iterator itr = SaronitList.begin(); itr != SaronitList.end(); ++itr)
if (GameObject* saronit = (*itr))
saronit->UseDoorOrButton();
JumpToNextStep(5 * IN_MILLISECONDS);
break;
}
case 116:
Talk(THRALL_SAY_SANCTUM_7);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_ROYAL_QUARTER_FIGHT_H, 1);
FollowThrall();
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
// Valimathras Intro
case 117:
Talk(THRALL_SAY_THRONE_1);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 118:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
{
valimathras->AI()->Talk(SAY_THRONE_1);
valimathras->CastSpell(me, SPELL_OPENING_LEGION_PORTALS);
}
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 119:
SpawnWave(20);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 120:
SpawnWave(21);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 121:
ActivateValimathrasPortal();
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_THRONE_2);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 122:
SpawnWave(20);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 123:
SpawnWave(21);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 124:
ActivateValimathrasPortal();
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_THRONE_3);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 125:
SpawnWave(20);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 126:
SpawnWave(21);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 127:
ActivateValimathrasPortal();
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_THRONE_4);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 128:
SpawnWave(20);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 129:
SpawnWave(21);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 130:
ActivateValimathrasPortal();
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_THRONE_5);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 131:
SpawnWave(20);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 132:
SpawnWave(21);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 133:
ActivateValimathrasPortal();
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
valimathras->AI()->Talk(SAY_THRONE_6);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 134:
SpawnWave(20);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 135:
SpawnWave(21);
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 136:
ActivateValimathrasPortal();
JumpToNextStep(5 * IN_MILLISECONDS);
break;
// Valimathras Fight
case 137:
if (Creature* valimathras = ObjectAccessor::GetCreature(*me, ValimathrasGUID))
{
valimathras->SetImmuneToAll(false);
valimathras->RemoveAura(SPELL_AURA_OF_VARIMATHRAS);
valimathras->RemoveAura(SPELL_OPENING_LEGION_PORTALS);
valimathras->AI()->Talk(SAY_VALIMATHRAS_ATTACK);
valimathras->SetHomePosition(me->GetPosition());
valimathras->AddThreat(me, 100.0f);
me->AddThreat(valimathras, 100.0f);
valimathras->AI()->AttackStart(me);
me->AI()->AttackStart(valimathras);
}
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
// Valimathras Won
case 138:
Talk(THRALL_SAY_THRONE_2);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 139:
Talk(THRALL_SAY_THRONE_3);
JumpToNextStep(2 * IN_MILLISECONDS);
break;
case 140:
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 141:
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 142:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
me->SetFacingToObject(sylvanas);
Talk(THRALL_SAY_THRONE_4);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 143:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
{
sylvanas->GetMotionMaster()->MovePoint(0, 1289.48f, 314.33f, -57.32f, true);
sylvanas->CastSpell(sylvanas, SPELL_LEAP_TO_PLATFORM);
}
JumpToNextStep(10 * IN_MILLISECONDS);
break;
case 144:
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
{
sylvanas->AI()->Talk(SYLVANAS_SAY_THRONE_1);
me->SetFacingToObject(sylvanas);
sylvanas->SetFacingToObject(me);
me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
}
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 145:
Talk(THRALL_SAY_THRONE_5);
FollowThrall();
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 146:
Talk(THRALL_SAY_THRONE_6);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
case 147:
for (uint8 i = 0; i < ALLIANCE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = me->SummonCreature(NPC_SW_SOLDIER, AllianceSpawn[i + 25].x, AllianceSpawn[i + 25].y, AllianceSpawn[i + 25].z, AllianceSpawn[i + 25].o, TEMPSUMMON_MANUAL_DESPAWN))
{
allianceForcesGUID[i] = temp->GetGUID();
temp->SetImmuneToAll(true);
temp->ApplySpellImmune(0, IMMUNITY_ID, SPELL_SYLVANAS_BUFF, true);
temp->SetReactState(REACT_PASSIVE);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
}
}
if (Creature* wrynn = me->SummonCreature(NPC_WRYNN, 1308.862f, 381.809f, -66.044243f, TEMPSUMMON_MANUAL_DESPAWN))
{
WrynnGUID = wrynn->GetGUID();
wrynn->SetImmuneToAll(true);
wrynn->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
wrynn->SetReactState(REACT_PASSIVE);
wrynn->GetMotionMaster()->MovePoint(0, 1302.543f, 359.472f, -67.295f, true);
}
if (Creature* jaina = me->SummonCreature(NPC_JAINA, 1308.862f, 381.809f, -66.044243f, TEMPSUMMON_MANUAL_DESPAWN))
{
JainaGUID = jaina->GetGUID();
jaina->SetImmuneToAll(true);
jaina->SetReactState(REACT_PASSIVE);
}
JumpToNextStep(6 * IN_MILLISECONDS);
break;
// Wrynn Intro
case 148:
if (Creature* wrynn = ObjectAccessor::GetCreature(*me, WrynnGUID))
wrynn->AI()->Talk(WRYNN_SAY_THRONE_5);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 149:
if (Creature* wrynn = ObjectAccessor::GetCreature(*me, WrynnGUID))
wrynn->AI()->Talk(WRYNN_SAY_THRONE_6);
JumpToNextStep(15 * IN_MILLISECONDS);
break;
case 150:
if (Creature* wrynn = ObjectAccessor::GetCreature(*me, WrynnGUID))
wrynn->AI()->Talk(WRYNN_SAY_THRONE_7);
JumpToNextStep(16.5 * IN_MILLISECONDS);
break;
case 151:
if (Creature* wrynn = ObjectAccessor::GetCreature(*me, WrynnGUID))
wrynn->AI()->Talk(WRYNN_SAY_THRONE_8);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
// Wrynn Fight
case 152:
me->SetImmuneToAll(false);
if (Creature* wrynn = ObjectAccessor::GetCreature(*me, WrynnGUID))
{
wrynn->SetImmuneToNPC(false);
wrynn->SetImmuneToPC(true);
wrynn->SetReactState(REACT_AGGRESSIVE);
wrynn->AddThreat(me, 100.0f);
me->AddThreat(wrynn, 100.0f);
wrynn->AI()->AttackStart(me);
}
for (uint8 i = 0; i < ALLIANCE_FORCE_MAXCOUNT; ++i)
{
if (Creature* temp = ObjectAccessor::GetCreature(*me, allianceForcesGUID[i]))
{
temp->SetImmuneToAll(false);
temp->SetReactState(REACT_AGGRESSIVE);
temp->AddThreat(me, 100.0f);
temp->AI()->AttackStart(me);
}
}
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 153:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, JainaGUID))
{
jaina->GetMotionMaster()->MovePoint(0, AllianceWP[9].x, AllianceWP[9].y, AllianceWP[9].z);
jaina->AI()->Talk(JAINA_SAY_THRONE_2);
}
JumpToNextStep(8 * IN_MILLISECONDS);
break;
case 154:
if (Creature* jaina = ObjectAccessor::GetCreature(*me, JainaGUID))
{
jaina->AI()->DoCastAOE(SPELL_DEEPFREEZE);
jaina->AI()->Talk(JAINA_SAY_THRONE_3);
}
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 155:
{
std::list HelperList;
me->GetCreatureListWithEntryInGrid(HelperList, NPC_SW_SOLDIER, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_JAINA, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_WRYNN, 100.0f);
if (!HelperList.empty())
for (std::list::iterator itr = HelperList.begin(); itr != HelperList.end(); itr++)
(*itr)->DespawnOrUnsummon();
JumpToNextStep(8 * IN_MILLISECONDS);
break;
}
case 156:
Talk(THRALL_SAY_THRONE_7);
SetEscortPaused(false);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
case 157:
Talk(THRALL_SAY_THRONE_9);
me->SetStandState(UNIT_STAND_STATE_SIT);
JumpToNextStep(3 * IN_MILLISECONDS);
break;
// Ending
case 158:
if (Creature* saurfang = me->SummonCreature(NPC_OVERLORD_SAURFANG, 1297.574f, 347.154f, -65.027f, TEMPSUMMON_MANUAL_DESPAWN))
{
SaurfangGUID = saurfang->GetGUID();
saurfang->SetWalk(true);
saurfang->GetMotionMaster()->MovePoint(0, 1300.862f, 353.670f, -66.187f, true);
}
JumpToNextStep(7 * IN_MILLISECONDS);
break;
case 159:
if (Creature* saurfang = ObjectAccessor::GetCreature(*me, SaurfangGUID))
{
saurfang->AI()->Talk(SAY_SAURFANG_ARRIVAL_1);
saurfang->SetStandState(UNIT_STAND_STATE_SIT);
}
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 160:
if (Creature* saurfang = ObjectAccessor::GetCreature(*me, SaurfangGUID))
saurfang->AI()->Talk(SAY_SAURFANG_ARRIVAL_2);
JumpToNextStep(6 * IN_MILLISECONDS);
break;
case 161:
if (Creature* saurfang = ObjectAccessor::GetCreature(*me, SaurfangGUID))
saurfang->AI()->Talk(SAY_SAURFANG_ARRIVAL_3);
if (Map* map = me->GetMap())
{
Map::PlayerList const& PlayerList = map->GetPlayers();
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (Player* player = i->GetSource())
{
if (me->IsInRange(player, 0.0f, 50.0f))
{
if (player->GetTeamId() == TEAM_HORDE)
{
player->RemoveAura(SPELL_SYLVANAS_BUFF);
player->RemoveAura(SPELL_THRALL_BUFF);
player->CompleteQuest(QUEST_BATTLE_H);
player->CastSpell(player, SPELL_PHASING_HORDE);
}
}
}
}
}
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 162:
Talk(THRALL_SAY_THRONE_10);
JumpToNextStep(5 * IN_MILLISECONDS);
break;
case 163:
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
Talk(THRALL_SAY_THRONE_11);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_ROYAL_QUARTER_FIGHT_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_INNER_SANCTUM_FIGHT_H, 0);
UpdateWorldState(me->GetMap(), WORLD_STATE_BATTLE_FOR_UNDERCITY_COURTYARD_FIGHT_H, 0);
std::list HelperList;
me->GetCreatureListWithEntryInGrid(HelperList, NPC_SYLVANAS, 100.0f);
me->GetCreatureListWithEntryInGrid(HelperList, NPC_OVERLORD_SAURFANG, 100.0f);
if (!HelperList.empty())
for (std::list::iterator itr = HelperList.begin(); itr != HelperList.end(); itr++)
(*itr)->DespawnOrUnsummon(120 * IN_MILLISECONDS);
me->DespawnOrUnsummon(120 * IN_MILLISECONDS);
bStepping = false;
JumpToNextStep(0 * IN_MILLISECONDS);
break;
}
}
else phaseTimer -= diff;
}
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CHAIN_LIGHTNING:
DoCastVictim(SPELL_CHAIN_LIGHTNING);
_events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5s, 8s);
break;
case EVENT_LAVA_BURST:
DoCastVictim(SPELL_LAVA_BURST);
_events.ScheduleEvent(EVENT_LAVA_BURST, 3s, 5s);
break;
case EVENT_THUNDER:
DoCast(me, SPELL_THUNDER);
_events.ScheduleEvent(EVENT_THUNDER, 15s);
break;
case EVENT_AGGRO_SYLVANAS:
if (me->GetVictim())
if (Creature* sylvanas = ObjectAccessor::GetCreature(*me, sylvanasfollowGUID))
sylvanas->AI()->AttackStart(me->GetVictim());
_events.ScheduleEvent(EVENT_AGGRO_SYLVANAS, 2s);
break;
case EVENT_THRALL_BUFF:
DoCast(me, SPELL_THRALL_BUFF);
_events.ScheduleEvent(EVENT_THRALL_BUFF, 10s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_thrall_bfuAI(creature);
}
};
/*######
## npc_lady_sylvanas_windrunner_bfu
######*/
class npc_lady_sylvanas_windrunner_bfu : public CreatureScript
{
public:
npc_lady_sylvanas_windrunner_bfu() : CreatureScript("npc_lady_sylvanas_windrunner_bfu") { }
struct npc_lady_sylvanas_windrunner_bfuAI : public ScriptedAI
{
npc_lady_sylvanas_windrunner_bfuAI(Creature* creature) : ScriptedAI(creature)
{
Reset();
}
void InitializeAI() override
{
me->Mount(MODEL_SKELETON_MOUNT);
}
void JustRespawned() override
{
me->Mount(MODEL_SKELETON_MOUNT);
}
void Reset() override
{
me->SetCorpseDelay(1);
me->SetRespawnTime(1);
_events.ScheduleEvent(EVENT_BLACK_ARROW, 15s);
_events.ScheduleEvent(EVENT_SHOOT, 5s);
_events.ScheduleEvent(EVENT_MULTI_SHOT, 6s);
_events.ScheduleEvent(EVENT_SHRIEK_OF_HIGHBORN, 3s);
_events.ScheduleEvent(EVENT_SYLVANAS_BUFF, 1s);
me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_WRYNN_BUFF, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_INCREASE_SPEED, true);
}
bool CanAIAttack(Unit const* victim) const override
{
return victim->GetEntry() != NPC_BLIGHT_SLINGER;
}
void UpdateAI(uint32 diff) override
{
if (!me->GetVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BLACK_ARROW:
if (Unit* victim = me->GetVictim())
DoCast(victim, SPELL_BLACK_ARROW);
_events.ScheduleEvent(EVENT_BLACK_ARROW,6s, 9s);
break;
case EVENT_SHOOT:
if (Unit* victim = me->GetVictim())
DoCast(victim, SPELL_SHOT);
_events.ScheduleEvent(EVENT_SHOOT, 5s, 10s);
break;
case EVENT_MULTI_SHOT:
if (Unit* victim = me->GetVictim())
DoCast(victim, SPELL_MULTI_SHOT);
_events.ScheduleEvent(EVENT_MULTI_SHOT, 10s, 13s);
break;
case EVENT_SHRIEK_OF_HIGHBORN:
DoCastVictim(SPELL_SHRIEK_OF_HIGHBORN);
_events.ScheduleEvent(EVENT_SHRIEK_OF_HIGHBORN, 3s);
break;
case EVENT_SYLVANAS_BUFF:
DoCast(me, SPELL_SYLVANAS_BUFF, true);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_lady_sylvanas_windrunner_bfuAI(creature);
}
};
/*######
## AddSC
######*/
void AddSC_undercity()
{
new npc_lady_sylvanas_windrunner();
new npc_highborne_lamenter();
new npc_parqual_fintallas();
new npc_varian_wrynn();
new npc_thrall_bfu();
new npc_jaina_proudmoore_bfu();
new npc_lady_sylvanas_windrunner_bfu();
new boss_blight_worm();
RegisterSpellScript(spell_blight_worm_ingest);
}