Skip to content

Instantly share code, notes, and snippets.

@Sarjuuk
Created September 10, 2011 12:38
Show Gist options
  • Save Sarjuuk/1208260 to your computer and use it in GitHub Desktop.
Save Sarjuuk/1208260 to your computer and use it in GitHub Desktop.
malygos
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
index cc74ce9..59eb2af 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h
@@ -24,49 +24,82 @@ enum InstanceData
MAX_ENCOUNTER,
DATA_VORTEX_HANDLING,
- DATA_POWER_SPARKS_HANDLING
+ DATA_POWER_SPARKS_HANDLING,
+ DATA_LIGHT_HANDLING,
+
+ DATA_INIT,
+ DATA_START,
+ DATA_SUMMON_DEATHS,
+ DATA_PHASE
};
enum InstanceData64
{
- DATA_TRIGGER,
+ DATA_VORTEX,
DATA_MALYGOS,
- DATA_PLATFORM
+ DATA_PLATFORM,
+ DATA_IRIS,
+ DATA_AOI,
+ DATA_SURGE,
+ DATA_PROXY
};
enum InstanceNpcs
{
- NPC_MALYGOS = 28859,
- NPC_VORTEX_TRIGGER = 30090,
- NPC_PORTAL_TRIGGER = 30118,
- NPC_POWER_SPARK = 30084,
- NPC_HOVER_DISK_MELEE = 30234,
- NPC_HOVER_DISK_CASTER = 30248,
- NPC_ARCANE_OVERLOAD = 30282,
- NPC_WYRMREST_SKYTALON = 30161,
- NPC_ALEXSTRASZA = 32295
+ NPC_MALYGOS = 28859,
+ NPC_VORTEX_TRIGGER = 30090,
+ NPC_PORTAL_TRIGGER = 30118,
+ NPC_POWER_SPARK = 30084,
+ NPC_HOVER_DISK_MELEE = 30234,
+ NPC_HOVER_DISK_CASTER = 30248,
+ NPC_ARCANE_OVERLOAD = 30282,
+ NPC_WYRMREST_SKYTALON = 30161,
+ NPC_ALEXSTRASZA = 32295,
+ NPC_ALEXSTRASZA_S_GIFT = 32448,
+ NPC_WORLD_TRIGGER_AOI = 22517,
+ NPC_SURGE_OF_POWER = 30334,
+ NPC_ALEXSTRASZA_PROXY = 31253
};
enum InstanceGameObjects
{
- GO_NEXUS_RAID_PLATFORM = 193070,
- GO_EXIT_PORTAL = 193908,
- GO_FOCUSING_IRIS = 193958,
- GO_ALEXSTRASZA_S_GIFT = 193905,
- GO_ALEXSTRASZA_S_GIFT_2 = 193967
+ GO_NEXUS_RAID_PLATFORM = 193070,
+ GO_EXIT_PORTAL = 193908,
+ GO_FOCUSING_IRIS_10 = 193958,
+ GO_FOCUSING_IRIS_25 = 193960,
+ GO_ALEXSTRASZA_S_GIFT_10 = 193905,
+ GO_ALEXSTRASZA_S_GIFT_25 = 193967,
+ GO_HEART_OF_MAGIC_10 = 194158,
+ GO_HEART_OF_MAGIC_25 = 194159
};
enum InstanceEvents
{
- EVENT_FOCUSING_IRIS = 20711
+ EVENT_FOCUSING_IRIS = 20711
};
enum InstanceSpells
{
- SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle
- SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle
- SPELL_PORTAL_OPENED = 61236,
- SPELL_RIDE_RED_DRAGON = 56071,
+ SPELL_SUMMOM_RED_DRAGON = 56070,
+ SPELL_RIDE_RED_DRAGON = 56071,
+ SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle
+ SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle
+ SPELL_PORTAL_OPENED = 61236
+};
+
+enum InstanceQuests
+{
+ QUEST_JUDGEMENT_10 = 13384,
+ QUEST_JUDGEMENT_25 = 13385
+};
+
+enum InstanceLights
+{
+ LIGHT_NATIVE = 1773,
+ LIGHT_RUNES = 1824,
+ LIGHT_WARP = 1823,
+ LIGHT_RUNES_CLOUDS = 1825,
+ LIGHT_CLOUDS = 1822
};
#endif
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
index 09fe37d..bb48c8f 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
@@ -40,7 +40,12 @@ public:
malygosGUID = 0;
lastPortalGUID = 0;
platformGUID = 0;
+ irisGUID = 0;
exitPortalGUID = 0;
+ worldTriggerGUID = 0;
+ surgeGUID = 0;
+ alexstraszaProxyGUID = 0;
+ currentLight = 1773;
};
bool SetBossState(uint32 type, EncounterState state)
@@ -62,8 +67,11 @@ public:
}
}
- SpawnGameObject(GO_FOCUSING_IRIS, focusingIrisPosition);
- SpawnGameObject(GO_EXIT_PORTAL, exitPortalPosition);
+ if (GameObject* iris = instance->GetGameObject(irisGUID))
+ iris->SetPhaseMask(PHASEMASK_NORMAL, true);
+
+ if (GameObject* exit = instance->GetGameObject(exitPortalGUID))
+ exit->SetPhaseMask(PHASEMASK_NORMAL, true);
if (GameObject* platform = instance->GetGameObject(platformGUID))
platform->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED);
@@ -71,34 +79,35 @@ public:
else if (state == DONE)
{
if (Creature* malygos = instance->GetCreature(malygosGUID))
- malygos->SummonCreature(NPC_ALEXSTRASZA, 829.0679f, 1244.77f, 279.7453f, 2.32f);
-
- SpawnGameObject(GO_EXIT_PORTAL, exitPortalPosition);
+ malygos->SummonCreature(NPC_ALEXSTRASZA, 718.544f, 1358.71f, 304.7453f, 2.32f);
- // we make the platform appear again because at the moment we don't support looting using a vehicle
- if (GameObject* platform = instance->GetGameObject(platformGUID))
- platform->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED);
-
- if (GameObject* chest = instance->GetGameObject(chestGUID))
- chest->SetRespawnTime(7*DAY);
+ if (GameObject* exit = instance->GetGameObject(exitPortalGUID))
+ exit->SetPhaseMask(PHASEMASK_NORMAL, true);
}
}
return true;
}
- // There is no other way afaik...
- void SpawnGameObject(uint32 entry, Position& pos)
+ void OnPlayerEnter(Player* player)
{
- GameObject* go = new GameObject;
- if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, instance,
- PHASEMASK_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(),
- 0, 0, 0, 0, 120, GO_STATE_READY))
- {
- delete go;
+ Creature* malygos = instance->GetCreature(malygosGUID);
+ if (!malygos)
return;
- }
- instance->Add(go);
+ uint32 data = LIGHT_NATIVE << 16;
+ if (GetBossState(DATA_MALYGOS_EVENT) == DONE)
+ data = LIGHT_CLOUDS << 16;
+
+ UpdateLight(data, player);
+
+ if (!malygos->AI()->GetData(DATA_INIT))
+ malygos->AI()->SetData(DATA_INIT, 1);
+
+ if (GetBossState(DATA_MALYGOS_EVENT) == DONE)
+ player->CastSpell(player, SPELL_SUMMOM_RED_DRAGON, true);
+ else
+ if (!player->HasItemCount(45280, 1))
+ player->AddItem(45280, 1);
}
void OnGameObjectCreate(GameObject* go)
@@ -108,16 +117,12 @@ public:
case GO_NEXUS_RAID_PLATFORM:
platformGUID = go->GetGUID();
break;
- case GO_FOCUSING_IRIS:
- go->GetPosition(&focusingIrisPosition);
+ case GO_FOCUSING_IRIS_10:
+ case GO_FOCUSING_IRIS_25:
+ irisGUID = go->GetGUID();
break;
case GO_EXIT_PORTAL:
exitPortalGUID = go->GetGUID();
- go->GetPosition(&exitPortalPosition);
- break;
- case GO_ALEXSTRASZA_S_GIFT:
- case GO_ALEXSTRASZA_S_GIFT_2:
- chestGUID = go->GetGUID();
break;
}
}
@@ -135,22 +140,56 @@ public:
case NPC_PORTAL_TRIGGER:
portalTriggers.push_back(creature->GetGUID());
break;
+ case NPC_WORLD_TRIGGER_AOI:
+ worldTriggerGUID = creature->GetGUID();
+ break;
+ case NPC_SURGE_OF_POWER:
+ surgeGUID = creature->GetGUID();
+ break;
+ case NPC_ALEXSTRASZA_PROXY:
+ alexstraszaProxyGUID = creature->GetGUID();
+ break;
}
}
- void ProcessEvent(WorldObject* obj, uint32 eventId)
+ void ProcessEvent(GameObject* go, uint32 eventId)
{
if (eventId == EVENT_FOCUSING_IRIS)
{
- if (GameObject* go = obj->ToGameObject())
- go->Delete(); // this is not the best way.
-
if (Creature* malygos = instance->GetCreature(malygosGUID))
- malygos->GetMotionMaster()->MovePoint(4, 770.10f, 1275.33f, 267.23f); // MOVE_INIT_PHASE_ONE
+ malygos->AI()->SetData(DATA_START, 1);
if (GameObject* exitPortal = instance->GetGameObject(exitPortalGUID))
- exitPortal->Delete();
+ exitPortal->SetPhaseMask(0x1000, true); // just something out of sight
+ }
+ }
+
+ // eliminate compile warning
+ void ProcessEvent(Unit* /*unit*/, uint32 /*eventId*/)
+ {
+ }
+
+ void UpdateLight(uint32 lightData, Player* player = NULL)
+ {
+ uint32 transition = lightData & 0xFFFF;
+ uint32 newLight = (lightData >> 16);
+
+ if (!player)
+ {
+ if (currentLight == newLight)
+ return;
+
+ currentLight = newLight;
}
+
+ WorldPacket data(SMSG_OVERRIDE_LIGHT, 12);
+ data << uint32(LIGHT_NATIVE);
+ data << newLight;
+ data << transition;
+ if (player)
+ player->GetSession()->SendPacket(&data);
+ else
+ instance->SendToPlayers(&data);
}
void VortexHandling()
@@ -209,7 +248,7 @@ public:
}
}
- void SetData(uint32 data, uint32 /*value*/)
+ void SetData(uint32 data, uint32 value)
{
switch (data)
{
@@ -219,6 +258,9 @@ public:
case DATA_POWER_SPARKS_HANDLING:
PowerSparksHandling();
break;
+ case DATA_LIGHT_HANDLING:
+ UpdateLight(value);
+ break;
}
}
@@ -226,14 +268,21 @@ public:
{
switch (data)
{
- case DATA_TRIGGER:
+ case DATA_VORTEX:
return vortexTriggers.front();
case DATA_MALYGOS:
return malygosGUID;
case DATA_PLATFORM:
return platformGUID;
+ case DATA_IRIS:
+ return irisGUID;
+ case DATA_AOI:
+ return worldTriggerGUID;
+ case DATA_SURGE:
+ return surgeGUID;
+ case DATA_PROXY:
+ return alexstraszaProxyGUID;
}
-
return 0;
}
@@ -286,9 +335,11 @@ public:
uint64 lastPortalGUID;
uint64 platformGUID;
uint64 exitPortalGUID;
- uint64 chestGUID;
- Position focusingIrisPosition;
- Position exitPortalPosition;
+ uint64 irisGUID;
+ uint64 worldTriggerGUID;
+ uint64 surgeGUID;
+ uint64 alexstraszaProxyGUID;
+ uint32 currentLight;
};
};
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 7ecd9c8..8511a4f 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -19,14 +19,6 @@
SDName: Boss malygos
Script Data End */
-// TO-DOs:
-// Implement a better pathing for Malygos.
-// Find sniffed spawn position for chest
-// Implement a better way to disappear the gameobjects
-// Implement achievements
-// Remove hack that re-adds targets to the aggro list after they enter to a vehicle when it works as expected
-// Improve whatever can be improved :)
-
#include "ScriptPCH.h"
#include "eye_of_eternity.h"
#include "ScriptedEscortAI.h"
@@ -34,84 +26,126 @@ Script Data End */
// not implemented
enum Achievements
{
- ACHIEV_TIMED_START_EVENT = 20387,
+ ACHIEV_TIMED_START_EVENT = 20387,
};
enum Events
{
- // =========== PHASE ONE ===============
- EVENT_ARCANE_BREATH = 1,
- EVENT_ARCANE_STORM = 2,
- EVENT_VORTEX = 3,
- EVENT_POWER_SPARKS = 4,
+ // ============= Prefight ==============
+ EVENT_SAY_INTRO_1 = 1,
+ EVENT_SAY_INTRO_2 = 2,
+ EVENT_PREFIGHT_MOVEMENT = 3,
+ EVENT_START_P1 = 4,
- // =========== PHASE TWO ===============
- EVENT_SURGE_POWER = 5, // wowhead is wrong, Surge of Power is casted instead of Arcane Pulse (source sniffs!)
- EVENT_SUMMON_ARCANE = 6,
+ // =========== PHASE ONE ===============
+ EVENT_ARCANE_BREATH = 5,
+ EVENT_ARCANE_STORM = 6,
+ EVENT_PRE_VORTEX = 7,
+ EVENT_EXECUTE_VORTEX = 8,
+ EVENT_POST_VORTEX = 9,
+ EVENT_RESUME_COMBAT = 10,
+ EVENT_POWER_SPARKS = 11,
+ EVENT_START_P2 = 12,
// =========== PHASE TWO ===============
- EVENT_SURGE_POWER_PHASE_3 = 7,
- EVENT_STATIC_FIELD = 8,
-
- // =============== YELLS ===============
- EVENT_YELL_0 = 9,
- EVENT_YELL_1 = 10,
- EVENT_YELL_2 = 11,
- EVENT_YELL_3 = 12,
- EVENT_YELL_4 = 13,
+ EVENT_SUMMON_ARCANE_BOMB = 13,
+ EVENT_PREPARE_POWER_SURGE = 14,
+ EVENT_RESUME_ROTATION = 15,
+ EVENT_FLY_OUT = 16,
+ EVENT_SAY_END_P2 = 17,
+
+ // ======== PREPARE PHASE THREE ========
+ EVENT_PLATTFORM_CHANNEL = 18,
+ EVENT_PLATTFORM_BOOM = 19,
+ EVENT_DESTROY_PLATTFORM = 20,
+ EVENT_SUMMON_RED_DRAKES = 21,
+
+ // ========== PHASE THREE ==============
+ EVENT_SURGE_POWER_P3 = 22,
+ EVENT_STATIC_FIELD = 23,
+ EVENT_ARCANE_PULSE_P3 = 24,
};
enum Phases
{
- PHASE_ONE = 1,
- PHASE_TWO = 2,
- PHASE_THREE = 3
+ PHASE_PREFIGHT = 1,
+ PREPARE_P1 = 2,
+ DO_P1 = 3,
+ PREPARE_P2 = 4,
+ DO_P2 = 5,
+ PREPARE_P3 = 6,
+ DO_P3 = 7
};
enum Spells
{
- SPELL_ARCANE_BREATH = 56272,
- SPELL_ARCANE_STORM = 57459,
- SPELL_BERSEKER = 60670,
+ // ============= Prefight ==============
+ SPELL_BERSEKER = 60670,
+ SPELL_PORTAL_VISUAL_CLOSED = 55949,
+ SPELL_PORTAL_BEAM = 56046,
- SPELL_VORTEX_1 = 56237, // seems that frezze object animation
- SPELL_VORTEX_2 = 55873, // visual effect
- SPELL_VORTEX_3 = 56105, // this spell must handle all the script - casted by the boss and to himself
- //SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle - defined in eye_of_eternity.h
- //SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle - defined in eye_of_eternity.h
- SPELL_VORTEX_6 = 73040, // teleport - (casted to all raid) | caster 30090 | target player
+ // =========== PHASE ONE ===============
+ SPELL_ARCANE_BREATH_10 = 56272,
+ SPELL_ARCANE_STORM_10 = 57459,
+ SPELL_ARCANE_BREATH_25 = 60072,
+ SPELL_ARCANE_STORM_25 = 61694,
+
+ SPELL_VORTEX_1 = 56237, // seems that frezze object animation
+ SPELL_VORTEX_2 = 55873, // visual effect
+ SPELL_VORTEX_3 = 56105, // this spell must handle all the script - casted by the boss and to himself
+ //SPELL_VORTEX_4 = 55853, // damage | used to enter to the vehicle - defined in eye_of_eternity.h
+ //SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle - defined in eye_of_eternity.h
+ SPELL_VORTEX_6 = 73040, // teleport - (casted to all raid) | caster 30090 | target player
+
+ SPELL_SUMMON_POWER_PARK = 56142,
+ SPELL_POWER_SPARK_DEATH = 55852,
+ SPELL_POWER_SPARK_MALYGOS = 56152,
- SPELL_PORTAL_VISUAL_CLOSED = 55949,
- SPELL_SUMMON_POWER_PARK = 56142,
- SPELL_POWER_SPARK_DEATH = 55852,
- SPELL_POWER_SPARK_MALYGOS = 56152,
-
- SPELL_SURGE_POWER = 56505, // used in phase 2
- SPELL_SUMMON_ARCANE_BOMB = 56429,
- SPELL_ARCANE_OVERLOAD = 56432,
- SPELL_SUMMOM_RED_DRAGON = 56070,
- SPELL_SURGE_POWER_PHASE_3 = 57407,
- SPELL_STATIC_FIELD = 57430
+ // =========== PHASE TWO ===============
+ SPELL_SURGE_POWER_P2 = 56505, // used in phase 2
+ SPELL_ARCANE_BOMB_SUMMON = 56429,
+ SPELL_ARCANE_BOMB_MISSILE = 56430,
+ SPELL_ARCANE_BOMB_EFFECT = 56431,
+ SPELL_ARCANE_OVERLOAD = 56432,
+ SPELL_ARCANE_OVERLOAD_SIZE = 56435,
+
+ SPELL_ARCANE_BARRAGE_TRIG = 56397,
+
+ // ========== PHASE THREE ==============
+ SPELL_PLATTFORM_CHANNEL = 58842,
+ SPELL_PLATTFORM_BOOM = 59084,
+ SPELL_SURGE_POWER_P3 = 60936,
+ SPELL_STATIC_FIELD = 57430,
+ SPELL_ARCANE_PULSE = 57432,
+
+ // ========= ALEXSTRASZA OUTRO =========
+
+ SPELL_GIFT_CHANNEL = 61028,
+ SPELL_GIFT_VISUAL = 61023,
+ SPELL_IRIS_OPENED = 61012
};
enum Movements
{
- MOVE_VORTEX = 1,
- MOVE_PHASE_TWO,
- MOVE_DEEP_BREATH_ROTATION,
- MOVE_INIT_PHASE_ONE,
- MOVE_CENTER_PLATFORM
+ MOVE_PORTAL_PREFIGHT = 1,
+ MOVE_VORTEX_START = 2,
+ MOVE_VORTEX_END = 3,
+ MOVE_P2 = 4,
+ MOVE_DEEP_BREATH_ROTATION = 5,
+ MOVE_INIT_P1 = 6,
+ MOVE_CENTER_PLATFORM = 7,
+ MOVE_SURGE_EXECUTION = 8
};
enum Seats
{
- SEAT_0 = 0,
+ SEAT_0 = 0,
};
enum Factions
{
- FACTION_FRIENDLY = 35,
- FACTION_HOSTILE = 14
+ FACTION_FRIENDLY = 35,
+ FACTION_HOSTILE = 14
};
enum Actions
@@ -120,31 +154,29 @@ enum Actions
ACTION_HOVER_DISK_START_WP_2
};
-enum MalygosEvents
-{
- DATA_SUMMON_DEATHS, // phase 2
- DATA_PHASE
-};
-
-#define TEN_MINUTES 600000
-
enum MalygosSays
{
- SAY_AGGRO_P_ONE,
- SAY_KILLED_PLAYER_P_ONE,
- SAY_END_P_ONE,
- SAY_AGGRO_P_TWO,
- SAY_ANTI_MAGIC_SHELL, // not sure when execute it
- SAY_MAGIC_BLAST, // not sure when execute it
- SAY_KILLED_PLAYER_P_TWO,
- SAY_END_P_TWO,
- SAY_INTRO_P_THREE,
- SAY_AGGRO_P_THREE,
- SAY_SURGE_POWER, // not sure when execute it
+ SAY_INTRO_1,
+ SAY_INTRO_2,
+ SAY_AGGRO,
+ SAY_DEEP_BREATH,
+ SAY_KILL_P1,
+ SAY_END_P1,
+ SAY_AGGRO_P2,
+ SAY_ANTI_MAGIC_SHELL, // unused
+ SAY_VORTEX,
+ SAY_KILL_P2,
+ SAY_END_P2,
+ SAY_INTRO_P3,
+ SAY_AGGRO_P3, // unused
+ SAY_SURGE_POWER, // unused
SAY_BUFF_SPARK,
- SAY_KILLED_PLAYER_P_THREE,
- SAY_SPELL_CASTING_P_THREE,
- SAY_DEATH
+ SAY_KILL_P3,
+ SAY_SPELL_CASTING_GENERIC, // unused
+ SAY_DEATH,
+ EMOTE_POWER_SPARK,
+ EMOTE_DEEP_BREATH,
+ EMOTE_SURGE_OF_POWER
};
#define MAX_HOVER_DISK_WAYPOINTS 18
@@ -172,32 +204,32 @@ const Position HoverDiskWaypoints[MAX_HOVER_DISK_WAYPOINTS] =
{782.8365f, 1306.778f, 282.3035f, 0.0f},
};
-#define GROUND_Z 268
+#define GROUND_Z 266.0f
+#define ANIM_OFFSET 20.0f
+#define ANIM_DELAY 2300
// Source: Sniffs (x,y,z)
#define MALYGOS_MAX_WAYPOINTS 16
-const Position MalygosPhaseTwoWaypoints[MALYGOS_MAX_WAYPOINTS] =
+const Position MalygosCirclingWPs[MALYGOS_MAX_WAYPOINTS] =
{
{812.7299f, 1391.672f, 283.2763f, 0.0f},
- {848.2912f, 1358.61f, 283.2763f, 0.0f},
+ {848.2912f, 1358.61f, 283.2763f, 0.0f}, // portal waypoint
{853.9227f, 1307.911f, 283.2763f, 0.0f},
{847.1437f, 1265.538f, 283.2763f, 0.0f},
{839.9229f, 1245.245f, 283.2763f, 0.0f},
- {827.3463f, 1221.818f, 283.2763f, 0.0f},
+ {827.3463f, 1221.818f, 283.2763f, 0.0f}, // portal waypoint (start)
{803.2727f, 1203.851f, 283.2763f, 0.0f},
{772.9372f, 1197.981f, 283.2763f, 0.0f},
{732.1138f, 1200.647f, 283.2763f, 0.0f},
- {693.8761f, 1217.995f, 283.2763f, 0.0f},
+ {693.8761f, 1217.995f, 283.2763f, 0.0f}, // portal waypoint
{664.5038f, 1256.539f, 283.2763f, 0.0f},
{650.1497f, 1303.485f, 283.2763f, 0.0f},
{662.9109f, 1350.291f, 283.2763f, 0.0f},
- {677.6391f, 1377.607f, 283.2763f, 0.0f},
+ {677.6391f, 1377.607f, 283.2763f, 0.0f}, // portal waypoint
{704.8198f, 1401.162f, 283.2763f, 0.0f},
{755.2642f, 1417.1f, 283.2763f, 0.0f},
};
-#define MAX_SUMMONS_PHASE_TWO 4
-
#define MAX_MALYGOS_POS 2
const Position MalygosPositions[MAX_MALYGOS_POS] =
{
@@ -219,127 +251,131 @@ public:
{
boss_malygosAI(Creature* creature) : BossAI(creature, DATA_MALYGOS_EVENT)
{
- // If we enter in combat when MovePoint generator is active, it overrwrites our homeposition
- _homePosition = creature->GetHomePosition();
+ // If we enter in combat when MovePoint generator is active, it overwrites our homeposition
+ homePosition = creature->GetHomePosition();
+ introDone = false;
+ if (Creature* gift = me->FindNearestCreature(NPC_ALEXSTRASZA_S_GIFT, 200.0f))
+ {
+ gift->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ gift->SetFlying(true);
+ }
}
void Reset()
{
_Reset();
- _bersekerTimer = 0;
- _currentPos = 0;
-
- SetPhase(PHASE_ONE, true);
-
- _delayedMovementTimer = 8000;
- _delayedMovement = false;
-
- _summonDeaths = 0;
+ currentPos = 0;
+ preFightWP = 5;
+ summonDeaths = 0;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ SetPhase(PHASE_PREFIGHT, true);
+ instance->SetData(DATA_LIGHT_HANDLING, (LIGHT_NATIVE << 16));
- _cannotMove = true;
+ if (instance)
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+
+ me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetSpeed(MOVE_FLIGHT, 2.5f);
+ me->SetFlying(true);
+ me->GetMotionMaster()->MoveIdle(MOTION_SLOT_IDLE);
}
uint32 GetData(uint32 data)
{
if (data == DATA_SUMMON_DEATHS)
- return _summonDeaths;
+ return summonDeaths;
else if (data == DATA_PHASE)
- return _phase;
+ return phase;
+ else if (data == DATA_INIT)
+ return introDone ? 1 : 0;
return 0;
}
void SetData(uint32 data, uint32 value)
{
- if (data == DATA_SUMMON_DEATHS && _phase == PHASE_TWO)
+ if (data == DATA_INIT)
{
- _summonDeaths = value;
-
- if (_summonDeaths >= MAX_SUMMONS_PHASE_TWO)
- StartPhaseThree();
+ introDone = true;
+ events.ScheduleEvent(EVENT_SAY_INTRO_1, 5 * IN_MILLISECONDS, 0, PHASE_PREFIGHT);
+ events.ScheduleEvent(EVENT_SAY_INTRO_2, 20 * IN_MILLISECONDS, 0, PHASE_PREFIGHT);
+ }
+ else if (data == DATA_START)
+ {
+ InitCombat();
+ }
+ else if (data == DATA_SUMMON_DEATHS && phase == DO_P2)
+ {
+ summonDeaths = value;
+ if (summonDeaths >= RAID_MODE(4, 8))
+ {
+ // this despawns Hover Disks
+ summons.DespawnAll();
+ // players that used Hover Disk are no in the aggro list
+ me->SetInCombatWithZone();
+ me->GetMotionMaster()->MoveIdle();
+ SetPhase(PREPARE_P3, true);
+ instance->SetData(DATA_LIGHT_HANDLING, (LIGHT_WARP << 16));
+ }
}
}
void EnterEvadeMode()
{
- me->SetHomePosition(_homePosition);
-
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetHomePosition(homePosition);
+ HandleRedDrakes(false);
BossAI::EnterEvadeMode();
if (instance)
instance->SetBossState(DATA_MALYGOS_EVENT, FAIL);
+
+ Reset();
}
- void SetPhase(uint8 phase, bool setEvents = false)
+ void SetPhase(uint8 _phase, bool setEvents = false)
{
events.Reset();
- events.SetPhase(phase);
- _phase = phase;
+ events.SetPhase(_phase);
+ phase = _phase;
if (setEvents)
- SetPhaseEvents();
- }
-
- void StartPhaseThree()
- {
- if (!instance)
- return;
-
- SetPhase(PHASE_THREE, true);
-
- // this despawns Hover Disks
- summons.DespawnAll();
- // players that used Hover Disk are no in the aggro list
- me->SetInCombatWithZone();
- std::list<HostileReference*> &m_threatlist = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr)
- {
- if (Unit* target = (*itr)->getTarget())
- {
- if (target->GetTypeId() != TYPEID_PLAYER)
- continue;
-
- // The rest is handled in the AI of the vehicle.
- target->CastSpell(target, SPELL_SUMMOM_RED_DRAGON, true);
- }
- }
-
- if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_PLATFORM)))
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); // In sniffs it has this flag, but i don't know how is applied.
-
- // pos sniffed
- me->GetMotionMaster()->MoveIdle();
- me->GetMotionMaster()->MovePoint(MOVE_CENTER_PLATFORM, MalygosPositions[0].GetPositionX(), MalygosPositions[0].GetPositionY(), MalygosPositions[0].GetPositionZ());
+ SetPhaseEvents(_phase);
}
- void SetPhaseEvents()
+ void SetPhaseEvents(uint8 _phase)
{
switch (_phase)
{
- case PHASE_ONE:
- events.ScheduleEvent(EVENT_ARCANE_BREATH, urand(15, 20)*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_ARCANE_STORM, urand(5, 10)*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_VORTEX, urand(30, 40)*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_POWER_SPARKS, urand(30, 35)*IN_MILLISECONDS, 0, _phase);
+ case PHASE_PREFIGHT:
+ events.ScheduleEvent(EVENT_PREFIGHT_MOVEMENT, 0, 0, _phase);
+ break;
+ case DO_P1:
+ events.ScheduleEvent(EVENT_ARCANE_BREATH, urand(15, 20) * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_ARCANE_STORM, urand( 5, 10) * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_PRE_VORTEX, urand(30, 40) * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_POWER_SPARKS, urand(30, 35) * IN_MILLISECONDS, 0, _phase);
break;
- case PHASE_TWO:
- events.ScheduleEvent(EVENT_YELL_0, 0, 0, _phase);
- events.ScheduleEvent(EVENT_YELL_1, 24*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_SURGE_POWER, urand(60, 70)*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_SUMMON_ARCANE, urand(2, 5)*IN_MILLISECONDS, 0, _phase);
+ case DO_P2:
+ events.ScheduleEvent(EVENT_FLY_OUT, 24 * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_PREPARE_POWER_SURGE, urand(50, 60) * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, 24 * IN_MILLISECONDS, 0, _phase);
break;
- case PHASE_THREE:
- events.ScheduleEvent(EVENT_YELL_2, 0, 0, _phase);
- events.ScheduleEvent(EVENT_YELL_3, 8*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_YELL_4, 16*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_SURGE_POWER_PHASE_3, urand(7, 16)*IN_MILLISECONDS, 0, _phase);
- events.ScheduleEvent(EVENT_STATIC_FIELD, urand(20, 30)*IN_MILLISECONDS, 0, _phase);
+ case PREPARE_P3:
+ events.ScheduleEvent(EVENT_SAY_END_P2, 0 , 0, _phase);
+ events.ScheduleEvent(EVENT_PLATTFORM_CHANNEL, 4 * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_PLATTFORM_BOOM, 9 * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_DESTROY_PLATTFORM, 11 * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_SUMMON_RED_DRAKES, 14 * IN_MILLISECONDS, 0, _phase);
+ break;
+ case DO_P3:
+ events.ScheduleEvent(EVENT_SURGE_POWER_P3, 10 * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_STATIC_FIELD, urand(15, 25) * IN_MILLISECONDS, 0, _phase);
+ events.ScheduleEvent(EVENT_ARCANE_PULSE_P3, 2 * IN_MILLISECONDS, 0, _phase);
break;
default:
break;
@@ -350,10 +386,8 @@ public:
{
_EnterCombat();
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
- Talk(SAY_AGGRO_P_ONE);
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
DoCast(SPELL_BERSEKER);
}
@@ -363,21 +397,21 @@ public:
if (who->GetTypeId() != TYPEID_PLAYER)
return;
- switch (_phase)
+ switch (phase)
{
- case PHASE_ONE:
- Talk(SAY_KILLED_PLAYER_P_ONE);
- break;
- case PHASE_TWO:
- Talk(SAY_KILLED_PLAYER_P_TWO);
- break;
- case PHASE_THREE:
- Talk(SAY_KILLED_PLAYER_P_THREE);
- break;
+ case DO_P1:
+ Talk(SAY_KILL_P1);
+ break;
+ case DO_P2:
+ Talk(SAY_KILL_P2);
+ break;
+ case DO_P3:
+ Talk(SAY_KILL_P3);
+ break;
}
}
- void SpellHit(Unit* caster, const SpellInfo* spell)
+ void SpellHit(Unit* caster, const SpellEntry* spell)
{
if (spell->Id == SPELL_POWER_SPARK_MALYGOS)
{
@@ -396,27 +430,11 @@ public:
if (who->GetEntry() == NPC_POWER_SPARK)
{
// not sure about the distance | I think it is better check this here than in the UpdateAI function...
- if (who->GetDistance(me) <= 2.5f)
- who->CastSpell(me, SPELL_POWER_SPARK_MALYGOS, true);
- }
- }
-
- void PrepareForVortex()
- {
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
-
- me->GetMotionMaster()->MovementExpired();
- me->GetMotionMaster()->MovePoint(MOVE_VORTEX, MalygosPositions[1].GetPositionX(), MalygosPositions[1].GetPositionY(), MalygosPositions[1].GetPositionZ());
- // continues in MovementInform function.
- }
+ if (who->GetDistance(me) <= 0.5f)
+ if (!who->ToCreature()->AI()->GetData(0))
+ who->CastSpell(me, SPELL_POWER_SPARK_MALYGOS, true);
- void ExecuteVortex()
- {
- DoCast(me, SPELL_VORTEX_1, true);
- DoCast(me, SPELL_VORTEX_2, true);
-
- // the vortex execution continues in the dummy effect of this spell (see its script)
- DoCast(me, SPELL_VORTEX_3, true);
+ }
}
void MovementInform(uint32 type, uint32 id)
@@ -426,154 +444,319 @@ public:
switch (id)
{
- case MOVE_VORTEX:
+ case MOVE_PORTAL_PREFIGHT:
+ events.ScheduleEvent(EVENT_PREFIGHT_MOVEMENT, urand(5, 10)*IN_MILLISECONDS);
+ if (Creature* portal = me->FindNearestCreature(NPC_PORTAL_TRIGGER, 50.0f))
+ {
+ me->SetFacing(0, portal);
+ me->CastSpell(portal, SPELL_PORTAL_BEAM, false);
+ }
+ break;
+ case MOVE_INIT_P1:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
me->GetMotionMaster()->MoveIdle();
- ExecuteVortex();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_DOWN);
+ me->SetFlying(false);
+ events.ScheduleEvent(EVENT_START_P1, ANIM_DELAY, 0, PREPARE_P1);
+ break;
+ case MOVE_VORTEX_START:
+ DoCast(me, SPELL_VORTEX_1, true);
+ DoCast(me, SPELL_VORTEX_2, true);
+ // the vortex execution continues in the dummy effect of this spell (see its script)
+ DoCast(me, SPELL_VORTEX_3, true);
+ me->SetFlying(false);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->GetMotionMaster()->MoveIdle();
+ me->HandleEmoteCommand(EMOTE_STATE_CUSTOM_SPELL_01);
+ events.ScheduleEvent(EVENT_POST_VORTEX, 12*IN_MILLISECONDS, 0, DO_P1);
+ break;
+ case MOVE_VORTEX_END:
+ me->GetMotionMaster()->MoveIdle();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_DOWN);
+ me->SetFlying(false);
+ events.ScheduleEvent(EVENT_RESUME_COMBAT, ANIM_DELAY, 0, DO_P1);
break;
case MOVE_DEEP_BREATH_ROTATION:
- _currentPos = _currentPos == MALYGOS_MAX_WAYPOINTS - 1 ? 0 : _currentPos+1;
- me->GetMotionMaster()->MovementExpired();
- me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosPhaseTwoWaypoints[_currentPos]);
+ currentPos = currentPos == MALYGOS_MAX_WAYPOINTS - 1 ? 0 : currentPos+1;
+ me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosCirclingWPs[currentPos]);
break;
- case MOVE_INIT_PHASE_ONE:
- me->SetInCombatWithZone();
+ case MOVE_SURGE_EXECUTION:
+ me->GetMotionMaster()->MoveIdle();
+ me->SetFacing(0, Unit::GetCreature(*me, instance->GetData64(DATA_SURGE)));
+ Talk(EMOTE_DEEP_BREATH);
+ DoCast(SPELL_SURGE_POWER_P2);
+ events.ScheduleEvent(EVENT_RESUME_ROTATION, 8000, 0, DO_P2);
break;
case MOVE_CENTER_PLATFORM:
- _cannotMove = false;
// malygos will move into center of platform and then he does not chase dragons, he just turns to his current target.
+ if (phase == PREPARE_P3)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ SetPhase(DO_P3, true);
+ }
me->GetMotionMaster()->MoveIdle();
break;
}
}
- void StartPhaseTwo()
+ void UpdateAI(uint32 const diff)
{
- SetPhase(PHASE_TWO, true);
-
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
-
- me->GetMotionMaster()->MoveIdle();
- me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosPhaseTwoWaypoints[0]);
-
- Creature* summon = me->SummonCreature(NPC_HOVER_DISK_CASTER, HoverDiskWaypoints[MAX_HOVER_DISK_WAYPOINTS-1]);
- if (summon && summon->IsAIEnabled)
- summon->AI()->DoAction(ACTION_HOVER_DISK_START_WP_2);
- summon = me->SummonCreature(NPC_HOVER_DISK_CASTER, HoverDiskWaypoints[0]);
- if (summon && summon->IsAIEnabled)
- summon->AI()->DoAction(ACTION_HOVER_DISK_START_WP_1);
-
- for (uint8 i = 0; i < 2; i++)
+ // UpdateVictim() conflicts with REACT_PASSIVE and vehicles
+ if (phase >= DO_P1 && !me->getVictim())
{
- // not sure about its position.
- summon = me->SummonCreature(NPC_HOVER_DISK_MELEE, HoverDiskWaypoints[0]);
- if (summon)
- summon->SetInCombatWithZone();
+ // we have curently no target but threatList is not empty .. get new one
+ if (!me->getThreatManager().getThreatList().size())
+ EnterEvadeMode();
+ else
+ me->SelectVictim();
}
- }
-
- void UpdateAI(uint32 const diff)
- {
- if (!UpdateVictim())
- return;
events.Update(diff);
- if (_phase == PHASE_THREE)
- {
- if (!_cannotMove)
- {
- // it can change if the player falls from the vehicle.
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
- {
- me->GetMotionMaster()->MovementExpired();
- me->GetMotionMaster()->MoveIdle();
- }
- } else
- {
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
- {
- me->GetMotionMaster()->MovementExpired();
- me->GetMotionMaster()->MovePoint(MOVE_CENTER_PLATFORM, MalygosPositions[0].GetPositionX(), MalygosPositions[0].GetPositionY(), MalygosPositions[0].GetPositionZ());
- }
- }
- }
+ // the boss is handling vortex
+ if (me->HasAura(SPELL_VORTEX_2))
+ return;
- // we need a better way for pathing
- if (_delayedMovement)
+ if (phase == DO_P3)
{
- if (_delayedMovementTimer <= diff)
+ // it can change if the player falls from the vehicle.
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
{
- me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosPhaseTwoWaypoints[_currentPos]);
- _delayedMovementTimer = 8000;
- _delayedMovement = false;
- } _delayedMovementTimer -= diff;
+ me->GetMotionMaster()->MovementExpired();
+ me->GetMotionMaster()->MoveIdle();
+ }
}
// at 50 % health malygos switch to phase 2
- if (me->GetHealthPct() <= 50.0f && _phase == PHASE_ONE)
- StartPhaseTwo();
+ if (me->GetHealthPct() <= 50.0f && phase == DO_P1)
+ {
+ me->AttackStop();
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MoveIdle();
+ me->SetFlying(true);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP);
- // the boss is handling vortex
- if (me->HasAura(SPELL_VORTEX_2))
- return;
+ SetPhase(PREPARE_P2, true);
+ instance->SetData(DATA_LIGHT_HANDLING, ((LIGHT_RUNES << 16) + 2000));
+ events.ScheduleEvent(EVENT_START_P2, ANIM_DELAY, 0, PREPARE_P2);
+ }
// We can't cast if we are casting already.
- if (me->HasUnitState(UNIT_STAT_CASTING))
+ if (me->HasUnitState(UNIT_STAT_CASTING) && phase != PHASE_PREFIGHT)
return;
+ // mustn't be declared in loop...
+ UnitList surgeTargets;
+ UnitList fieldTargets;
+ float x, y, normal;
+
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_YELL_2:
- Talk(SAY_END_P_TWO);
- break;
- case EVENT_YELL_3:
- Talk(SAY_INTRO_P_THREE);
+ // Prefight
+ case EVENT_SAY_INTRO_1:
+ {
+ Talk(SAY_INTRO_1);
+ break;
+ }
+ case EVENT_SAY_INTRO_2:
+ {
+ Talk(SAY_INTRO_2);
break;
- case EVENT_YELL_4:
- Talk(SAY_AGGRO_P_THREE);
+ }
+ case EVENT_PREFIGHT_MOVEMENT:
+ {
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ me->GetMotionMaster()->MovePoint(MOVE_PORTAL_PREFIGHT, MalygosCirclingWPs[preFightWP].GetPositionX(),
+ MalygosCirclingWPs[preFightWP].GetPositionY(), MalygosCirclingWPs[preFightWP].GetPositionZ()+15.0f);
+ preFightWP = preFightWP <= 4 ? 13 : preFightWP - 4;
break;
- case EVENT_YELL_0:
- Talk(SAY_END_P_ONE);
+ }
+ case EVENT_START_P1:
+ {
+ if (GameObject* iris = instance->instance->GetGameObject(instance->GetData64(DATA_IRIS)))
+ iris->SetPhaseMask(0x1000, true); // random value, just be invisible
+
+ // me->SetPosition(me->GetPositionX(), me->GetPositionY(), GROUND_Z, me->GetOrientation());
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetInCombatWithZone();
+ me->GetMotionMaster()->MoveChase(me->SelectVictim());
+ SetPhase(DO_P1, true);
break;
- case EVENT_YELL_1:
- Talk(SAY_AGGRO_P_TWO);
+ }
+ // Phase 1
+ case EVENT_RESUME_COMBAT:
+ {
+ // me->SetPosition(me->GetPositionX(), me->GetPositionY(), GROUND_Z, me->GetOrientation());
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->Attack(me->SelectVictim(), true);
+ me->GetMotionMaster()->MoveChase(me->SelectVictim());
break;
+ }
case EVENT_ARCANE_BREATH:
- DoCast(me->getVictim(), SPELL_ARCANE_BREATH);
- events.ScheduleEvent(EVENT_ARCANE_BREATH, urand(35, 60)*IN_MILLISECONDS, 0, PHASE_ONE);
+ {
+ DoCast(me->getVictim(), RAID_MODE(SPELL_ARCANE_BREATH_10, SPELL_ARCANE_BREATH_25));
+ events.ScheduleEvent(EVENT_ARCANE_BREATH, urand(35, 60)*IN_MILLISECONDS, 0, DO_P1);
break;
+ }
case EVENT_ARCANE_STORM:
- DoCast(me->getVictim(), SPELL_ARCANE_STORM);
- events.ScheduleEvent(EVENT_ARCANE_STORM, urand(5, 10)*IN_MILLISECONDS, 0, PHASE_ONE);
+ {
+ DoCast(me->getVictim(), RAID_MODE(SPELL_ARCANE_STORM_10, SPELL_ARCANE_STORM_25));
+ events.ScheduleEvent(EVENT_ARCANE_STORM, urand(5, 10)*IN_MILLISECONDS, 0, DO_P1);
break;
- case EVENT_VORTEX:
- PrepareForVortex();
- events.ScheduleEvent(EVENT_VORTEX, urand(60, 80)*IN_MILLISECONDS, 0, PHASE_ONE);
+ }
+ case EVENT_PRE_VORTEX:
+ {
+ Talk(SAY_VORTEX);
+ me->AttackStop();
+ me->SetReactState(REACT_PASSIVE);
+ events.ScheduleEvent(EVENT_PRE_VORTEX, urand(60, 80)*IN_MILLISECONDS, 0, DO_P1);
+ events.ScheduleEvent(EVENT_EXECUTE_VORTEX, ANIM_DELAY, 0, DO_P1);
+ me->GetMotionMaster()->MoveIdle();
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLY_SIT_GROUND_UP);
+ me->SetFlying(true);
+ break;
+ }
+ case EVENT_EXECUTE_VORTEX:
+ {
+ // me->SetPosition(me->GetPositionX(), me->GetPositionY(), GROUND_Z + ANIM_OFFSET, me->GetOrientation());
+ me->GetMotionMaster()->MovePoint(MOVE_VORTEX_START, MalygosPositions[1]);
break;
+ }
+ case EVENT_POST_VORTEX:
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_NONE);
+ me->RemoveAura(SPELL_VORTEX_1);
+ me->SetFlying(true);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->GetMotionMaster()->MovePoint(MOVE_VORTEX_END, MalygosPositions[0].GetPositionX(), MalygosPositions[0].GetPositionY(), GROUND_Z/* + ANIM_OFFSET*/);
+ // do NOT immediately breathe after vortex in 10-man-mode
+ if (RAID_MODE(true, false))
+ events.RescheduleEvent(EVENT_ARCANE_BREATH, urand(10, 25)*IN_MILLISECONDS, 0, DO_P1);
+ break;
+ }
case EVENT_POWER_SPARKS:
+ {
instance->SetData(DATA_POWER_SPARKS_HANDLING, 0);
- events.ScheduleEvent(EVENT_POWER_SPARKS, urand(30, 35)*IN_MILLISECONDS, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_POWER_SPARKS, urand(30, 35)*IN_MILLISECONDS, 0, DO_P1);
break;
- case EVENT_SURGE_POWER:
+ }
+ case EVENT_START_P2:
+ {
+ // me->SetPosition(me->GetPositionX(), me->GetPositionY(), GROUND_Z + ANIM_OFFSET, me->GetOrientation());
+ me->GetMotionMaster()->MovePoint(MOVE_CENTER_PLATFORM, me->GetPositionX(), me->GetPositionY(), MalygosPositions[1].GetPositionZ());
+ Talk(SAY_END_P1);
+ SetPhase(DO_P2, true);
+ break;
+ }
+ // Phase 2
+ case EVENT_FLY_OUT:
+ {
+ Talk(SAY_AGGRO_P2);
me->GetMotionMaster()->MoveIdle();
- _delayedMovement = true;
- DoCast(SPELL_SURGE_POWER);
- events.ScheduleEvent(EVENT_SURGE_POWER, urand(60, 70)*IN_MILLISECONDS, 0, PHASE_TWO);
+ me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION,MalygosCirclingWPs[0]);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ for (uint8 i = 0; i < RAID_MODE(2, 4); i++)
+ {
+ // not sure about its position.
+ Creature* summon = NULL;
+
+ // Caster
+ summon = me->SummonCreature(NPC_HOVER_DISK_CASTER, HoverDiskWaypoints[i*4]);
+ if (summon && summon->IsAIEnabled)
+ summon->AI()->DoAction(i%2 ? ACTION_HOVER_DISK_START_WP_1 : ACTION_HOVER_DISK_START_WP_2);
+
+ // Melee
+ if (summon = me->SummonCreature(NPC_HOVER_DISK_MELEE, HoverDiskWaypoints[i*2]))
+ summon->SetInCombatWithZone();
+ }
+ break;
+ }
+ case EVENT_PREPARE_POWER_SURGE:
+ {
+ // executed in MovementInform
+ Talk(SAY_DEEP_BREATH);
+ // head should be in the center of the plattform, but malygos follws his target
+ x = me->GetPositionX() - MalygosPositions[0].GetPositionX();
+ y = me->GetPositionY() - MalygosPositions[0].GetPositionY();
+ normal = 18.5f / sqrt(pow(x, 2) + pow(y, 2));
+ me->GetMotionMaster()->MovePoint(MOVE_SURGE_EXECUTION, MalygosPositions[0].GetPositionX() + x*normal, MalygosPositions[0].GetPositionY() + y*normal, MalygosPositions[0].GetPositionZ());
+ events.ScheduleEvent(EVENT_PREPARE_POWER_SURGE, urand(60, 70)*IN_MILLISECONDS, 0, DO_P2);
+ break;
+ }
+ case EVENT_RESUME_ROTATION:
+ {
+ me->GetMotionMaster()->MovePoint(MOVE_DEEP_BREATH_ROTATION, MalygosCirclingWPs[currentPos]);
+ break;
+ }
+ case EVENT_SUMMON_ARCANE_BOMB:
+ {
+ DoCast(SPELL_ARCANE_BOMB_SUMMON);
+ events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, urand(12, 15)*IN_MILLISECONDS, 0, DO_P2);
+ break;
+ }
+ // Prepare Phase 3
+ case EVENT_SAY_END_P2:
+ {
+ Talk(SAY_END_P2);
+ break;
+ }
+ // Prepare Phase 3
+ case EVENT_PLATTFORM_CHANNEL:
+ {
+ instance->SetData(DATA_LIGHT_HANDLING, (LIGHT_RUNES_CLOUDS << 16));
+ me->SetFacing(0, Unit::GetCreature(*me, instance->GetData64(DATA_SURGE)));
+ me->CastSpell(me, SPELL_PLATTFORM_CHANNEL, false);
+ break;
+ }
+ case EVENT_PLATTFORM_BOOM:
+ {
+ if (Creature* trigger = Unit::GetCreature(*me, instance->GetData64(DATA_SURGE)))
+ trigger->CastSpell(trigger, SPELL_PLATTFORM_BOOM, false);
+ break;
+ }
+ case EVENT_DESTROY_PLATTFORM:
+ {
+ if (Creature* proxy = Unit::GetCreature(*me, instance->GetData64(DATA_PROXY)))
+ proxy->AI()->Talk(0);
+
+ // pos sniffed
+ me->GetMotionMaster()->MovePoint(MOVE_CENTER_PLATFORM, MalygosPositions[1]);
+ if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_PLATFORM)))
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); // In sniffs it has this flag, but i don't know how is applied.
break;
- case EVENT_SUMMON_ARCANE:
- DoCast(SPELL_SUMMON_ARCANE_BOMB);
- events.ScheduleEvent(EVENT_SUMMON_ARCANE, urand(12, 15)*IN_MILLISECONDS, 0, PHASE_TWO);
+ }
+ case EVENT_SUMMON_RED_DRAKES:
+ {
+ Talk(SAY_INTRO_P3);
+ HandleRedDrakes(true);
break;
- case EVENT_SURGE_POWER_PHASE_3:
- DoCast(GetTargetPhaseThree(), SPELL_SURGE_POWER_PHASE_3);
- events.ScheduleEvent(EVENT_SURGE_POWER_PHASE_3, urand(7, 16)*IN_MILLISECONDS, 0, PHASE_THREE);
+ }
+ // Phase 3
+ case EVENT_SURGE_POWER_P3:
+ {
+ DoCast(SPELL_SURGE_POWER_P3); // target selection and Boss-Warning in SpellScript
+ events.ScheduleEvent(EVENT_SURGE_POWER_P3, 3500, 0, DO_P3);
break;
+ }
+ case EVENT_ARCANE_PULSE_P3:
+ {
+ DoCast(SPELL_ARCANE_PULSE);
+ events.ScheduleEvent(EVENT_ARCANE_PULSE_P3, 1000, 0, DO_P3);
+ break;
+ }
case EVENT_STATIC_FIELD:
- DoCast(GetTargetPhaseThree(), SPELL_STATIC_FIELD);
- events.ScheduleEvent(EVENT_STATIC_FIELD, urand(20, 30)*IN_MILLISECONDS, 0, PHASE_THREE);
+ {
+ fieldTargets = SelectRandomTargets(RAID_MODE(1, 3), true);
+ for (UnitList::iterator itr = fieldTargets.begin(); itr != fieldTargets.end(); ++itr)
+ DoCast((*itr), SPELL_STATIC_FIELD, true);
+ events.ScheduleEvent(EVENT_STATIC_FIELD, urand(20, 30)*IN_MILLISECONDS, 0, DO_P3);
break;
+ }
default:
break;
}
@@ -582,42 +765,320 @@ public:
DoMeleeAttackIfReady();
}
- Unit* GetTargetPhaseThree()
+ UnitList SelectRandomTargets(uint8 maxCount, bool targetVehicle = false)
{
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
+ UnitList temp;
+ UnitList result;
- // we are a drake
- if (target->GetVehicleKit())
- return target;
+ std::list<HostileReference*> &UnitList = me->getThreatManager().getThreatList();
+ if (UnitList.empty())
+ return result;
- // we are a player using a drake (or at least you should)
- if (target->GetTypeId() == TYPEID_PLAYER)
+ for (std::list<HostileReference*>::iterator itr = UnitList.begin(); itr != UnitList.end(); ++itr)
{
- if (Unit* base = target->GetVehicleBase())
- return base;
+ if (Unit* target = (*itr)->getTarget())
+ {
+ if (target->GetTypeId() == TYPEID_UNIT && !target->GetVehicleKit())
+ continue;
+
+ if (targetVehicle)
+ {
+ if (Unit* base = target->GetVehicleBase())
+ temp.push_back(base);
+ else if (target->IsVehicle())
+ temp.push_back(target);
+ }
+ else
+ {
+ if (!target->IsVehicle())
+ temp.push_back(target);
+ else if (Vehicle* kit = target->GetVehicleKit())
+ if (Unit* rider = kit->GetPassenger(SEAT_0))
+ temp.push_back(rider);
+
+ }
+ }
}
- // is a player falling from a vehicle?
- return NULL;
+ UnitList::iterator j;
+ for (uint8 i = 0; i < maxCount; i++)
+ {
+ if (temp.empty())
+ break;
+
+ j = temp.begin();
+ advance(j, rand()%temp.size());
+ result.push_back(*j);
+ temp.erase(j);
+ }
+ return result;
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
_JustDied();
+
+ instance->SetData(DATA_LIGHT_HANDLING, ((LIGHT_CLOUDS << 16) + 2000));
+
+ Map::PlayerList const &PlayerList = instance->instance->GetPlayers();
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (Player* player = i->getSource())
+ {
+ if (player->GetQuestStatus(RAID_MODE(QUEST_JUDGEMENT_10, QUEST_JUDGEMENT_25)) == QUEST_STATUS_INCOMPLETE)
+ {
+ GameObject* go = new GameObject;
+ if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), RAID_MODE(GO_HEART_OF_MAGIC_10, GO_HEART_OF_MAGIC_25), instance->instance, PHASEMASK_NORMAL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), 0, 0, 0, 0, 120, GO_STATE_READY))
+ delete go;
+ instance->instance->Add(go);
+ break;
+ }
+
+ }
+ }
+ }
+
+ void InitCombat()
+ {
+ SetPhase(PREPARE_P1, true);
+
+ Talk(SAY_AGGRO);
+
+ if (Creature* trigger = Unit::GetCreature(*me, instance->GetData64(DATA_AOI)))
+ trigger->CastSpell(trigger, SPELL_IRIS_OPENED, true);
+
+ // center: 754.544f, 1301.71f, landing on radius: ~31.0
+ float x = me->GetPositionX() - MalygosPositions[0].GetPositionX();
+ float y = me->GetPositionY() - MalygosPositions[0].GetPositionY();
+ float normal = 31.0f / sqrt(pow(x, 2) + pow(y, 2));
+ me->GetMotionMaster()->MovePoint(MOVE_INIT_P1, MalygosPositions[0].GetPositionX() + x*normal, MalygosPositions[0].GetPositionY() + y*normal, GROUND_Z /*+ANIM_OFFSET*/);
+ }
+
+ void HandleRedDrakes(bool apply)
+ {
+std::ostringstream ss;
+ss << "summonign drakes";
+me->MonsterSay(ss.str().c_str(), LANG_UNIVERSAL, 0);
+
+ Map::PlayerList const &PlayerList = instance->instance->GetPlayers();
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (Player* player = i->getSource())
+ {
+ if (player->isAlive())
+ {
+ if (apply)
+ player->CastSpell(player, SPELL_SUMMOM_RED_DRAGON, true);
+ else
+ player->ExitVehicle();
+ }
+ }
+ }
+ }
}
private:
- uint8 _phase;
- uint32 _bersekerTimer;
- uint8 _currentPos; // used for phase 2 rotation...
- bool _delayedMovement; // used in phase 2.
- uint32 _delayedMovementTimer; // used in phase 2
- uint8 _summonDeaths;
- Position _homePosition; // it can get bugged because core thinks we are pathing
- bool _mustTalk;
- bool _cannotMove;
+ uint8 phase;
+ uint8 preFightWP;
+ uint8 currentPos; // used for phase 2 rotation...
+ uint8 summonDeaths;
+ Position homePosition; // it can get bugged because core thinks we are pathing
+ bool introDone;
+ };
+
+};
+
+class spell_malygos_surge_of_power_p3 : public SpellScriptLoader
+{
+public:
+ spell_malygos_surge_of_power_p3() : SpellScriptLoader("spell_malygos_surge_of_power_p3") {}
+
+ class spell_malygos_surge_of_power_p3_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_malygos_surge_of_power_p3_SpellScript)
+
+ void FilterTargets(std::list<Unit*>& unitList)
+ {
+ Unit* caster = GetCaster();
+ if (!caster || !caster->IsAIEnabled)
+ return;
+
+ uint8 numTargets = caster->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL ? 3 : 1;
+ unitList = CAST_AI(boss_malygos::boss_malygosAI, (caster->ToCreature()->AI()))->SelectRandomTargets(numTargets, true);
+ for (UnitList::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
+ caster->ToCreature()->AI()->Talk(EMOTE_SURGE_OF_POWER, (*itr)->GetVehicleKit()->GetPassenger(SEAT_0)->GetGUID());
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_malygos_surge_of_power_p3_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
+ }
+ };
+
+ SpellScript *GetSpellScript() const
+ {
+ return new spell_malygos_surge_of_power_p3_SpellScript();
+ }
+};
+
+class spell_malygos_arcane_storm : public SpellScriptLoader
+{
+public:
+ spell_malygos_arcane_storm() : SpellScriptLoader("spell_malygos_arcane_storm") {}
+
+ class spell_malygos_arcane_storm_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_malygos_arcane_storm_SpellScript)
+
+ void FilterTargets(std::list<Unit*>& unitList)
+ {
+ Unit* caster = GetCaster();
+ if (!caster || !caster->IsAIEnabled)
+ return;
+
+ uint8 numTargets = caster->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL ? urand(7, 9) : urand(1, 3);
+ unitList = CAST_AI(boss_malygos::boss_malygosAI, (caster->ToCreature()->AI()))->SelectRandomTargets(numTargets);
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_malygos_arcane_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
+ }
+ };
+
+ SpellScript *GetSpellScript() const
+ {
+ return new spell_malygos_arcane_storm_SpellScript();
+ }
+};
+
+class spell_malygos_arcane_barrage : public SpellScriptLoader
+{
+public:
+ spell_malygos_arcane_barrage() : SpellScriptLoader("spell_malygos_arcane_barrage") {}
+
+ class spell_malygos_arcane_barrage_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_malygos_arcane_barrage_SpellScript)
+
+ bool heroic;
+
+ bool Load()
+ {
+ heroic = false;
+ if (Unit* caster = GetCaster())
+ heroic = caster->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL;
+
+ return true;
+ }
+
+ void FilterTargets(std::list<Unit*>& unitList)
+ {
+ if (GetSpellInfo()->Id != SPELL_ARCANE_BARRAGE_TRIG)
+ return;
+
+ if (Unit* caster = GetCaster())
+ if (InstanceScript* iScript = caster->GetInstanceScript())
+ if (Creature* malygos = Unit::GetCreature(*caster, iScript->GetData64(DATA_MALYGOS)))
+ unitList = CAST_AI(boss_malygos::boss_malygosAI, (malygos->AI()))->SelectRandomTargets(heroic ? 3 : 1);
+ }
+
+ void DoHeroicDamage()
+ {
+ if (heroic && GetSpellInfo()->Id != SPELL_ARCANE_BARRAGE_TRIG)
+ SetHitDamage(int32(GetHitDamage() * 1.2f));
+ }
+
+ void Register()
+ {
+ OnHit += SpellHitFn(spell_malygos_arcane_barrage_SpellScript::DoHeroicDamage);
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_malygos_arcane_barrage_SpellScript::FilterTargets, EFFECT_0, TARGET_SRC_CASTER);
+ }
};
+
+ SpellScript *GetSpellScript() const
+ {
+ return new spell_malygos_arcane_barrage_SpellScript();
+ }
+};
+
+class spell_malygos_arcane_overload : public SpellScriptLoader
+{
+public:
+ spell_malygos_arcane_overload() : SpellScriptLoader("spell_malygos_arcane_overload") {}
+
+ class spell_malygos_arcane_overload_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_malygos_arcane_overload_SpellScript)
+
+ void FilterTargets(std::list<Unit*>& targetList)
+ {
+ uint8 stack = 50;
+ Unit* caster = GetCaster();
+
+ if (!caster)
+ return;
+
+ if (Aura* aur = caster->GetAura(SPELL_ARCANE_OVERLOAD_SIZE))
+ stack -= aur->GetStackAmount();
+
+ for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();)
+ {
+ if (caster->GetExactDist((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ()) > ((stack / 50.0f) * 18.0f))
+ itr = targetList.erase(itr);
+ else
+ itr++;
+ }
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_malygos_arcane_overload_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_malygos_arcane_overload_SpellScript();
+ }
+};
+
+class spell_malygos_surge_of_power : public SpellScriptLoader
+{
+public:
+ spell_malygos_surge_of_power() : SpellScriptLoader("spell_malygos_surge_of_power") {}
+
+ class spell_malygos_surge_of_power_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_malygos_surge_of_power_SpellScript)
+
+ void FilterTargets(std::list<Unit*>& targetList)
+ {
+ for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();)
+ {
+ if ((*itr)->ToCreature() || (*itr)->ToPlayer()->GetVehicle())
+ itr = targetList.erase(itr);
+ else
+ itr++;
+ }
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_malygos_surge_of_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_malygos_surge_of_power_SpellScript();
+ }
};
class spell_malygos_vortex_dummy : public SpellScriptLoader
@@ -632,7 +1093,6 @@ public:
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
-
if (!caster)
return;
@@ -682,7 +1142,7 @@ class spell_malygos_vortex_visual : public SpellScriptLoader
if (InstanceScript* instance = caster->GetInstanceScript())
{
// teleport spell - i am not sure but might be it must be casted by each vehicle when its passenger leaves it
- if (Creature* trigger = caster->GetMap()->GetCreature(instance->GetData64(DATA_TRIGGER)))
+ if (Creature* trigger = caster->GetMap()->GetCreature(instance->GetData64(DATA_VORTEX)))
trigger->CastSpell(targetPlayer, SPELL_VORTEX_6, true);
}
}
@@ -693,11 +1153,6 @@ class spell_malygos_vortex_visual : public SpellScriptLoader
// This is a hack, we have to re add players to the threat list because when they enter to the vehicles they are removed.
// Anyway even with this issue, the boss does not enter in evade mode - this prevents iterate an empty list in the next vortex execution.
malygos->SetInCombatWithZone();
-
- malygos->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
-
- malygos->GetMotionMaster()->MoveChase(caster->getVictim());
- malygos->RemoveAura(SPELL_VORTEX_1);
}
}
@@ -729,41 +1184,49 @@ public:
{
npc_portal_eoeAI(Creature* creature) : ScriptedAI(creature)
{
- _instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
void Reset()
{
- _summonTimer = urand(5, 7)*IN_MILLISECONDS;
+ summonTimer = urand(5, 7)*IN_MILLISECONDS;
+ active = true;
}
void UpdateAI(uint32 const diff)
{
- if (!me->HasAura(SPELL_PORTAL_VISUAL_CLOSED) &&
- !me->HasAura(SPELL_PORTAL_OPENED))
- DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
+ if (!instance)
+ return;
- if (_instance)
+ Creature* malygos = Unit::GetCreature(*me, instance->GetData64(DATA_MALYGOS));
+ if (!malygos)
+ return;
+
+ if (malygos->AI()->GetData(DATA_PHASE) > DO_P1)
{
- if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
- {
- if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE)
- {
- me->RemoveAura(SPELL_PORTAL_OPENED);
- DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
- }
- }
+ active = false;
+ me->RemoveAllAuras();
}
+ else
+ active = true;
+
+ if (!active)
+ return;
+
+ if (!me->HasAura(SPELL_PORTAL_VISUAL_CLOSED) && !me->HasAura(SPELL_PORTAL_OPENED))
+ DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
if (!me->HasAura(SPELL_PORTAL_OPENED))
return;
- if (_summonTimer <= diff)
+ if (summonTimer <= diff)
{
DoCast(SPELL_SUMMON_POWER_PARK);
- _summonTimer = urand(5, 7)*IN_MILLISECONDS;
- } else
- _summonTimer -= diff;
+ malygos->AI()->Talk(EMOTE_POWER_SPARK);
+ DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
+ me->RemoveAura(SPELL_PORTAL_OPENED);
+ summonTimer = urand(5, 7)*IN_MILLISECONDS;
+ } else summonTimer -= diff;
}
void JustSummoned(Creature* summon)
@@ -772,12 +1235,12 @@ public:
}
private:
- uint32 _summonTimer;
- InstanceScript* _instance;
+ bool active;
+ uint32 summonTimer;
+ InstanceScript* instance;
};
};
-
class npc_power_spark: public CreatureScript
{
public:
@@ -792,9 +1255,16 @@ public:
{
npc_power_sparkAI(Creature* creature) : ScriptedAI(creature)
{
- _instance = creature->GetInstanceScript();
+ me->SetReactState(REACT_PASSIVE);
+
+ if (instance = creature->GetInstanceScript())
+ {
+ me->GetMotionMaster()->MoveIdle();
+ if (Creature* malygos = Unit::GetCreature(*me, instance->GetData64(DATA_MALYGOS)))
+ me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
+ }
- MoveToMalygos();
+ isDead = false;
}
void EnterEvadeMode()
@@ -802,25 +1272,19 @@ public:
me->DespawnOrUnsummon();
}
- void MoveToMalygos()
+ uint32 GetData(uint32 /*data*/)
{
- me->GetMotionMaster()->MoveIdle();
-
- if (_instance)
- {
- if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
- me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
- }
+ return isDead ? 1 : 0;
}
void UpdateAI(uint32 const /*diff*/)
{
- if (!_instance)
+ if (!instance)
return;
- if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = Unit::GetCreature(*me, instance->GetData64(DATA_MALYGOS)))
{
- if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE)
+ if (malygos->AI()->GetData(DATA_PHASE) != DO_P1)
{
me->DespawnOrUnsummon();
return;
@@ -828,27 +1292,34 @@ public:
if (malygos->HasAura(SPELL_VORTEX_1))
{
- me->GetMotionMaster()->MoveIdle();
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
+ me->GetMotionMaster()->MoveIdle();
return;
}
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
- me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
+ if (!isDead && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
}
}
void DamageTaken(Unit* /*done_by*/, uint32& damage)
{
- if (damage > me->GetMaxHealth())
+ if (damage > me->GetHealth())
{
damage = 0;
+ isDead = true;
+ me->RemoveAllAuras();
+ me->GetMotionMaster()->MoveFall(GROUND_Z);
+ me->GetMotionMaster()->MoveIdle();
DoCast(me, SPELL_POWER_SPARK_DEATH, true);
- me->DespawnOrUnsummon(1000);
+ me->DespawnOrUnsummon(60000);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
}
}
private:
- InstanceScript* _instance;
+ InstanceScript* instance;
+ bool isDead;
};
};
@@ -868,10 +1339,13 @@ public:
{
if (me->GetEntry() == NPC_HOVER_DISK_CASTER)
me->SetReactState(REACT_PASSIVE);
- else
+ else
me->SetInCombatWithZone();
- _instance = creature->GetInstanceScript();
+ me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
+
+ instance = creature->GetInstanceScript();
+ rider = NULL;
}
void PassengerBoarded(Unit* unit, int8 /*seat*/, bool apply)
@@ -880,6 +1354,7 @@ public:
{
if (unit->GetTypeId() == TYPEID_UNIT)
{
+ rider = unit->ToCreature();
me->setFaction(FACTION_HOSTILE);
unit->ToCreature()->SetInCombatWithZone();
}
@@ -887,30 +1362,25 @@ public:
else
{
// Error found: This is not called if the passenger is a player
-
if (unit->GetTypeId() == TYPEID_UNIT)
{
// This will only be called if the passenger dies
- if (_instance)
- {
- if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
+ if (instance)
+ if (Creature* malygos = Unit::GetCreature(*me, instance->GetData64(DATA_MALYGOS)))
malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS)+1);
- }
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ rider = NULL;
+ SetEscortPaused(true);
}
me->GetMotionMaster()->MoveIdle();
-
- if (me->GetEntry() == NPC_HOVER_DISK_MELEE || me->GetEntry() == NPC_HOVER_DISK_CASTER)
- {
- // Hack: Fall ground function can fail (remember the platform is a gameobject), we will teleport the disk to the ground
- if (me->GetPositionZ() > GROUND_Z)
- me->NearTeleportTo(me->GetPositionX(), me->GetPositionY(), GROUND_Z, 0);
- me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
- me->setFaction(FACTION_FRIENDLY);
- me->AI()->EnterEvadeMode();
- }
+ if (me->GetPositionZ() > GROUND_Z)
+ me->GetMotionMaster()->MoveFall(GROUND_Z);
+ me->SetFlying(true);
+ me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
+ me->setFaction(FACTION_FRIENDLY);
+ me->AI()->EnterEvadeMode();
}
}
@@ -947,8 +1417,32 @@ public:
Start(true, false, 0, 0, false, true);
}
+ void UpdateAI(const uint32 /*diff*/)
+ {
+// npc_escortAI::UpdateAI(diff);
+ if (me->GetEntry() == NPC_HOVER_DISK_MELEE)
+ {
+ if (rider && me->getVictim() != rider->getVictim())
+ {
+ me->getThreatManager().resetAllAggro();
+ me->AddThreat(rider->getVictim(), 1000000.0f);
+ }
+ }
+ }
+
+
void UpdateEscortAI(const uint32 /*diff*/)
{
+/*
+ if (me->GetEntry() == NPC_HOVER_DISK_MELEE)
+ {
+ if (rider && me->getVictim() != rider->getVictim())
+ {
+ me->getThreatManager().resetAllAggro();
+ me->AddThreat(rider->getVictim(), 1000000.0f);
+ }
+ }
+*/
// we dont do melee damage!
}
@@ -957,11 +1451,11 @@ public:
}
private:
- InstanceScript* _instance;
+ Creature* rider;
+ InstanceScript* instance;
};
};
-
// The reason of this AI is to make the creature able to enter in combat otherwise the spell casting of SPELL_ARCANE_OVERLOAD fails.
class npc_arcane_overload : public CreatureScript
{
@@ -984,14 +1478,36 @@ public:
void Reset()
{
- DoCast(me, SPELL_ARCANE_OVERLOAD, false);
+ delay = 1000; // cast animation is not played if the model still 'animates in'
+ me->DespawnOrUnsummon(50*IN_MILLISECONDS);
}
- void UpdateAI(uint32 const /*diff*/)
+ void UpdateAI(uint32 const diff)
{
+ if (delay <= diff && delay > 0)
+ {
+ delay = 0;
+ if (InstanceScript* instance = me->GetInstanceScript())
+ if (Creature* malygos = Unit::GetCreature(*me, instance->GetData64(DATA_MALYGOS)))
+ malygos->CastSpell(me, SPELL_ARCANE_BOMB_MISSILE, true);
+ }
+ else
+ delay -=diff;
+
// we dont do melee damage!
}
+ void SpellHit(Unit* /*caster*/, SpellEntry const* spell)
+ {
+ if (spell->Id == SPELL_ARCANE_BOMB_MISSILE)
+ {
+ me->CastSpell(me, SPELL_ARCANE_BOMB_EFFECT, true);
+ me->CastSpell(me, SPELL_ARCANE_OVERLOAD, true);
+ }
+ }
+
+ private:
+ uint16 delay;
};
};
@@ -1010,13 +1526,20 @@ public:
{
npc_wyrmrest_skytalonAI(Creature* creature) : NullCreatureAI(creature)
{
- _instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
- _timer = 1000;
- _entered = false;
+ timer = 1000;
+ entered = false;
}
- void PassengerBoarded(Unit* /*unit*/, int8 /*seat*/, bool apply)
+ void IsSummonedBy(Unit* summoner)
+ {
+ if (InstanceScript* script = me->GetInstanceScript())
+ if (script->GetBossState(0) == IN_PROGRESS) // DATA_EVENT_MALYGOS == 0
+ me->SetPosition(summoner->GetPositionX(), summoner->GetPositionY(), summoner->GetPositionZ()-40.0f, summoner->GetOrientation());
+ }
+
+ void PassengerBoarded(Unit* unit, int8 /*seat*/, bool apply)
{
if (!apply)
me->DespawnOrUnsummon();
@@ -1025,39 +1548,37 @@ public:
// we can't call this in reset function, it fails.
void MakePlayerEnter()
{
- if (!_instance)
+ if (!instance)
return;
if (Unit* summoner = me->ToTempSummon()->GetSummoner())
{
- if (Creature* malygos = Unit::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = Unit::GetCreature(*me, instance->GetData64(DATA_MALYGOS)))
{
summoner->CastSpell(me, SPELL_RIDE_RED_DRAGON, true);
- float victimThreat = malygos->getThreatManager().getThreat(summoner);
- malygos->getThreatManager().resetAllAggro();
- malygos->AI()->AttackStart(me);
- malygos->AddThreat(me, victimThreat);
+ float victim_threat = malygos->getThreatManager().getThreat(summoner);
+ malygos->Attack(me, true);
+ malygos->AddThreat(me, victim_threat);
}
}
}
void UpdateAI(const uint32 diff)
{
- if (!_entered)
+ if (!entered)
{
- if (_timer <= diff)
+ if (timer <= diff)
{
MakePlayerEnter();
- _entered = true;
- } else
- _timer -= diff;
+ entered = true;
+ } else timer -= diff;
}
}
private:
- InstanceScript* _instance;
- uint32 _timer;
- bool _entered;
+ InstanceScript* instance;
+ uint32 timer;
+ bool entered;
};
};
@@ -1069,10 +1590,19 @@ enum AlexstraszaYells
SAY_FOUR
};
+enum AlexstraszaEvents
+{
+ EVENT_MOVE_IN = 1,
+ EVENT_CREATE_GIFT = 2,
+ EVENT_SAY_ONE = 3,
+ EVENT_SAY_TWO = 4,
+ EVENT_SAY_THREE = 5,
+ EVENT_SAY_FOUR = 6
+};
class npc_alexstrasza_eoe : public CreatureScript
{
public:
- npc_alexstrasza_eoe() : CreatureScript("npc_alexstrasza_eoe") {}
+ npc_alexstrasza_eoe() : CreatureScript("npc_alexstrasza_eoe") { }
CreatureAI* GetAI(Creature* creature) const
{
@@ -1083,45 +1613,72 @@ public:
{
npc_alexstrasza_eoeAI(Creature* creature) : ScriptedAI(creature) {}
+ Creature* gift;
+
void Reset()
{
- _events.Reset();
- _events.ScheduleEvent(EVENT_YELL_1, 0);
+ me->SetFlying(true);
+ me->SetSpeed(MOVE_FLIGHT, 2.0f);
+ events.Reset();
+ events.ScheduleEvent(EVENT_MOVE_IN, 0);
+ gift = me->FindNearestCreature(NPC_ALEXSTRASZA_S_GIFT, 200.0f);
}
- void UpdateAI(uint32 const /*diff*/)
+ void UpdateAI(uint32 const diff)
{
- while (uint32 eventId = _events.ExecuteEvent())
+ events.Update(diff);
+ while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_YELL_1:
+ case EVENT_MOVE_IN:
+ me->GetMotionMaster()->MovePoint(0, 788.254761f, 1326.236938f, 227.795822f);
+ events.ScheduleEvent(EVENT_CREATE_GIFT, 8*IN_MILLISECONDS);
+ break;
+ case EVENT_CREATE_GIFT:
+ me->SetFacing(0, gift);
+ DoCast(gift, SPELL_GIFT_VISUAL, true);
+ DoCast(gift, SPELL_GIFT_CHANNEL);
+ events.ScheduleEvent(EVENT_SAY_ONE, 2*IN_MILLISECONDS);
+ break;
+ case EVENT_SAY_ONE:
+ if (gift)
+ {
+ if (InstanceScript* script = me->GetInstanceScript())
+ {
+ GameObject* go = new GameObject;
+ if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), RAID_MODE(GO_ALEXSTRASZA_S_GIFT_10, GO_ALEXSTRASZA_S_GIFT_25), script->instance, PHASEMASK_NORMAL, gift->GetPositionX(), gift->GetPositionY(), gift->GetPositionZ(), gift->GetOrientation(), 0, 0, 0, 0, 120, GO_STATE_READY))
+ delete go;
+ script->instance->Add(go);
+ }
+ }
Talk(SAY_ONE);
- _events.ScheduleEvent(EVENT_YELL_2, 4*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SAY_TWO, 4*IN_MILLISECONDS);
break;
- case EVENT_YELL_2:
+ case EVENT_SAY_TWO:
Talk(SAY_TWO);
- _events.ScheduleEvent(EVENT_YELL_3, 4*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SAY_THREE, 4*IN_MILLISECONDS);
break;
- case EVENT_YELL_3:
+ case EVENT_SAY_THREE:
Talk(SAY_THREE);
- _events.ScheduleEvent(EVENT_YELL_4, 7*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SAY_FOUR, 7*IN_MILLISECONDS);
break;
- case EVENT_YELL_4:
+ case EVENT_SAY_FOUR:
Talk(SAY_FOUR);
break;
}
}
}
+
private:
- EventMap _events;
+ EventMap events;
};
};
class achievement_denyin_the_scion : public AchievementCriteriaScript
{
public:
- achievement_denyin_the_scion() : AchievementCriteriaScript("achievement_denyin_the_scion") {}
+ achievement_denyin_the_scion() : AchievementCriteriaScript("achievement_denyin_the_scion") { }
bool OnCheck(Player* source, Unit* /*target*/)
{
@@ -1140,8 +1697,13 @@ void AddSC_boss_malygos()
new npc_hover_disk();
new npc_arcane_overload();
new npc_wyrmrest_skytalon();
+ new npc_alexstrasza_eoe();
+ new spell_malygos_arcane_overload();
+ new spell_malygos_surge_of_power();
new spell_malygos_vortex_dummy();
new spell_malygos_vortex_visual();
- new npc_alexstrasza_eoe();
+ new spell_malygos_arcane_barrage();
+ new spell_malygos_arcane_storm();
+ new spell_malygos_surge_of_power_p3();
new achievement_denyin_the_scion();
}
-- update "Denying the Scion 10/25"
DELETE FROM achievement_criteria_data WHERE criteria_id IN (7573,7574) AND type=12;
INSERT INTO achievement_criteria_data VALUES (7573,12,0,0,''),(7574,12,1,0,'');
-- Spellscripts (mostyl target selection)
DELETE FROM spell_script_names WHERE spell_id IN (56548,56397,63934,57459,61694,60936);
INSERT INTO spell_script_names VALUES
(56548,'spell_malygos_surge_of_power'),
(56397,'spell_malygos_arcane_barrage'),
(63934,'spell_malygos_arcane_barrage'),
(57459,'spell_malygos_arcane_storm'),
(61694,'spell_malygos_arcane_storm'),
(60936,'spell_malygos_surge_of_power_p3');
-- condition for gift-beam-visual
DELETE FROM conditions WHERE SourceTypeOrReferenceId=13 AND SourceEntry=61028;
INSERT INTO conditions VALUES (13,0,61028,0,18,1,32448,0,0,'','Eye of Eternity: Alexstrasza Gift Beam targeting');
-- remove already spawned containers
DELETE FROM gameobject WHERE id IN (193905,193967,194158,194159);
-- disable LoS for Eye of Eternity
DELETE FROM disables WHERE sourceType=6 AND entry=616;
INSERT INTO disables VALUES (6,616,0x4,0,0,'Eye of Eternity - Line of Sight');
-- add SmartScript to Static Fields so they despawn in time
UPDATE creature_template SET AIName='SmartAI' WHERE entry=30592;
DELETE FROM smart_scripts WHERE entryOrGuid=30592;
INSERT INTO smart_scripts VALUES (30592,0,0,0,54,0,100,0,0,0,0,0,41,20000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Static Field - Despawn after 20sec');
-- MachanicImmunity to Malygos .. knockback..?
UPDATE creature_template SET mechanic_immune_mask = 0x24CB3F7F WHERE entry IN (28859, 31734);
-- was 0x0
-- give energy sparks a visible aura
DELETE FROM creature_template_addon WHERE entry IN (30084,32187);
INSERT INTO creature_template_addon (entry,auras) VALUES (30084,55845),(32187,55845);
-- sparks should fly (Eri)
UPDATE creature_template SET InhabitType=7 WHERE entry IN (30084,32187);
-- was InhabitType=1
-- move areatrigger to new location for open iris animation
UPDATE creature SET position_x=754.228882,position_y=1301.886230,position_z=277.580750 WHERE guid=132315;
-- war .. vermutlich mal identisch mit der Iris
-- the gift-trigger-npc should not move
UPDATE creature SET MovementType=0 WHERE id=32448;
-- make heroic hover discs hover in a heroic fashion
UPDATE creature_template SET InhabitType=5 WHERE entry IN (31748,31749);
-- war InhabitType=3
-- make vortex-trigger invisible
UPDATE creature_template SET modelid2=0 WHERE entry=30090;
-- war n infernal wie die anderen trigger auch
-- Update Malygos Melee to 10:~35k 25:~45k
UPDATE creature_template SET mindmg=892, maxdmg=1208 WHERE entry=28859;
UPDATE creature_template SET mindmg=1165, maxdmg=1576 WHERE entry=31734;
-- war 10:496-674 25:509-683
-- Add sound to mute Alexstrasza
UPDATE creature_text SET sound=14406 WHERE entry=32295 AND groupid=0;
UPDATE creature_text SET sound=14407 WHERE entry=32295 AND groupid=1;
UPDATE creature_text SET sound=14408 WHERE entry=32295 AND groupid=2;
UPDATE creature_text SET sound=14409 WHERE entry=32295 AND groupid=3;
DELETE FROM creature_text WHERE entry=31253;
INSERT INTO creature_text VALUES (31253,0,0,'Champions! My children, blessed with my powers, shall aid you in your fight!',14,0,0,0,0,14405,'Alexstrasza (Proxy) - Spawn Drakes');
-- Redo Malygos text
DELETE FROM creature_text WHERE entry=28859;
INSERT INTO creature_text VALUES
(28859,0,0,'Lesser beings, intruding here! A shame that your excess courage does not compensate for your stupidity!',14,0,50,0,0,14512,'Malygos - Yell: Intro 1'),
(28859,0,1,'None but the blue dragonflight are welcome here. Perhaps this is the work of Alexstrasza? Well, then, she has sent you to your deaths!',14,0,50,0,0,14513,'Malygos - Yell: Intro 1'),
(28859,1,0,'What could you hope to accomplish? To storm brazenly into my domain... to employ magic... against ME?',14,0,34,0,0,14514,'Malygos - Yell: Intro 2'),
(28859,1,1,'I am without limits here. The rules of your cherished reality do not apply. In this realm, I am in control!',14,0,33,0,0,14515,'Malygos - Yell: Intro 2'),
(28859,1,2,'I give you one chance. Pledge fealty to me, and perhaps I will not slaughter you for your insolence.',14,0,33,0,0,14516,'Malygos - Yell: Intro 2'),
(28859,2,0,'My patience has reached its limit, I will be rid of you!',14,0,0,0,0,14517,'Malygos - Aggro (Phase 1)'),
(28859,3,0,'You will not succeed while I draw breath!',14,0,0,0,0,14518,'Malygos - Deep Breath'),
(28859,4,0,'Your stupidity has finally caught up to you',14,0,34,0,0,14519,'Malygos - Killed Player (1) (Phase 1)'),
(28859,4,1,'More artifacts to confiscate...',14,0,33,0,0,14520,'Malygos - Killed Player (2) (Phase 1)'),
(28859,4,2,'<Laughs> How very... naive...',14,0,33,0,0,14521,'Malygos - Killed Player (3) (Phase 1)'),
(28859,5,0,'I had hoped to end your lives quickly, but you have proven more... resilient then I had anticipated. Nonetheless, your efforts are in vain, it is you reckless, careless mortals who are to blame for this war! I do what I must... And if it means your... extinction... THEN SO BE IT',14,0,0,0,0,14522,'Malygos - End Phase One'),
(28859,6,0,'Few have experienced the pain I will now inflict upon you!',14,0,0,0,0,14523,'Malygos - Aggro (Phase 2) [unused]'),
(28859,7,0,'I will teach you IGNORANT children just how little you know of magic...',14,0,0,0,0,14524,'Malygos - Anti-Magic Shell [unused]'),
(28859,8,0,'Watch helplessly as your hopes are swept away...',14,0,0,0,0,14525,'Malygos - Vortex'),
(28859,9,0,'Your energy will be put to good use!',14,0,34,0,0,14526,'Malygos - Killed Player 1 (Phase 2)'),
(28859,9,1,'I am the spell-weaver! My power is infinite!',14,0,33,0,0,14527,'Malygos - Killed Player 2 (Phase 2)'),
(28859,9,2,'Your spirit will linger here forever!',14,0,33,0,0,14528,'Malygos - Killed Player 3 (Phase 2)'),
(28859,10,0,'ENOUGH! If you intend to reclaim Azeroth''s magic, then you shall have it...',14,0,0,0,0,14529,'Malygos - End Phase 2'),
(28859,11,0,'Now your benefactors make their appearance, but they are too late! The powers contained here are sufficient to destroy the world ten times over. What do you think they will do to you?',14,0,0,0,0,14530,'Malygos - Intro Phase 3'),
(28859,12,0,'SUBMIT!',14,0,0,0,0,14531,'Malygos - Aggro (Phase 3) [unused]'),
(28859,13,0,'The powers at work here exceed anything you could possibly imagine!',14,0,0,0,0,14532,'Malygos - Surge of Power [unused]'),
(28859,14,0,'I AM UNSTOPPABLE!',14,0,0,0,0,14533,'Malygos - Power Spark Buff'),
(28859,15,0,'Alexstrasza! Another of your brood falls!',14,0,34,0,0,14534,'Malygos - Killed Player 1 (Phase 3)'),
(28859,15,1,'Little more then gnats!',14,0,33,0,0,14535,'Malygos - Killed Player 2 (Phase 3)'),
(28859,15,2,'Your red allies will share your fate...',14,0,33,0,0,14536,'Malygos - Killed Player 3 (Phase 3)'),
(28859,16,0,'Still standing? Not for long...',14,0,34,0,0,14537,'Malygos - Spell Casting 1(Phase 3) [unused]'),
(28859,16,1,'Your cause is lost',14,0,33,0,0,14538,'Malygos - Spell Casting 2 (Phase 3) [unused]'),
(28859,16,2,'Your fragile mind will be shattered!',14,0,33,0,0,14539,'Malygos - Spell Casting 3 (Phase 3) [unused]'),
(28859,17,0,'Unthinkable! The mortals will destroy... everything... my sister... what have you...',14,0,0,0,0,14540,'Malygos - Death'),
(28859,18,0,'A Power Spark forms from a nearby rift!',41,0,0,0,0,0,'Malygos - Emote: Power Spark'),
(28859,19,0,'%s takes a deep breath.',41,0,0,0,0,0,'Malygos - Emote: Deep Breath'),
(28859,20,0,'%s fixes his eyes on you!',42,0,0,0,0,0,'Malygos - Emote: Surge of Power');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment