aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/Northrend
diff options
context:
space:
mode:
authorVincent_Michael <Vincent_Michael@gmx.de>2013-12-20 17:39:13 +0100
committerVincent_Michael <Vincent_Michael@gmx.de>2013-12-20 17:39:13 +0100
commit8658b5338c905c79daf50cb56dbe739f82d25acc (patch)
treeebb2c18b6d9618ac9fef1d2c5f8b335f34d3702c /src/server/scripts/Northrend
parent59fd1a164fc38ddd282707b3221dcd64af284166 (diff)
parent9ac96fd702d8ed23491d13eda2238312120cf52f (diff)
Merge branch 'master' of github.com:TrinityCore/TrinityCore into mmaps_rw
Conflicts: src/server/collision/Management/MMapManager.cpp src/server/game/Maps/Map.cpp src/server/game/Movement/PathGenerator.cpp
Diffstat (limited to 'src/server/scripts/Northrend')
-rw-r--r--src/server/scripts/Northrend/CMakeLists.txt1
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp1732
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp155
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp1159
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h19
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp3
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp17
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp48
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h8
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp17
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp4
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp25
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp3
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_drakos.cpp202
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp285
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp392
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp167
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp558
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp855
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.h76
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp322
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp6
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp592
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp49
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp383
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h84
-rw-r--r--src/server/scripts/Northrend/zone_dalaran.cpp8
-rw-r--r--src/server/scripts/Northrend/zone_dragonblight.cpp435
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp122
-rw-r--r--src/server/scripts/Northrend/zone_howling_fjord.cpp112
-rw-r--r--src/server/scripts/Northrend/zone_icecrown.cpp88
-rw-r--r--src/server/scripts/Northrend/zone_sholazar_basin.cpp52
-rw-r--r--src/server/scripts/Northrend/zone_storm_peaks.cpp265
-rw-r--r--src/server/scripts/Northrend/zone_zuldrak.cpp1003
37 files changed, 4456 insertions, 4797 deletions
diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt
index 3c56361d096..285f8f866cb 100644
--- a/src/server/scripts/Northrend/CMakeLists.txt
+++ b/src/server/scripts/Northrend/CMakeLists.txt
@@ -45,6 +45,7 @@ set(scripts_STAT_SRCS
Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h
Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
+ Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
Northrend/ChamberOfAspects/RubySanctum/instance_ruby_sanctum.cpp
Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h
Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
index 2088ef2fa2e..a212a74df86 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
@@ -37,9 +37,6 @@ enum Enums
SAY_SARTHARION_SLAY = 8,
WHISPER_LAVA_CHURN = 9,
- WHISPER_HATCH_EGGS = 6,
- WHISPER_OPEN_PORTAL = 6, // whisper, shared by two dragons
-
WHISPER_SHADRON_DICIPLE = 7,
WHISPER_VESPERON_DICIPLE = 7,
@@ -58,70 +55,25 @@ enum Enums
SPELL_PYROBUFFET = 56916, // currently used for hard enrage after 15 minutes
SPELL_PYROBUFFET_RANGE = 58907, // possibly used when player get too far away from dummy creatures (2x Creature entry 30494)
- SPELL_TWILIGHT_SHIFT_ENTER = 57620, // enter phase. Player get this when click GO
- SPELL_TWILIGHT_SHIFT = 57874, // Twilight Shift Aura
- SPELL_TWILIGHT_SHIFT_REMOVAL = 61187, // leave phase
- SPELL_TWILIGHT_SHIFT_REMOVAL_ALL = 61190, // leave phase (probably version to make all leave)
-
- //Mini bosses common spells
- SPELL_TWILIGHT_RESIDUE = 61885, // makes immune to shadow damage, applied when leave phase
-
- //Miniboses (Vesperon, Shadron, Tenebron)
- SPELL_SHADOW_BREATH_H = 59126, // Inflicts 8788 to 10212 Fire damage to enemies in a cone in front of the caster.
- SPELL_SHADOW_BREATH = 57570, // Inflicts 6938 to 8062 Fire damage to enemies in a cone in front of the caster.
-
- SPELL_SHADOW_FISSURE_H = 59127, // Deals 9488 to 13512 Shadow damage to any enemy within the Shadow fissure after 5 sec.
- SPELL_SHADOW_FISSURE = 57579, // Deals 6188 to 8812 Shadow damage to any enemy within the Shadow fissure after 5 sec.
-
//Vesperon
//In portal is a disciple, when disciple killed remove Power_of_vesperon, portal open multiple times
NPC_ACOLYTE_OF_VESPERON = 31219, // Acolyte of Vesperon
SPELL_POWER_OF_VESPERON = 61251, // Vesperon's presence decreases the maximum health of all enemies by 25%.
- SPELL_TWILIGHT_TORMENT_VESP = 57948, // (Shadow only) trigger 57935 then 57988
- SPELL_TWILIGHT_TORMENT_VESP_ACO = 58853, // (Fire and Shadow) trigger 58835 then 57988
//Shadron
//In portal is a disciple, when disciple killed remove Power_of_vesperon, portal open multiple times
NPC_ACOLYTE_OF_SHADRON = 31218, // Acolyte of Shadron
SPELL_POWER_OF_SHADRON = 58105, // Shadron's presence increases Fire damage taken by all enemies by 100%.
- SPELL_GIFT_OF_TWILIGTH_SHA = 57835, // TARGET_SCRIPT shadron
- SPELL_GIFT_OF_TWILIGTH_SAR = 58766, // TARGET_SCRIPT sartharion
- SPELL_VOID_BLAST = 57581, // Twilight Fissure
- SPELL_VOID_BLAST_H = 59128,
//Tenebron
//in the portal spawns 6 eggs, if not killed in time (approx. 20s) they will hatch, whelps can cast 60708
SPELL_POWER_OF_TENEBRON = 61248, // Tenebron's presence increases Shadow damage taken by all enemies by 100%.
- //Tenebron, dummy spell
- SPELL_SUMMON_TWILIGHT_WHELP = 58035, // doesn't work, will spawn NPC_TWILIGHT_WHELP
- SPELL_SUMMON_SARTHARION_TWILIGHT_WHELP = 58826, // doesn't work, will spawn NPC_SHARTHARION_TWILIGHT_WHELP
-
- SPELL_HATCH_EGGS_H = 59189,
- SPELL_HATCH_EGGS = 58542,
- SPELL_HATCH_EGGS_EFFECT_H = 59190,
- SPELL_HATCH_EGGS_EFFECT = 58685,
- NPC_TWILIHT_WHELP = 31214,
- NPC_TWILIGHT_EGG = 30882,
- NPC_SARTHARION_TWILIGHT_EGG = 31204,
-
- //Whelps
- NPC_TWILIGHT_WHELP = 30890,
- NPC_SHARTHARION_TWILIGHT_WHELP = 31214,
- SPELL_FADE_ARMOR = 60708, // Reduces the armor of an enemy by 1500 for 15s
-
- //flame tsunami
- SPELL_FLAME_TSUNAMI = 57494, // the visual dummy
- SPELL_FLAME_TSUNAMI_LEAP = 60241, // SPELL_EFFECT_138 some leap effect, causing caster to move in direction
-
- SPELL_FLAME_TSUNAMI_DMG_AURA = 57491, // periodic damage, npc has this aura
- SPELL_FLAME_TSUNAMI_BUFF = 60430,
NPC_FLAME_TSUNAMI = 30616, // for the flame waves
- NPC_LAVA_BLAZE = 30643, // adds spawning from flame strike
//using these custom points for dragons start and end
POINT_ID_INIT = 100,
- POINT_ID_LAND = 200,
+ POINT_ID_LAND = 200
};
enum Misc
@@ -129,25 +81,32 @@ enum Misc
DATA_CAN_LOOT = 0
};
-struct Waypoint
-{
- float m_fX, m_fY, m_fZ;
-};
-
struct Location
{
float x, y, z;
};
-struct Locations
+
+static Location FlameRight1Spawn = { 3200.00f, 573.211f, 57.1551f };
+static Location FlameRight1Direction = { 3289.28f, 573.211f, 57.1551f };
+static Location FlameRight2Spawn = { 3200.00f, 532.211f, 57.1551f };
+static Location FlameRight2Direction = { 3289.28f, 532.211f, 57.1551f };
+static Location FlameRight3Spawn = { 3200.00f, 491.211f, 57.1551f };
+static Location FlameRight3Direction = { 3289.28f, 491.211f, 57.1551f };
+static Location FlameLeft1Spawn = { 3289.28f, 511.711f, 57.1551f };
+static Location FlameLeft1Direction = { 3200.00f, 511.711f, 57.1551f };
+static Location FlameLeft2Spawn = { 3289.28f, 552.711f, 57.1551f };
+static Location FlameLeft2Direction = { 3200.00f, 552.711f, 57.1551f };
+
+struct Waypoint
{
- float x, y, z;
+ float m_fX, m_fY, m_fZ;
};
//each dragons special points. First where fly to before connect to connon, second where land point is.
Waypoint m_aTene[]=
{
- {3212.854f, 575.597f, 109.856f}, //init
- {3246.425f, 565.367f, 61.249f} //end
+ {3212.854f, 575.597f, 109.856f}, // init
+ {3246.425f, 565.367f, 61.249f} // end
};
Waypoint m_aShad[]=
@@ -162,54 +121,19 @@ Waypoint m_aVesp[]=
{3227.268f, 533.238f, 59.995f}
};
-#define MAX_WAYPOINT 6
-//points around raid "isle", counter clockwise. should probably be adjusted to be more alike
-Waypoint m_aDragonCommon[MAX_WAYPOINT]=
+enum SartharionEvents
{
- {3214.012f, 468.932f, 98.652f},
- {3244.950f, 468.427f, 98.652f},
- {3283.520f, 496.869f, 98.652f},
- {3287.316f, 555.875f, 98.652f},
- {3250.479f, 585.827f, 98.652f},
- {3209.969f, 566.523f, 98.652f}
+ EVENT_HARD_ENRAGE = 1,
+ EVENT_FLAME_TSUNAMI = 2,
+ EVENT_FLAME_BREATH = 3,
+ EVENT_TAIL_SWEEP = 4,
+ EVENT_CLEAVE_ATTACK = 5,
+ EVENT_LAVA_STRIKE = 6,
+ EVENT_CALL_TENEBRON = 7,
+ EVENT_CALL_SHADRON = 8,
+ EVENT_CALL_VESPERON = 9
};
-static Location FlameRight1Spawn = { 3200.00f, 573.211f, 57.1551f };
-static Location FlameRight1Direction = { 3289.28f, 573.211f, 57.1551f };
-static Location FlameRight2Spawn = { 3200.00f, 532.211f, 57.1551f };
-static Location FlameRight2Direction = { 3289.28f, 532.211f, 57.1551f };
-static Location FlameRight3Spawn = { 3200.00f, 491.211f, 57.1551f };
-static Location FlameRight3Direction = { 3289.28f, 491.211f, 57.1551f };
-static Location FlameLeft1Spawn = { 3289.28f, 511.711f, 57.1551f };
-static Location FlameLeft1Direction = { 3200.00f, 511.711f, 57.1551f };
-static Location FlameLeft2Spawn = { 3289.28f, 552.711f, 57.1551f };
-static Location FlameLeft2Direction = { 3200.00f, 552.711f, 57.1551f };
-
-static Location AcolyteofShadron = { 3363.92f, 534.703f, 97.2683f };
-static Location AcolyteofShadron2 = { 3246.57f, 551.263f, 58.6164f };
-static Location AcolyteofVesperon = { 3145.68f, 520.71f, 89.7f };
-static Location AcolyteofVesperon2 = { 3246.57f, 551.263f, 58.6164f };
-Locations TwilightEggs[] =
-{
- {3219.28f, 669.121f, 88.5549f},
- {3221.55f, 682.852f, 90.5361f},
- {3239.77f, 685.94f, 90.3168f},
- {3250.33f, 669.749f, 88.7637f},
- {3246.6f, 642.365f, 84.8752f},
- {3233.68f, 653.117f, 85.7051f}
-};
-Locations TwilightEggsSarth[] =
-{
- {3252.73f, 515.762f, 58.5501f},
- {3256.56f, 521.119f, 58.6061f},
- {3255.63f, 527.513f, 58.7568f},
- {3264.90f, 525.865f, 58.6436f},
- {3264.26f, 516.364f, 58.8011f},
- {3257.54f, 502.285f, 58.2077f}
-};
-
-#define TWILIGHT_ACHIEVEMENTS 1
-
/*######
## Boss Sartharion
######*/
@@ -219,169 +143,71 @@ class boss_sartharion : public CreatureScript
public:
boss_sartharion() : CreatureScript("boss_sartharion") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_sartharionAI(creature);
- }
-
- struct boss_sartharionAI : public ScriptedAI
+ struct boss_sartharionAI : public BossAI
{
- boss_sartharionAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- bool m_bIsBerserk;
- bool m_bIsSoftEnraged;
-
- uint32 m_uiEnrageTimer;
- bool m_bIsHardEnraged;
-
- uint32 m_uiTenebronTimer;
- uint32 m_uiShadronTimer;
- uint32 m_uiVesperonTimer;
-
- uint32 m_uiFlameTsunamiTimer;
- uint32 m_uiFlameBreathTimer;
- uint32 m_uiTailSweepTimer;
- uint32 m_uiCleaveTimer;
- uint32 m_uiLavaStrikeTimer;
-
- bool m_bHasCalledTenebron;
- bool m_bHasCalledShadron;
- bool m_bHasCalledVesperon;
-
- uint8 drakeCount;
+ boss_sartharionAI(Creature* creature) : BossAI(creature, DATA_SARTHARION) { }
void Reset() OVERRIDE
{
- m_bIsBerserk = false;
- m_bIsSoftEnraged = false;
-
- m_uiEnrageTimer = 15*MINUTE*IN_MILLISECONDS;
- m_bIsHardEnraged = false;
-
- m_uiTenebronTimer = 30000;
- m_uiShadronTimer = 75000;
- m_uiVesperonTimer = 120000;
-
- m_uiFlameTsunamiTimer = 30000;
- m_uiFlameBreathTimer = 20000;
- m_uiTailSweepTimer = 20000;
- m_uiCleaveTimer = 7000;
- m_uiLavaStrikeTimer = 5000;
-
- m_bHasCalledTenebron = false;
- m_bHasCalledShadron = false;
- m_bHasCalledVesperon = false;
+ _isBerserk = false;
+ _isSoftEnraged = false;
+ _isHardEnraged = false;
+ drakeCount = 0;
if (me->HasAura(SPELL_TWILIGHT_REVENGE))
me->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE);
me->SetHomePosition(3246.57f, 551.263f, 58.6164f, 4.66003f);
- drakeCount = 0;
-
- // Drakes respawning system
if (instance)
{
- Creature* pTenebron = Unit::GetCreature(*me, instance->GetData64(DATA_TENEBRON));
- Creature* pShadron = Unit::GetCreature(*me, instance->GetData64(DATA_SHADRON));
- Creature* pVesperon = Unit::GetCreature(*me, instance->GetData64(DATA_VESPERON));
- if (pTenebron)
- {
- pTenebron->SetHomePosition(3239.07f, 657.235f, 86.8775f, 4.74729f);
- if (pTenebron->IsAlive())
- {
- if (pTenebron->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pTenebron->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- pTenebron->GetMotionMaster()->MoveTargetedHome();
- }else
- {
- if (instance->GetData(TYPE_TENEBRON_PREKILLED) == false)
- {
- pTenebron->Respawn();
- pTenebron->GetMotionMaster()->MoveTargetedHome();
- pTenebron->AI()->SetData(DATA_CAN_LOOT, 0);
- }
- }
- }
- if (pShadron)
- {
- pShadron->SetHomePosition(3363.06f, 525.28f, 98.362f, 4.76475f);
- if (pShadron->IsAlive())
- {
- if (pShadron->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pShadron->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- pShadron->GetMotionMaster()->MoveTargetedHome();
- }else
- {
- if (instance->GetData(TYPE_SHADRON_PREKILLED) == false)
- {
- pShadron->Respawn();
- pShadron->GetMotionMaster()->MoveTargetedHome();
- pShadron->AI()->SetData(DATA_CAN_LOOT, 0);
- }
- }
- }
- if (pVesperon)
- {
- pVesperon->SetHomePosition(3145.68f, 520.71f, 89.7f, 4.64258f);
- if (pVesperon->IsAlive())
- {
- if (pVesperon->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pVesperon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- pVesperon->GetMotionMaster()->MoveTargetedHome();
- }else
- {
- if (instance->GetData(TYPE_VESPERON_PREKILLED) == false)
- {
- pVesperon->Respawn();
- pVesperon->GetMotionMaster()->MoveTargetedHome();
- pVesperon->AI()->SetData(DATA_CAN_LOOT, 0);
- }
- }
- }
+ DrakeRespawn();
+ instance->SetBossState(DATA_PORTAL_OPEN, NOT_STARTED);
}
}
void JustReachedHome() OVERRIDE
{
- if (instance)
- instance->SetData(TYPE_SARTHARION_EVENT, NOT_STARTED);
+ _Reset();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
Talk(SAY_SARTHARION_AGGRO);
+ _EnterCombat();
DoZoneInCombat();
if (instance)
- {
- instance->SetData(TYPE_SARTHARION_EVENT, IN_PROGRESS);
FetchDragons();
- }
+
+ events.ScheduleEvent(EVENT_LAVA_STRIKE, 5000);
+ events.ScheduleEvent(EVENT_CLEAVE_ATTACK, 7000);
+ events.ScheduleEvent(EVENT_FLAME_BREATH, 20000);
+ events.ScheduleEvent(EVENT_TAIL_SWEEP, 20000);
+ events.ScheduleEvent(EVENT_FLAME_TSUNAMI, 30000);
+ events.ScheduleEvent(EVENT_CALL_TENEBRON, 30000);
+ events.ScheduleEvent(EVENT_CALL_SHADRON, 75000);
+ events.ScheduleEvent(EVENT_CALL_VESPERON, 120000);
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
Talk(SAY_SARTHARION_DEATH);
+ _JustDied();
if (instance)
{
- Creature* pTenebron = Unit::GetCreature(*me, instance->GetData64(DATA_TENEBRON));
- Creature* pShadron = Unit::GetCreature(*me, instance->GetData64(DATA_SHADRON));
- Creature* pVesperon = Unit::GetCreature(*me, instance->GetData64(DATA_VESPERON));
- if (pTenebron && pTenebron->IsAlive())
- pTenebron->DisappearAndDie();
- if (pShadron && pShadron->IsAlive())
- pShadron->DisappearAndDie();
- if (pVesperon && pVesperon->IsAlive())
- pVesperon->DisappearAndDie();
-
- instance->SetData(TYPE_SARTHARION_EVENT, DONE);
+ if (Creature* tenebron = Unit::GetCreature(*me, instance->GetData64(DATA_TENEBRON)))
+ if (tenebron->IsAlive())
+ tenebron->DisappearAndDie();
+
+ if (Creature* shadron = Unit::GetCreature(*me, instance->GetData64(DATA_SHADRON)))
+ if (shadron->IsAlive())
+ shadron->DisappearAndDie();
+
+ if (Creature* vesperon = Unit::GetCreature(*me, instance->GetData64(DATA_VESPERON)))
+ if (vesperon->IsAlive())
+ vesperon->DisappearAndDie();
}
}
@@ -402,83 +228,140 @@ public:
me->AddLootMode(LOOT_MODE_HARD_MODE_1); // Add 1st Drake loot mode
}
- uint32 GetData(uint32 type) const OVERRIDE
+ void DrakeRespawn() // Drakes respawning system
{
- if (type == TWILIGHT_ACHIEVEMENTS)
- return drakeCount;
+ if (Creature* tenebron = Unit::GetCreature(*me, instance->GetData64(DATA_TENEBRON)))
+ {
+ tenebron->SetHomePosition(3239.07f, 657.235f, 86.8775f, 4.74729f);
+ if (tenebron->IsAlive())
+ {
+ if (tenebron->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ tenebron->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ tenebron->GetMotionMaster()->MoveTargetedHome();
+ }
+ else
+ {
+ if (instance->GetBossState(DATA_TENEBRON) != DONE)
+ {
+ tenebron->Respawn();
+ tenebron->GetMotionMaster()->MoveTargetedHome();
+ tenebron->AI()->SetData(DATA_CAN_LOOT, 0);
+ }
+ }
+ }
- return 0;
+ if (Creature* shadron = Unit::GetCreature(*me, instance->GetData64(DATA_SHADRON)))
+ {
+ shadron->SetHomePosition(3363.06f, 525.28f, 98.362f, 4.76475f);
+ if (shadron->IsAlive())
+ {
+ if (shadron->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ shadron->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ shadron->GetMotionMaster()->MoveTargetedHome();
+ }
+ else
+ {
+ if (instance->GetBossState(DATA_SHADRON) != DONE)
+ {
+ shadron->Respawn();
+ shadron->GetMotionMaster()->MoveTargetedHome();
+ shadron->AI()->SetData(DATA_CAN_LOOT, 0);
+ }
+ }
+ }
+
+ if (Creature* vesperon = Unit::GetCreature(*me, instance->GetData64(DATA_VESPERON)))
+ {
+ vesperon->SetHomePosition(3145.68f, 520.71f, 89.7f, 4.64258f);
+ if (vesperon->IsAlive())
+ {
+ if (vesperon->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ vesperon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ vesperon->GetMotionMaster()->MoveTargetedHome();
+ }
+ else
+ {
+ if (instance->GetBossState(DATA_VESPERON) != DONE)
+ {
+ vesperon->Respawn();
+ vesperon->GetMotionMaster()->MoveTargetedHome();
+ vesperon->AI()->SetData(DATA_CAN_LOOT, 0);
+ }
+ }
+ }
}
void FetchDragons()
{
- if (!instance)
- return;
-
me->ResetLootMode();
drakeCount = 0;
- Creature* pFetchTene = Unit::GetCreature(*me, instance->GetData64(DATA_TENEBRON));
- Creature* pFetchShad = Unit::GetCreature(*me, instance->GetData64(DATA_SHADRON));
- Creature* pFetchVesp = Unit::GetCreature(*me, instance->GetData64(DATA_VESPERON));
-
//if at least one of the dragons are alive and are being called
- bool bCanUseWill = false;
+ bool _canUseWill = false;
- if (pFetchTene && pFetchTene->IsAlive() && !pFetchTene->GetVictim())
+ if (Creature* fetchTene = Unit::GetCreature(*me, instance->GetData64(DATA_TENEBRON)))
{
- bCanUseWill = true;
- if (!pFetchTene->IsInCombat())
+ if (fetchTene->IsAlive() && !fetchTene->GetVictim())
{
- DoCast(me, SPELL_POWER_OF_TENEBRON);
- AddDrakeLootMode();
- ++drakeCount;
- }
- pFetchTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ);
+ _canUseWill = true;
+ if (!fetchTene->IsInCombat())
+ {
+ DoCast(me, SPELL_POWER_OF_TENEBRON);
+ AddDrakeLootMode();
+ ++drakeCount;
+ }
+ fetchTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ);
- if (!pFetchTene->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pFetchTene->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (!fetchTene->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ fetchTene->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
}
- if (pFetchShad && pFetchShad->IsAlive() && !pFetchShad->GetVictim())
+ if (Creature* fetchShad = Unit::GetCreature(*me, instance->GetData64(DATA_SHADRON)))
{
- bCanUseWill = true;
- if (!pFetchShad->IsInCombat())
+ if (fetchShad->IsAlive() && !fetchShad->GetVictim())
{
- DoCast(me, SPELL_POWER_OF_SHADRON);
- AddDrakeLootMode();
- ++drakeCount;
- }
- pFetchShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ);
+ _canUseWill = true;
+ if (!fetchShad->IsInCombat())
+ {
+ DoCast(me, SPELL_POWER_OF_SHADRON);
+ AddDrakeLootMode();
+ ++drakeCount;
+ }
+ fetchShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ);
- if (!pFetchShad->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pFetchShad->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (!fetchShad->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ fetchShad->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
}
- if (pFetchVesp && pFetchVesp->IsAlive() && !pFetchVesp->GetVictim())
+ if (Creature* fetchVesp = Unit::GetCreature(*me, instance->GetData64(DATA_VESPERON)))
{
- bCanUseWill = true;
- if (!pFetchVesp->IsInCombat())
+ if (fetchVesp && fetchVesp->IsAlive() && !fetchVesp->GetVictim())
{
- DoCast(me, SPELL_POWER_OF_VESPERON);
- AddDrakeLootMode();
- ++drakeCount;
- }
- pFetchVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ);
+ _canUseWill = true;
+ if (!fetchVesp->IsInCombat())
+ {
+ DoCast(me, SPELL_POWER_OF_VESPERON);
+ AddDrakeLootMode();
+ ++drakeCount;
+ }
+ fetchVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ);
- if (!pFetchVesp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- pFetchVesp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (!fetchVesp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ fetchVesp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
}
- if (bCanUseWill)
+ if (_canUseWill)
DoCast(me, SPELL_WILL_OF_SARTHARION);
}
- void CallDragon(uint32 uiDataId)
+ void CallDragon(uint32 dataId)
{
if (instance)
{
- if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(uiDataId)))
+ if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(dataId)))
{
if (temp->IsAlive() && !temp->GetVictim())
{
@@ -487,33 +370,41 @@ public:
if (temp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- int32 iTextId = 0;
+ int32 textId = 0;
switch (temp->GetEntry())
{
case NPC_TENEBRON:
- iTextId = SAY_SARTHARION_CALL_TENEBRON;
+ textId = SAY_SARTHARION_CALL_TENEBRON;
temp->AddAura(SPELL_POWER_OF_TENEBRON, temp);
temp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aTene[1].m_fX, m_aTene[1].m_fY, m_aTene[1].m_fZ);
break;
case NPC_SHADRON:
- iTextId = SAY_SARTHARION_CALL_SHADRON;
+ textId = SAY_SARTHARION_CALL_SHADRON;
temp->AddAura(SPELL_POWER_OF_SHADRON, temp);
temp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aShad[1].m_fX, m_aShad[1].m_fY, m_aShad[1].m_fZ);
break;
case NPC_VESPERON:
- iTextId = SAY_SARTHARION_CALL_VESPERON;
+ textId = SAY_SARTHARION_CALL_VESPERON;
temp->AddAura(SPELL_POWER_OF_VESPERON, temp);
temp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aVesp[1].m_fX, m_aVesp[1].m_fY, m_aVesp[1].m_fZ);
break;
}
- Talk(iTextId);
+ Talk(textId);
}
}
}
}
+ uint32 GetData(uint32 type) const OVERRIDE
+ {
+ if (type == TWILIGHT_ACHIEVEMENTS)
+ return drakeCount;
+
+ return 0;
+ }
+
void SendFlameTsunami()
{
if (Map* map = me->GetMap())
@@ -532,16 +423,16 @@ public:
// FIXME: Frequency of the casts reduced to compensate 100% chance of spawning a Lava Blaze add
void CastLavaStrikeOnTarget(Unit* target)
{
- std::list<Creature*> pFireCyclonesList;
+ std::list<Creature*> fireCyclonesList;
Trinity::AllCreaturesOfEntryInRange checker(me, NPC_FIRE_CYCLONE, 200.0f);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, pFireCyclonesList, checker);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, fireCyclonesList, checker);
me->VisitNearbyObject(200.0f, searcher);
- if (pFireCyclonesList.empty())
+ if (fireCyclonesList.empty())
return;
- std::list<Creature*>::iterator itr = pFireCyclonesList.begin();
- uint32 rnd = rand()%pFireCyclonesList.size();
+ std::list<Creature*>::iterator itr = fireCyclonesList.begin();
+ uint32 rnd = rand()%fireCyclonesList.size();
for (uint32 i = 0; i < rnd; ++i)
++itr;
@@ -549,1224 +440,121 @@ public:
(*itr)->CastSpell(target, SPELL_LAVA_STRIKE, true);
}
- void UpdateAI(uint32 uiDiff) OVERRIDE
+ void UpdateAI(uint32 diff) OVERRIDE
{
- //Return since we have no target
if (!UpdateVictim())
return;
- Unit* pTene = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_TENEBRON) : 0);
- Unit* pShad = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_SHADRON) : 0);
- Unit* pVesp = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_VESPERON) : 0);
-
- //spell will target dragons, if they are still alive at 35%
- if (!m_bIsBerserk && !HealthAbovePct(35)
- && ((pTene && pTene->IsAlive()) || (pShad && pShad->IsAlive()) || (pVesp && pVesp->IsAlive())))
- {
- Talk(SAY_SARTHARION_BERSERK);
- DoCast(me, SPELL_BERSERK);
- m_bIsBerserk = true;
- }
+ events.Update(diff);
- //soft enrage
- if (!m_bIsSoftEnraged && HealthBelowPct(10))
+ while (uint32 eventId = events.ExecuteEvent())
{
- // m_bIsSoftEnraged is used while determining Lava Strike cooldown.
- m_bIsSoftEnraged = true;
- }
-
- // hard enrage
- if (!m_bIsHardEnraged)
- {
- if (m_uiEnrageTimer <= uiDiff)
+ switch (eventId)
{
- DoCast(me, SPELL_PYROBUFFET, true);
- m_bIsHardEnraged = true;
- }
- else
- m_uiEnrageTimer -= uiDiff;
- }
-
- // flame tsunami
- if (m_uiFlameTsunamiTimer <= uiDiff)
- {
- SendFlameTsunami();
- switch (urand(0, 1))
- {
- case 0:
- {
- Creature* Right1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight1Spawn.x, FlameRight1Spawn.y, FlameRight1Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000);
- Creature* Right2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight2Spawn.x, FlameRight2Spawn.y, FlameRight2Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000);
- Creature* Right3 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight3Spawn.x, FlameRight3Spawn.y, FlameRight3Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000);
- Right1->GetMotionMaster()->MovePoint(0, FlameRight1Direction.x, FlameRight1Direction.y, FlameRight1Direction.z);
- Right2->GetMotionMaster()->MovePoint(0, FlameRight2Direction.x, FlameRight2Direction.y, FlameRight2Direction.z);
- Right3->GetMotionMaster()->MovePoint(0, FlameRight3Direction.x, FlameRight3Direction.y, FlameRight3Direction.z);
+ case EVENT_HARD_ENRAGE:
+ if (!_isHardEnraged)
+ {
+ DoCast(me, SPELL_PYROBUFFET, true);
+ _isHardEnraged = true;
+ }
break;
- }
- case 1:
- {
- Creature* Left1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft1Spawn.x, FlameLeft1Spawn.y, FlameLeft1Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000);
- Creature* Left2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft2Spawn.x, FlameLeft2Spawn.y, FlameLeft2Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000);
- Left1->GetMotionMaster()->MovePoint(0, FlameLeft1Direction.x, FlameLeft1Direction.y, FlameLeft1Direction.z);
- Left2->GetMotionMaster()->MovePoint(0, FlameLeft2Direction.x, FlameLeft2Direction.y, FlameLeft2Direction.z);
+ case EVENT_FLAME_TSUNAMI:
+ SendFlameTsunami();
+ switch (urand(0, 1))
+ {
+ case 0:
+ {
+ if (Creature* right1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight1Spawn.x, FlameRight1Spawn.y, FlameRight1Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000))
+ right1->GetMotionMaster()->MovePoint(0, FlameRight1Direction.x, FlameRight1Direction.y, FlameRight1Direction.z);
+ if (Creature* right2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight2Spawn.x, FlameRight2Spawn.y, FlameRight2Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000))
+ right2->GetMotionMaster()->MovePoint(0, FlameRight2Direction.x, FlameRight2Direction.y, FlameRight2Direction.z);
+ if (Creature* right3 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight3Spawn.x, FlameRight3Spawn.y, FlameRight3Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000))
+ right3->GetMotionMaster()->MovePoint(0, FlameRight3Direction.x, FlameRight3Direction.y, FlameRight3Direction.z);
+ break;
+ }
+ case 1:
+ {
+ if (Creature* left1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft1Spawn.x, FlameLeft1Spawn.y, FlameLeft1Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000))
+ left1->GetMotionMaster()->MovePoint(0, FlameLeft1Direction.x, FlameLeft1Direction.y, FlameLeft1Direction.z);
+ if (Creature* left2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft2Spawn.x, FlameLeft2Spawn.y, FlameLeft2Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN, 12000))
+ left2->GetMotionMaster()->MovePoint(0, FlameLeft2Direction.x, FlameLeft2Direction.y, FlameLeft2Direction.z);
+ break;
+ }
+ }
+ events.ScheduleEvent(EVENT_FLAME_TSUNAMI, 30000);
break;
- }
- }
-
- m_uiFlameTsunamiTimer = 30000;
- }
- else
- m_uiFlameTsunamiTimer -= uiDiff;
-
- // flame breath
- if (m_uiFlameBreathTimer <= uiDiff)
- {
- Talk(SAY_SARTHARION_BREATH);
- DoCastVictim(RAID_MODE(SPELL_FLAME_BREATH, SPELL_FLAME_BREATH_H));
- m_uiFlameBreathTimer = urand(25000, 35000);
- }
- else
- m_uiFlameBreathTimer -= uiDiff;
-
- // Tail Sweep
- if (m_uiTailSweepTimer <= uiDiff)
- {
- DoCastVictim(RAID_MODE(SPELL_TAIL_LASH, SPELL_TAIL_LASH_H));
- m_uiTailSweepTimer = urand(15000, 20000);
- }
- else
- m_uiTailSweepTimer -= uiDiff;
-
- // Cleave
- if (m_uiCleaveTimer <= uiDiff)
- {
- DoCastVictim(SPELL_CLEAVE);
- m_uiCleaveTimer = urand(7000, 10000);
- }
- else
- m_uiCleaveTimer -= uiDiff;
-
- // Lavas Strike
- if (m_uiLavaStrikeTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- CastLavaStrikeOnTarget(target);
-
- if (urand(0, 5) == 0)
- Talk(SAY_SARTHARION_SPECIAL);
- }
- m_uiLavaStrikeTimer = (m_bIsSoftEnraged ? urand(1400, 2000) : urand(5000, 20000));
- }
- else
- m_uiLavaStrikeTimer -= uiDiff;
-
- // call tenebron
- if (!m_bHasCalledTenebron && m_uiTenebronTimer <= uiDiff)
- {
- CallDragon(DATA_TENEBRON);
- m_bHasCalledTenebron = true;
- }
- else
- m_uiTenebronTimer -= uiDiff;
-
- // call shadron
- if (!m_bHasCalledShadron && m_uiShadronTimer <= uiDiff)
- {
- CallDragon(DATA_SHADRON);
- m_bHasCalledShadron = true;
- }
- else
- m_uiShadronTimer -= uiDiff;
-
- // call vesperon
- if (!m_bHasCalledVesperon && m_uiVesperonTimer <= uiDiff)
- {
- CallDragon(DATA_VESPERON);
- m_bHasCalledVesperon = true;
- }
- else
- m_uiVesperonTimer -= uiDiff;
-
- DoMeleeAttackIfReady();
-
- EnterEvadeIfOutOfCombatArea(uiDiff);
- }
- };
-
-};
-
-enum TeneText
-{
- SAY_TENEBRON_AGGRO = 0,
- SAY_TENEBRON_SLAY = 1,
- SAY_TENEBRON_DEATH = 2,
- SAY_TENEBRON_BREATH = 3,
- SAY_TENEBRON_RESPOND = 4,
- SAY_TENEBRON_SPECIAL = 5
-};
-
-enum ShadText
-{
- SAY_SHADRON_AGGRO = 0,
- SAY_SHADRON_SLAY = 1,
- SAY_SHADRON_DEATH = 2,
- SAY_SHADRON_BREATH = 3,
- SAY_SHADRON_RESPOND = 4,
- SAY_SHADRON_SPECIAL = 5
-};
-
-enum VespText
-{
- SAY_VESPERON_AGGRO = 0,
- SAY_VESPERON_SLAY = 1,
- SAY_VESPERON_DEATH = 2,
- SAY_VESPERON_BREATH = 3,
- SAY_VESPERON_RESPOND = 4,
- SAY_VESPERON_SPECIAL = 5,
-};
-
-//to control each dragons common abilities
-struct dummy_dragonAI : public ScriptedAI
-{
- dummy_dragonAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 m_uiWaypointId;
- uint32 m_uiMoveNextTimer;
- int32 m_iPortalRespawnTime;
- bool m_bCanMoveFree;
- bool m_bCanLoot;
-
- void Reset() OVERRIDE
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
- m_uiWaypointId = 0;
- m_uiMoveNextTimer = 500;
- m_iPortalRespawnTime = 30000;
- m_bCanMoveFree = false;
- m_bCanLoot = true;
- }
-
- void SetData(uint32 type, uint32 value) OVERRIDE
- {
- if (type == DATA_CAN_LOOT)
- m_bCanLoot = value;
- }
-
- void MovementInform(uint32 uiType, uint32 uiPointId) OVERRIDE
- {
- if (!instance || uiType != POINT_MOTION_TYPE)
- return;
-
-// debug_log("dummy_dragonAI: %s reached point %u", me->GetName(), uiPointId);
-
- //if healers messed up the raid and we was already initialized
- if (instance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
- {
- EnterEvadeMode();
- return;
- }
-
- //this is end, if we reach this, don't do much
- if (uiPointId == POINT_ID_LAND)
- {
- me->GetMotionMaster()->Clear();
- me->SetInCombatWithZone();
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
- {
- me->AddThreat(target, 1.0f);
- me->Attack(target, true);
- me->GetMotionMaster()->MoveChase(target);
- }
-
- m_bCanMoveFree = false;
- return;
- }
-
- //get amount of common points
- uint32 uiCommonWPCount = sizeof(m_aDragonCommon)/sizeof(Waypoint);
-
- //increase
- m_uiWaypointId = uiPointId+1;
-
- //if we have reached a point bigger or equal to count, it mean we must reset to point 0
- if (m_uiWaypointId >= uiCommonWPCount)
- {
- if (!m_bCanMoveFree)
- m_bCanMoveFree = true;
-
- m_uiWaypointId = 0;
- }
-
- m_uiMoveNextTimer = 500;
- }
-
- //used when open portal and spawn mobs in phase
- void DoRaidWhisper(int32 iTextId)
- {
- Map* map = me->GetMap();
-
- if (map && map->IsDungeon())
- {
- Map::PlayerList const &PlayerList = map->GetPlayers();
-
- if (!PlayerList.isEmpty())
- {
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- Talk(iTextId, i->GetSource()->GetGUID());
- }
- }
- }
-
- //"opens" the portal and does the "opening" whisper
- void OpenPortal()
- {
- int32 iTextId = 0;
-
- //there are 4 portal spawn locations, each are expected to be spawned with negative spawntimesecs in database
-
- //using a grid search here seem to be more efficient than caching all four guids
- //in instance script and calculate range to each.
- GameObject* pPortal = me->FindNearestGameObject(GO_TWILIGHT_PORTAL, 50.0f);
-
- switch (me->GetEntry())
- {
- case NPC_TENEBRON:
- {
- iTextId = WHISPER_HATCH_EGGS;
- if (instance && !instance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
- {
- for (uint32 i = 0; i < 6; ++i)
- me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggs[i].x, TwilightEggs[i].y, TwilightEggs[i].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
- }
- else
- {
- for (uint32 i = 0; i < 6; ++i)
- me->SummonCreature(NPC_SARTHARION_TWILIGHT_EGG, TwilightEggsSarth[i].x, TwilightEggsSarth[i].y, TwilightEggsSarth[i].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
- }
- break;
- }
- case NPC_SHADRON:
- {
- iTextId = WHISPER_OPEN_PORTAL;
- if (instance && !instance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
- me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron.x, AcolyteofShadron.y, AcolyteofShadron.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000);
- else
- me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron2.x, AcolyteofShadron2.y, AcolyteofShadron2.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000);
-
- break;
- }
- case NPC_VESPERON:
- {
- iTextId = WHISPER_OPEN_PORTAL;
- if (instance && !instance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
- {
- if (Creature* Acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon.x, AcolyteofVesperon.y, AcolyteofVesperon.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
- {
- me->InterruptNonMeleeSpells(true);
- Acolyte->InterruptNonMeleeSpells(true);
- me->CastSpell(me, 32747, false);
- }
- }
- else
- {
- if (Creature* Acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon2.x, AcolyteofVesperon2.y, AcolyteofVesperon2.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
- {
- me->InterruptNonMeleeSpells(true);
- Acolyte->InterruptNonMeleeSpells(true);
- me->CastSpell(me, 32747, false);
- }
- }
-
- break;
- }
- }
-
- DoRaidWhisper(iTextId);
-
- //By using SetRespawnTime() we will actually "spawn" the object with our defined time.
- //Once time is up, portal will disappear again.
- if (pPortal && !pPortal->isSpawned())
- pPortal->SetRespawnTime(m_iPortalRespawnTime);
-
- //Unclear what are expected to happen if one drake has a portal open already
- //Refresh respawnTime so time again are set to 30secs?
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (!m_bCanLoot)
- me->SetLootRecipient(NULL);
-
- int32 iTextId = 0;
- uint32 uiSpellId = 0;
-
- switch (me->GetEntry())
- {
- case NPC_TENEBRON:
- iTextId = SAY_TENEBRON_DEATH;
- uiSpellId = SPELL_POWER_OF_TENEBRON;
- if (instance && instance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
- instance->SetData(TYPE_TENEBRON_PREKILLED, 1);
- break;
- case NPC_SHADRON:
- iTextId = SAY_SHADRON_DEATH;
- uiSpellId = SPELL_POWER_OF_SHADRON;
- if (instance && instance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
- instance->SetData(TYPE_SHADRON_PREKILLED, 1);
- if (Creature* pAcolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_SHADRON, 100.0f))
- pAcolyte->Kill(pAcolyte);
- break;
- case NPC_VESPERON:
- iTextId = SAY_VESPERON_DEATH;
- uiSpellId = SPELL_POWER_OF_VESPERON;
- if (instance && instance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
- instance->SetData(TYPE_VESPERON_PREKILLED, 1);
- if (Creature* pAcolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_VESPERON, 100.0f))
- pAcolyte->Kill(pAcolyte);
- break;
- }
-
- Talk(iTextId);
-
- me->RemoveAurasDueToSpell(uiSpellId);
-
- if (instance)
- {
- instance->DoRemoveAurasDueToSpellOnPlayers(uiSpellId);
-
- // not if solo mini-boss fight
- if (instance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
- return;
-
- // Twilight Revenge to main boss
- if (Unit* pSartharion = Unit::GetUnit(*me, instance->GetData64(DATA_SARTHARION)))
- if (pSartharion->IsAlive())
- {
- pSartharion->RemoveAurasDueToSpell(uiSpellId);
- DoCast(pSartharion, SPELL_TWILIGHT_REVENGE, true);
- }
- }
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (m_bCanMoveFree && m_uiMoveNextTimer)
- {
- if (m_uiMoveNextTimer <= uiDiff)
- {
- if (m_uiWaypointId < MAX_WAYPOINT)
- me->GetMotionMaster()->MovePoint(m_uiWaypointId,
- m_aDragonCommon[m_uiWaypointId].m_fX, m_aDragonCommon[m_uiWaypointId].m_fY, m_aDragonCommon[m_uiWaypointId].m_fZ);
-
-// debug_log("dummy_dragonAI: %s moving to point %u", me->GetName(), m_uiWaypointId);
- m_uiMoveNextTimer = 0;
- }
- else
- m_uiMoveNextTimer -= uiDiff;
- }
- }
-};
-
-/*######
-## Mob Tenebron
-######*/
-
-class npc_tenebron : public CreatureScript
-{
-public:
- npc_tenebron() : CreatureScript("npc_tenebron") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_tenebronAI(creature);
- }
-
- struct npc_tenebronAI : public dummy_dragonAI
- {
- npc_tenebronAI(Creature* creature) : dummy_dragonAI(creature) { }
-
- uint32 m_uiShadowBreathTimer;
- uint32 m_uiShadowFissureTimer;
- uint32 m_uiHatchEggTimer;
-
- bool m_bHasPortalOpen;
-
- void Reset() OVERRIDE
- {
- dummy_dragonAI::Reset();
-
- m_uiShadowBreathTimer = 20000;
- m_uiShadowFissureTimer = 5000;
- m_uiHatchEggTimer = 30000;
-
- m_bHasPortalOpen = false;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- Talk(SAY_TENEBRON_AGGRO);
- DoZoneInCombat();
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- Talk(SAY_TENEBRON_SLAY);
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- //if no target, update dummy and return
- if (!UpdateVictim())
- {
- dummy_dragonAI::UpdateAI(uiDiff);
- return;
- }
-
- // shadow fissure
- if (m_uiShadowFissureTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE));
-
- m_uiShadowFissureTimer = urand(15000, 20000);
- }
- else
- m_uiShadowFissureTimer -= uiDiff;
-
- // Hatch Egg
- if (m_uiHatchEggTimer <= uiDiff)
- {
- OpenPortal();
- m_uiHatchEggTimer = 30000;
- }
- else
- m_uiHatchEggTimer -= uiDiff;
-
- // shadow breath
- if (m_uiShadowBreathTimer <= uiDiff)
- {
- Talk(SAY_TENEBRON_BREATH);
- DoCastVictim(RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
- m_uiShadowBreathTimer = urand(20000, 25000);
- }
- else
- m_uiShadowBreathTimer -= uiDiff;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-/*######
-## Mob Shadron
-######*/
-
-class npc_shadron : public CreatureScript
-{
-public:
- npc_shadron() : CreatureScript("npc_shadron") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_shadronAI(creature);
- }
-
- struct npc_shadronAI : public dummy_dragonAI
- {
- npc_shadronAI(Creature* creature) : dummy_dragonAI(creature) { }
-
- uint32 m_uiShadowBreathTimer;
- uint32 m_uiShadowFissureTimer;
- uint32 m_uiAcolyteShadronTimer;
-
- bool m_bHasPortalOpen;
-
- void Reset() OVERRIDE
- {
- dummy_dragonAI::Reset();
-
- m_uiShadowBreathTimer = 20000;
- m_uiShadowFissureTimer = 5000;
- m_uiAcolyteShadronTimer = 60000;
-
- if (me->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
- me->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
-
- if (me->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
- me->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
-
- m_bHasPortalOpen = false;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- Talk(SAY_SHADRON_AGGRO);
- DoZoneInCombat();
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- Talk(SAY_SHADRON_SLAY);
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- //if no target, update dummy and return
- if (!UpdateVictim())
- {
- dummy_dragonAI::UpdateAI(uiDiff);
- return;
- }
-
- // shadow fissure
- if (m_uiShadowFissureTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE_H));
-
- m_uiShadowFissureTimer = urand(15000, 20000);
- }
- else
- m_uiShadowFissureTimer -= uiDiff;
-
- // Portal Event
- if (m_uiAcolyteShadronTimer <= uiDiff)
- {
- if (m_bHasPortalOpen)
- m_uiAcolyteShadronTimer = 10000;
- else
- {
- if (me->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
- return;
-
- OpenPortal();
- m_bHasPortalOpen = true;
- m_uiAcolyteShadronTimer = urand(60000, 65000);
- }
- }
- else
- m_uiAcolyteShadronTimer -= uiDiff;
-
- // shadow breath
- if (m_uiShadowBreathTimer <= uiDiff)
- {
- Talk(SAY_SHADRON_BREATH);
- DoCastVictim(RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
- m_uiShadowBreathTimer = urand(20000, 25000);
- }
- else
- m_uiShadowBreathTimer -= uiDiff;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-/*######
-## Mob Vesperon
-######*/
-
-class npc_vesperon : public CreatureScript
-{
-public:
- npc_vesperon() : CreatureScript("npc_vesperon") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_vesperonAI(creature);
- }
-
- struct npc_vesperonAI : public dummy_dragonAI
- {
- npc_vesperonAI(Creature* creature) : dummy_dragonAI(creature) { }
-
- uint32 m_uiShadowBreathTimer;
- uint32 m_uiShadowFissureTimer;
- uint32 m_uiAcolyteVesperonTimer;
-
- bool m_bHasPortalOpen;
-
- void Reset() OVERRIDE
- {
- dummy_dragonAI::Reset();
-
- m_uiShadowBreathTimer = 20000;
- m_uiShadowFissureTimer = 5000;
- m_uiAcolyteVesperonTimer = 60000;
-
- m_bHasPortalOpen = false;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- Talk(SAY_VESPERON_AGGRO);
- DoZoneInCombat();
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- Talk(SAY_VESPERON_SLAY);
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- //if no target, update dummy and return
- if (!UpdateVictim())
- {
- dummy_dragonAI::UpdateAI(uiDiff);
- return;
- }
-
- // shadow fissure
- if (m_uiShadowFissureTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE_H));
-
- m_uiShadowFissureTimer = urand(15000, 20000);
- }
- else
- m_uiShadowFissureTimer -= uiDiff;
-
- // Portal Event
- if (m_uiAcolyteVesperonTimer <= uiDiff)
- {
- if (m_bHasPortalOpen)
- m_uiAcolyteVesperonTimer = 10000;
- else
- {
- OpenPortal();
- DoCastVictim(SPELL_TWILIGHT_TORMENT_VESP);
- m_uiAcolyteVesperonTimer = urand(60000, 70000);
- }
- }
- else
- m_uiAcolyteVesperonTimer -= uiDiff;
-
- // shadow breath
- if (m_uiShadowBreathTimer <= uiDiff)
- {
- Talk(SAY_VESPERON_BREATH);
- DoCastVictim(RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
- m_uiShadowBreathTimer = urand(20000, 25000);
- }
- else
- m_uiShadowBreathTimer -= uiDiff;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-/*######
-## Mob Acolyte of Shadron
-######*/
-
-class npc_acolyte_of_shadron : public CreatureScript
-{
-public:
- npc_acolyte_of_shadron() : CreatureScript("npc_acolyte_of_shadron") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_acolyte_of_shadronAI(creature);
- }
-
- struct npc_acolyte_of_shadronAI : public ScriptedAI
- {
- npc_acolyte_of_shadronAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
- uint32 uiDespawnTimer;
-
- void Reset() OVERRIDE
- {
- uiDespawnTimer = 28000;
- if (instance)
- {
- Creature* target = NULL;
- //if not solo figth, buff main boss, else place debuff on mini-boss. both spells TARGET_SCRIPT
- if (instance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
- {
- target = Unit::GetCreature((*me), instance->GetData64(DATA_SARTHARION));
- if (target)
- target->AddAura(SPELL_GIFT_OF_TWILIGTH_SAR, target);
- }
- else
- {
- target = Unit::GetCreature((*me), instance->GetData64(DATA_SHADRON));
- if (target)
- target->AddAura(SPELL_GIFT_OF_TWILIGTH_SHA, target);
- }
- }
-
- me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER, me);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (instance)
- {
- Creature* Shadron = instance->instance->GetCreature(instance->GetData64(DATA_SHADRON));
- if (Shadron)
- {
- (CAST_AI(npc_shadron::npc_shadronAI, Shadron->AI()))->m_bHasPortalOpen = false;
- }
-
- Creature* pDebuffTarget = NULL;
- Map* map = me->GetMap();
- if (map->IsDungeon())
- {
- Map::PlayerList const &PlayerList = map->GetPlayers();
-
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (i->GetSource()->IsAlive() && i->GetSource()->HasAura(SPELL_TWILIGHT_SHIFT, 0) && !i->GetSource()->GetVictim())
+ case EVENT_FLAME_BREATH:
+ Talk(SAY_SARTHARION_BREATH);
+ DoCastVictim(RAID_MODE(SPELL_FLAME_BREATH, SPELL_FLAME_BREATH_H));
+ events.ScheduleEvent(EVENT_FLAME_BREATH, urand(25000, 35000));
+ break;
+ case EVENT_TAIL_SWEEP:
+ DoCastVictim(RAID_MODE(SPELL_TAIL_LASH, SPELL_TAIL_LASH_H));
+ events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(15000, 20000));
+ break;
+ case EVENT_CLEAVE_ATTACK:
+ DoCastVictim(SPELL_CLEAVE);
+ events.ScheduleEvent(EVENT_CLEAVE_ATTACK, urand(7000, 10000));
+ break;
+ case EVENT_LAVA_STRIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
- i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_SHIFT_REMOVAL_ALL, true);
- i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_RESIDUE, true);
- i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
- i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_ENTER);
+ CastLavaStrikeOnTarget(target);
+ if (urand(0, 5) == 0)
+ Talk(SAY_SARTHARION_SPECIAL);
}
- }
+ events.ScheduleEvent(EVENT_LAVA_STRIKE, (_isSoftEnraged ? urand(1400, 2000) : urand(5000, 20000)));
+ break;
+ case EVENT_CALL_TENEBRON:
+ CallDragon(DATA_TENEBRON);
+ break;
+ case EVENT_CALL_SHADRON:
+ CallDragon(DATA_SHADRON);
+ break;
+ case EVENT_CALL_VESPERON:
+ CallDragon(DATA_VESPERON);
+ break;
+ default:
+ break;
}
-
- //not solo fight, so main boss has deduff
- pDebuffTarget = instance->instance->GetCreature(instance->GetData64(DATA_SARTHARION));
- if (pDebuffTarget && pDebuffTarget->IsAlive() && pDebuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SAR))
- pDebuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SAR);
-
- //event not in progress, then solo fight and must remove debuff mini-boss
- pDebuffTarget = instance->instance->GetCreature(instance->GetData64(DATA_SHADRON));
- if (pDebuffTarget && pDebuffTarget->IsAlive() && pDebuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
- pDebuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
}
- }
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (uiDespawnTimer < uiDiff)
+ // At 35% spell will target dragons, if they are still alive.
+ if (!_isBerserk && !HealthAbovePct(35))
{
- me->SetVisible(false);
- me->Kill(me);
- uiDespawnTimer = 28000;
- return;
- }else uiDespawnTimer -= uiDiff;
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-/*######
-## Mob Acolyte of Vesperon
-######*/
-
-class npc_acolyte_of_vesperon : public CreatureScript
-{
-public:
- npc_acolyte_of_vesperon() : CreatureScript("npc_acolyte_of_vesperon") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_acolyte_of_vesperonAI(creature);
- }
-
- struct npc_acolyte_of_vesperonAI : public ScriptedAI
- {
- npc_acolyte_of_vesperonAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
- uint32 uiDespawnTimer;
-
- void Reset() OVERRIDE
- {
- uiDespawnTimer = 28000;
- if (instance)
- me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER, me);
- DoCast(me, SPELL_TWILIGHT_TORMENT_VESP_ACO);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- me->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP_ACO);
-
- // remove twilight torment on Vesperon
- if (instance)
- {
- Creature* pVesperon = instance->instance->GetCreature(instance->GetData64(DATA_VESPERON));
- if (pVesperon)
- (CAST_AI(npc_vesperon::npc_vesperonAI, pVesperon->AI()))->m_bHasPortalOpen = false;
-
- if (pVesperon && pVesperon->IsAlive() && pVesperon->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
- pVesperon->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
-
- Map* map = me->GetMap();
- if (map->IsDungeon())
+ if (instance->GetBossState(DATA_TENEBRON) != DONE || instance->GetBossState(DATA_SHADRON) != DONE || instance->GetBossState(DATA_VESPERON) != DONE)
{
- Map::PlayerList const &PlayerList = map->GetPlayers();
-
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (i->GetSource()->IsAlive() && i->GetSource()->HasAura(SPELL_TWILIGHT_SHIFT, 0) && !i->GetSource()->GetVictim())
- {
- i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_SHIFT_REMOVAL_ALL, true);
- i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_RESIDUE, true);
- i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
- i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_ENTER);
- }
- if (i->GetSource()->IsAlive() && i->GetSource()->HasAura(SPELL_TWILIGHT_TORMENT_VESP, 0) && !i->GetSource()->GetVictim())
- i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
- }
+ Talk(SAY_SARTHARION_BERSERK);
+ DoCast(me, SPELL_BERSERK);
+ _isBerserk = true;
}
-
- instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_VESP_ACO);
- instance->DoRemoveAurasDueToSpellOnPlayers(57935);
- instance->DoRemoveAurasDueToSpellOnPlayers(58835); // Components of spell Twilight Torment
}
- }
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (uiDespawnTimer < uiDiff)
+ // Soft Enrage used while determining Lava Strike cooldown.
+ if (!_isSoftEnraged && HealthBelowPct(10))
{
- me->SetVisible(false);
- me->Kill(me);
- uiDespawnTimer = 28000;
- return;
- }else uiDespawnTimer -= uiDiff;
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-/*######
-## Mob Twilight Eggs
-######*/
-
-class npc_twilight_eggs : public CreatureScript
-{
-public:
- npc_twilight_eggs() : CreatureScript("npc_twilight_eggs") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_twilight_eggsAI(creature);
- }
-
- struct npc_twilight_eggsAI : public ScriptedAI
- {
- npc_twilight_eggsAI(Creature* creature) : ScriptedAI(creature)
- {
- SetCombatMovement(false);
- instance = creature->GetInstanceScript();
- }
-
- uint32 m_uiFadeArmorTimer;
- uint32 m_uiHatchEggTimer;
-
- InstanceScript* instance;
-
- void Reset() OVERRIDE
- {
- if (instance)
- me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER, me);
- m_uiFadeArmorTimer = 1000;
- m_uiHatchEggTimer = 20000;
- }
-
- void SpawnWhelps()
- {
- me->RemoveAllAuras();
-
- if (!instance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
- me->SummonCreature(NPC_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
- else
- me->SummonCreature(NPC_SHARTHARION_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
- me->DealDamage(me, me->GetHealth());
- }
-
- void JustSummoned(Creature* who) OVERRIDE
- {
- who->SetInCombatWithZone();
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (m_uiHatchEggTimer <= uiDiff)
- {
- Creature* Tenebron = instance->instance->GetCreature(instance->GetData64(DATA_TENEBRON));
- if (Tenebron)
- (CAST_AI(npc_tenebron::npc_tenebronAI, Tenebron->AI()))->m_bHasPortalOpen = false;
- SpawnWhelps();
+ _isSoftEnraged = true;
}
- else
- m_uiHatchEggTimer -= uiDiff;
- }
-
- void AttackStart(Unit* /*who*/) OVERRIDE { }
- void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
-
- };
-
-};
-
-/*######
-## Mob Flame Tsunami
-######*/
-class npc_flame_tsunami : public CreatureScript
-{
-public:
- npc_flame_tsunami() : CreatureScript("npc_flame_tsunami") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_flame_tsunamiAI(creature);
- }
-
- struct npc_flame_tsunamiAI : public ScriptedAI
- {
- npc_flame_tsunamiAI(Creature* creature) : ScriptedAI(creature)
- {
- me->SetDisplayId(11686);
- me->AddAura(SPELL_FLAME_TSUNAMI, me);
- }
-
- uint32 Tsunami_Timer;
- uint32 TsunamiBuff_timer;
- uint32 entry;
-
- void Reset() OVERRIDE
- {
- me->SetReactState(REACT_PASSIVE);
- Tsunami_Timer = 100;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- TsunamiBuff_timer = 1000;
- entry = 0;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (Tsunami_Timer <= diff)
- {
- DoCast(me, SPELL_FLAME_TSUNAMI_DMG_AURA);
- Tsunami_Timer = 500;
- }else Tsunami_Timer -= diff;
-
- if (TsunamiBuff_timer <= diff)
- {
- if (Unit* LavaBlaze = GetClosestCreatureWithEntry(me, NPC_LAVA_BLAZE, 10.0f, true))
- LavaBlaze->CastSpell(LavaBlaze, SPELL_FLAME_TSUNAMI_BUFF, true);
- TsunamiBuff_timer = 1000;
- }else TsunamiBuff_timer -= diff;
- }
- };
-
-};
-
-// Twilight Fissure
-class npc_twilight_fissure : public CreatureScript
-{
-public:
- npc_twilight_fissure() : CreatureScript("npc_twilight_fissure") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_twilight_fissureAI(creature);
- }
-
- struct npc_twilight_fissureAI : public ScriptedAI
- {
- npc_twilight_fissureAI(Creature* creature) : ScriptedAI(creature)
- {
- SetCombatMovement(false);
- }
- uint32 VoidBlast_Timer;
+ DoMeleeAttackIfReady();
- void Reset() OVERRIDE
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->AddAura( 46265, me ); // Wrong, can't find proper visual
- me->AddAura( 69422, me );
- VoidBlast_Timer = 5000;
+ EnterEvadeIfOutOfCombatArea(diff);
}
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (VoidBlast_Timer <= diff)
- {
- DoCastAOE(RAID_MODE(SPELL_VOID_BLAST, SPELL_VOID_BLAST_H));
- ////twilight realm
- //DoCastVictim(57620, true);
- //DoCastVictim(57874, true);
- VoidBlast_Timer = 9000;
- me->RemoveAllAuras();
- me->Kill(me);
- } else VoidBlast_Timer -= diff;
- }
+ private:
+ bool _isBerserk;
+ bool _isSoftEnraged;
+ bool _isHardEnraged;
+ uint8 drakeCount;
};
-};
-
-/*######
-## Mob Twilight Whelps
-######*/
-
-class npc_twilight_whelp : public CreatureScript
-{
-public:
- npc_twilight_whelp() : CreatureScript("npc_twilight_whelp") { }
-
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_twilight_whelpAI(creature);
+ return new boss_sartharionAI(creature);
}
-
- struct npc_twilight_whelpAI : public ScriptedAI
- {
- npc_twilight_whelpAI(Creature* creature) : ScriptedAI(creature)
- {
- Reset();
- }
-
- uint32 m_uiFadeArmorTimer;
-
- void Reset() OVERRIDE
- {
- me->RemoveAllAuras();
- me->SetInCombatWithZone();
- m_uiFadeArmorTimer = 1000;
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- // twilight torment
- if (m_uiFadeArmorTimer <= uiDiff)
- {
- DoCastVictim(SPELL_FADE_ARMOR);
- m_uiFadeArmorTimer = urand(5000, 10000);
- }
- else
- m_uiFadeArmorTimer -= uiDiff;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-class achievement_twilight_assist : public AchievementCriteriaScript
-{
- public:
- achievement_twilight_assist() : AchievementCriteriaScript("achievement_twilight_assist")
- {
- }
-
- bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
- {
- if (!target)
- return false;
-
- if (Creature* Sartharion = target->ToCreature())
- if (Sartharion->AI()->GetData(TWILIGHT_ACHIEVEMENTS) >= 1)
- return true;
-
- return false;
- }
-};
-
-class achievement_twilight_duo : public AchievementCriteriaScript
-{
- public:
- achievement_twilight_duo() : AchievementCriteriaScript("achievement_twilight_duo")
- {
- }
-
- bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
- {
- if (!target)
- return false;
-
- if (Creature* Sartharion = target->ToCreature())
- if (Sartharion->AI()->GetData(TWILIGHT_ACHIEVEMENTS) >= 2)
- return true;
-
- return false;
- }
-};
-
-class achievement_twilight_zone : public AchievementCriteriaScript
-{
- public:
- achievement_twilight_zone() : AchievementCriteriaScript("achievement_twilight_zone")
- {
- }
-
- bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
- {
- if (!target)
- return false;
-
- if (Creature* Sartharion = target->ToCreature())
- if (Sartharion->AI()->GetData(TWILIGHT_ACHIEVEMENTS) == 3)
- return true;
-
- return false;
- }
};
void AddSC_boss_sartharion()
{
new boss_sartharion();
- new npc_vesperon();
- new npc_shadron();
- new npc_tenebron();
- new npc_acolyte_of_shadron();
- new npc_acolyte_of_vesperon();
- new npc_twilight_eggs();
- new npc_flame_tsunami();
- new npc_twilight_fissure();
- new npc_twilight_whelp();
- new achievement_twilight_assist();
- new achievement_twilight_duo();
- new achievement_twilight_zone();
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
index ace2258ac9f..ad1346e7f37 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/instance_obsidian_sanctum.cpp
@@ -19,8 +19,6 @@
#include "InstanceScript.h"
#include "obsidian_sanctum.h"
-#define MAX_ENCOUNTER 1
-
/* Obsidian Sanctum encounters:
0 - Sartharion
*/
@@ -28,48 +26,18 @@
class instance_obsidian_sanctum : public InstanceMapScript
{
public:
- instance_obsidian_sanctum() : InstanceMapScript("instance_obsidian_sanctum", 615) { }
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
- {
- return new instance_obsidian_sanctum_InstanceMapScript(map);
- }
+ instance_obsidian_sanctum() : InstanceMapScript(OSScriptName, 615) { }
struct instance_obsidian_sanctum_InstanceMapScript : public InstanceScript
{
instance_obsidian_sanctum_InstanceMapScript(Map* map) : InstanceScript(map) { }
- uint32 m_auiEncounter[MAX_ENCOUNTER];
- uint64 m_uiSartharionGUID;
- uint64 m_uiTenebronGUID;
- uint64 m_uiShadronGUID;
- uint64 m_uiVesperonGUID;
-
- bool m_bTenebronKilled;
- bool m_bShadronKilled;
- bool m_bVesperonKilled;
-
void Initialize() OVERRIDE
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
-
- m_uiSartharionGUID = 0;
- m_uiTenebronGUID = 0;
- m_uiShadronGUID = 0;
- m_uiVesperonGUID = 0;
-
- m_bTenebronKilled = false;
- m_bShadronKilled = false;
- m_bVesperonKilled = false;
- }
-
- bool IsEncounterInProgress() const OVERRIDE
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- return true;
-
- return false;
+ sartharionGUID = 0;
+ tenebronGUID = 0;
+ shadronGUID = 0;
+ vesperonGUID = 0;
}
void OnCreatureCreate(Creature* creature) OVERRIDE
@@ -77,68 +45,113 @@ public:
switch (creature->GetEntry())
{
case NPC_SARTHARION:
- m_uiSartharionGUID = creature->GetGUID();
+ sartharionGUID = creature->GetGUID();
break;
- //three dragons below set to active state once created.
- //we must expect bigger raid to encounter main boss, and then three dragons must be active due to grid differences
+ // Three dragons below set to active state once created.
+ // We must expect bigger raid to encounter main boss, and then three dragons must be active due to grid differences
case NPC_TENEBRON:
- m_uiTenebronGUID = creature->GetGUID();
+ tenebronGUID = creature->GetGUID();
creature->setActive(true);
break;
case NPC_SHADRON:
- m_uiShadronGUID = creature->GetGUID();
+ shadronGUID = creature->GetGUID();
creature->setActive(true);
break;
case NPC_VESPERON:
- m_uiVesperonGUID = creature->GetGUID();
+ vesperonGUID = creature->GetGUID();
creature->setActive(true);
break;
}
}
- void SetData(uint32 uiType, uint32 uiData) OVERRIDE
- {
- if (uiType == TYPE_SARTHARION_EVENT)
- m_auiEncounter[0] = uiData;
- else if (uiType == TYPE_TENEBRON_PREKILLED)
- m_bTenebronKilled = true;
- else if (uiType == TYPE_SHADRON_PREKILLED)
- m_bShadronKilled = true;
- else if (uiType == TYPE_VESPERON_PREKILLED)
- m_bVesperonKilled = true;
- }
-
- uint32 GetData(uint32 uiType) const OVERRIDE
+ bool SetBossState(uint32 type, EncounterState state) OVERRIDE
{
- if (uiType == TYPE_SARTHARION_EVENT)
- return m_auiEncounter[0];
- else if (uiType == TYPE_TENEBRON_PREKILLED)
- return m_bTenebronKilled;
- else if (uiType == TYPE_SHADRON_PREKILLED)
- return m_bShadronKilled;
- else if (uiType == TYPE_VESPERON_PREKILLED)
- return m_bVesperonKilled;
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
- return 0;
+ switch (type)
+ {
+ case DATA_SARTHARION:
+ case DATA_TENEBRON:
+ case DATA_SHADRON:
+ case DATA_VESPERON:
+ break;
+ default:
+ break;
+ }
+ return true;
}
- uint64 GetData64(uint32 uiData) const OVERRIDE
+ uint64 GetData64(uint32 Data) const OVERRIDE
{
- switch (uiData)
+ switch (Data)
{
case DATA_SARTHARION:
- return m_uiSartharionGUID;
+ return sartharionGUID;
case DATA_TENEBRON:
- return m_uiTenebronGUID;
+ return tenebronGUID;
case DATA_SHADRON:
- return m_uiShadronGUID;
+ return shadronGUID;
case DATA_VESPERON:
- return m_uiVesperonGUID;
+ return vesperonGUID;
}
return 0;
}
+
+ std::string GetSaveData() OVERRIDE
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "O S " << GetBossSaveData();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* str) OVERRIDE
+ {
+ if (!str)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(str);
+
+ char dataHead1, dataHead2;
+
+ std::istringstream loadStream(str);
+ loadStream >> dataHead1 >> dataHead2;
+
+ if (dataHead1 == 'O' && dataHead2 == 'S')
+ {
+ for (uint32 i = 0; i < EncounterCount; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+ SetBossState(i, EncounterState(tmpState));
+ }
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ protected:
+ uint64 sartharionGUID;
+ uint64 tenebronGUID;
+ uint64 shadronGUID;
+ uint64 vesperonGUID;
};
+ InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
+ {
+ return new instance_obsidian_sanctum_InstanceMapScript(map);
+ }
};
void AddSC_instance_obsidian_sanctum()
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
new file mode 100644
index 00000000000..5fc4869c4af
--- /dev/null
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
@@ -0,0 +1,1159 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "obsidian_sanctum.h"
+
+enum Enums
+{
+ WHISPER_HATCH_EGGS = 6,
+ WHISPER_OPEN_PORTAL = 6, // whisper, shared by two dragons
+
+ //Mini bosses common spells
+ SPELL_TWILIGHT_RESIDUE = 61885, // makes immune to shadow damage, applied when leave phase
+
+ //Miniboses (Vesperon, Shadron, Tenebron)
+ SPELL_SHADOW_BREATH_H = 59126, // Inflicts 8788 to 10212 Fire damage to enemies in a cone in front of the caster.
+ SPELL_SHADOW_BREATH = 57570, // Inflicts 6938 to 8062 Fire damage to enemies in a cone in front of the caster.
+
+ SPELL_SHADOW_FISSURE_H = 59127, // Deals 9488 to 13512 Shadow damage to any enemy within the Shadow fissure after 5 sec.
+ SPELL_SHADOW_FISSURE = 57579, // Deals 6188 to 8812 Shadow damage to any enemy within the Shadow fissure after 5 sec.
+
+ //Vesperon
+ //In portal is a disciple, when disciple killed remove Power_of_vesperon, portal open multiple times
+ NPC_ACOLYTE_OF_VESPERON = 31219, // Acolyte of Vesperon
+ SPELL_POWER_OF_VESPERON = 61251, // Vesperon's presence decreases the maximum health of all enemies by 25%.
+ SPELL_TWILIGHT_TORMENT_VESP = 57948, // (Shadow only) trigger 57935 then 57988
+ SPELL_TWILIGHT_TORMENT_VESP_ACO = 58853, // (Fire and Shadow) trigger 58835 then 57988
+
+ //Shadron
+ //In portal is a disciple, when disciple killed remove Power_of_vesperon, portal open multiple times
+ NPC_ACOLYTE_OF_SHADRON = 31218, // Acolyte of Shadron
+ SPELL_POWER_OF_SHADRON = 58105, // Shadron's presence increases Fire damage taken by all enemies by 100%.
+ SPELL_GIFT_OF_TWILIGTH_SHA = 57835, // TARGET_SCRIPT shadron
+ SPELL_GIFT_OF_TWILIGTH_SAR = 58766, // TARGET_SCRIPT sartharion
+ SPELL_VOID_BLAST = 57581, // Twilight Fissure
+ SPELL_VOID_BLAST_H = 59128,
+
+ //Tenebron
+ //in the portal spawns 6 eggs, if not killed in time (approx. 20s) they will hatch, whelps can cast 60708
+ SPELL_POWER_OF_TENEBRON = 61248, // Tenebron's presence increases Shadow damage taken by all enemies by 100%.
+ //Tenebron, dummy spell
+ SPELL_SUMMON_TWILIGHT_WHELP = 58035, // doesn't work, will spawn NPC_TWILIGHT_WHELP
+ SPELL_SUMMON_SARTHARION_TWILIGHT_WHELP = 58826, // doesn't work, will spawn NPC_SHARTHARION_TWILIGHT_WHELP
+ SPELL_TWILIGHT_REVENGE = 60639,
+ SPELL_HATCH_EGGS_H = 59189,
+ SPELL_HATCH_EGGS = 58542,
+ SPELL_HATCH_EGGS_EFFECT_H = 59190,
+ SPELL_HATCH_EGGS_EFFECT = 58685,
+ NPC_TWILIHT_WHELP = 31214,
+ NPC_TWILIGHT_EGG = 30882,
+ NPC_SARTHARION_TWILIGHT_EGG = 31204,
+
+ SPELL_TWILIGHT_SHIFT_ENTER = 57620, // enter phase. Player get this when click GO
+ SPELL_TWILIGHT_SHIFT = 57874, // Twilight Shift Aura
+ SPELL_TWILIGHT_SHIFT_REMOVAL = 61187, // leave phase
+ SPELL_TWILIGHT_SHIFT_REMOVAL_ALL = 61190, // leave phase (probably version to make all leave)
+
+ //Whelps
+ NPC_TWILIGHT_WHELP = 30890,
+ NPC_SHARTHARION_TWILIGHT_WHELP = 31214,
+ SPELL_FADE_ARMOR = 60708, // Reduces the armor of an enemy by 1500 for 15s
+
+ //flame tsunami
+ SPELL_FLAME_TSUNAMI = 57494, // the visual dummy
+ SPELL_FLAME_TSUNAMI_LEAP = 60241, // SPELL_EFFECT_138 some leap effect, causing caster to move in direction
+
+ SPELL_FLAME_TSUNAMI_DMG_AURA = 57491, // periodic damage, npc has this aura
+ SPELL_FLAME_TSUNAMI_BUFF = 60430,
+ NPC_LAVA_BLAZE = 30643, // adds spawning from flame strike
+
+ //using these custom points for dragons start and end
+ POINT_ID_INIT = 100,
+ POINT_ID_LAND = 200
+};
+
+enum Misc
+{
+ DATA_CAN_LOOT = 0
+};
+
+struct Location
+{
+ float x, y, z;
+};
+
+struct Locations
+{
+ float x, y, z;
+};
+
+struct Waypoint
+{
+ float m_fX, m_fY, m_fZ;
+};
+
+#define MAX_WAYPOINT 6
+//points around raid "isle", counter clockwise. should probably be adjusted to be more alike
+Waypoint dragonCommon[MAX_WAYPOINT]=
+{
+ {3214.012f, 468.932f, 98.652f},
+ {3244.950f, 468.427f, 98.652f},
+ {3283.520f, 496.869f, 98.652f},
+ {3287.316f, 555.875f, 98.652f},
+ {3250.479f, 585.827f, 98.652f},
+ {3209.969f, 566.523f, 98.652f}
+};
+
+static Location AcolyteofShadron = { 3363.92f, 534.703f, 97.2683f };
+static Location AcolyteofShadron2 = { 3246.57f, 551.263f, 58.6164f };
+static Location AcolyteofVesperon = { 3145.68f, 520.71f, 89.7f };
+static Location AcolyteofVesperon2 = { 3246.57f, 551.263f, 58.6164f };
+
+Locations TwilightEggs[] =
+{
+ {3219.28f, 669.121f, 88.5549f},
+ {3221.55f, 682.852f, 90.5361f},
+ {3239.77f, 685.94f, 90.3168f},
+ {3250.33f, 669.749f, 88.7637f},
+ {3246.6f, 642.365f, 84.8752f},
+ {3233.68f, 653.117f, 85.7051f}
+};
+Locations TwilightEggsSarth[] =
+{
+ {3252.73f, 515.762f, 58.5501f},
+ {3256.56f, 521.119f, 58.6061f},
+ {3255.63f, 527.513f, 58.7568f},
+ {3264.90f, 525.865f, 58.6436f},
+ {3264.26f, 516.364f, 58.8011f},
+ {3257.54f, 502.285f, 58.2077f}
+};
+
+enum SharedTextIDs
+{
+ SAY_AGGRO = 0,
+ SAY_SLAY = 1,
+ SAY_DEATH = 2,
+ SAY_BREATH = 3,
+ SAY_RESPOND = 4,
+ SAY_SPECIAL = 5
+};
+
+enum DummyDragonEvents
+{
+ EVENT_FREE_MOVEMENT = 1
+};
+
+//to control each dragons common abilities
+struct dummy_dragonAI : public ScriptedAI
+{
+ dummy_dragonAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() OVERRIDE
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ waypointId = 0;
+ portalRespawnTime = 30000;
+ _canMoveFree = false;
+ _canLoot = true;
+ }
+
+ void SetData(uint32 type, uint32 value) OVERRIDE
+ {
+ if (type == DATA_CAN_LOOT)
+ _canLoot = value;
+ }
+
+ void MovementInform(uint32 type, uint32 pointId) OVERRIDE
+ {
+ if (!instance || type != POINT_MOTION_TYPE)
+ return;
+
+ // debug_log("dummy_dragonAI: %s reached point %u", me->GetName(), uiPointId);
+
+ // if healers messed up the raid and we was already initialized
+ if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ // this is end, if we reach this, don't do much
+ if (pointId == POINT_ID_LAND)
+ {
+ me->GetMotionMaster()->Clear();
+ me->SetInCombatWithZone();
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
+ {
+ me->AddThreat(target, 1.0f);
+ me->Attack(target, true);
+ me->GetMotionMaster()->MoveChase(target);
+ }
+
+ _canMoveFree = false;
+ return;
+ }
+
+ // get amount of common points
+ uint32 commonWPCount = sizeof(dragonCommon)/sizeof(Waypoint);
+
+ // increase
+ waypointId = pointId+1;
+
+ // if we have reached a point bigger or equal to count, it mean we must reset to point 0
+ if (waypointId >= commonWPCount)
+ {
+ if (!_canMoveFree)
+ _canMoveFree = true;
+
+ waypointId = 0;
+ }
+
+ events.ScheduleEvent(EVENT_FREE_MOVEMENT, 500);
+ }
+
+ // used when open portal and spawn mobs in phase
+ void DoRaidWhisper(int32 iTextId)
+ {
+ Map* map = me->GetMap();
+
+ if (map && map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ Talk(iTextId, i->GetSource()->GetGUID());
+ }
+ }
+ }
+
+ // "opens" the portal and does the "opening" whisper
+ void OpenPortal()
+ {
+ int32 textId = 0;
+
+ // there are 4 portal spawn locations, each are expected to be spawned with negative spawntimesecs in database
+
+ // using a grid search here seem to be more efficient than caching all four guids
+ // in instance script and calculate range to each.
+ GameObject* portal = me->FindNearestGameObject(GO_TWILIGHT_PORTAL, 50.0f);
+
+ switch (me->GetEntry())
+ {
+ case NPC_TENEBRON:
+ {
+ textId = WHISPER_HATCH_EGGS;
+ if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ {
+ for (uint32 i = 0; i < 6; ++i)
+ me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggs[i].x, TwilightEggs[i].y, TwilightEggs[i].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
+ }
+ else
+ {
+ for (uint32 i = 0; i < 6; ++i)
+ me->SummonCreature(NPC_SARTHARION_TWILIGHT_EGG, TwilightEggsSarth[i].x, TwilightEggsSarth[i].y, TwilightEggsSarth[i].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
+ }
+ break;
+ }
+ case NPC_SHADRON:
+ {
+ textId = WHISPER_OPEN_PORTAL;
+ if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron.x, AcolyteofShadron.y, AcolyteofShadron.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000);
+ else
+ me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron2.x, AcolyteofShadron2.y, AcolyteofShadron2.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000);
+
+ break;
+ }
+ case NPC_VESPERON:
+ {
+ textId = WHISPER_OPEN_PORTAL;
+ if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ {
+ if (Creature* acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon.x, AcolyteofVesperon.y, AcolyteofVesperon.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
+ {
+ me->InterruptNonMeleeSpells(true);
+ acolyte->InterruptNonMeleeSpells(true);
+ me->CastSpell(me, 32747, false);
+ }
+ }
+ else
+ {
+ if (Creature* acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon2.x, AcolyteofVesperon2.y, AcolyteofVesperon2.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
+ {
+ me->InterruptNonMeleeSpells(true);
+ acolyte->InterruptNonMeleeSpells(true);
+ me->CastSpell(me, 32747, false);
+ }
+ }
+
+ break;
+ }
+ }
+
+ DoRaidWhisper(textId);
+
+ // By using SetRespawnTime() we will actually "spawn" the object with our defined time.
+ // Once time is up, portal will disappear again.
+ if (portal && !portal->isSpawned())
+ portal->SetRespawnTime(portalRespawnTime);
+
+ // Unclear what are expected to happen if one drake has a portal open already
+ // Refresh respawnTime so time again are set to 30secs?
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ if (!_canLoot)
+ me->SetLootRecipient(NULL);
+
+ uint32 spellId = 0;
+
+ switch (me->GetEntry())
+ {
+ case NPC_TENEBRON:
+ spellId = SPELL_POWER_OF_TENEBRON;
+ if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ instance->SetBossState(DATA_TENEBRON, DONE);
+ break;
+ case NPC_SHADRON:
+ spellId = SPELL_POWER_OF_SHADRON;
+ if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ instance->SetBossState(DATA_SHADRON, DONE);
+ if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_SHADRON, 100.0f))
+ acolyte->Kill(acolyte);
+ break;
+ case NPC_VESPERON:
+ spellId = SPELL_POWER_OF_VESPERON;
+ if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ instance->SetBossState(DATA_VESPERON, DONE);
+ if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_VESPERON, 100.0f))
+ acolyte->Kill(acolyte);
+ break;
+ }
+
+ Talk(SAY_DEATH);
+ me->RemoveAurasDueToSpell(spellId);
+
+ if (instance)
+ {
+ instance->DoRemoveAurasDueToSpellOnPlayers(spellId);
+
+ // not if solo mini-boss fight
+ if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ return;
+
+ // Twilight Revenge to main boss
+ if (Unit* sartharion = Unit::GetUnit(*me, instance->GetData64(DATA_SARTHARION)))
+ if (sartharion->IsAlive())
+ {
+ sartharion->RemoveAurasDueToSpell(spellId);
+ DoCast(sartharion, SPELL_TWILIGHT_REVENGE, true);
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_FREE_MOVEMENT)
+ {
+ if (_canMoveFree && waypointId < MAX_WAYPOINT)
+ me->GetMotionMaster()->MovePoint(waypointId, dragonCommon[waypointId].m_fX, dragonCommon[waypointId].m_fY, dragonCommon[waypointId].m_fZ);
+ }
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ uint32 waypointId;
+ int32 portalRespawnTime;
+ bool _canMoveFree;
+ bool _canLoot;
+};
+
+/*######
+## Tenebron
+######*/
+
+enum TenebronEvents
+{
+ EVENT_SHADOW_FISSURE_TENEBRON = 2,
+ EVENT_HATCH_EGGS = 3,
+ EVENT_SHADOW_BREATH_TENEBRON = 4
+};
+
+class npc_tenebron : public CreatureScript
+{
+public:
+ npc_tenebron() : CreatureScript("npc_tenebron") { }
+
+ struct npc_tenebronAI : public dummy_dragonAI
+ {
+ npc_tenebronAI(Creature* creature) : dummy_dragonAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ dummy_dragonAI::Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ Talk(SAY_AGGRO);
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE_TENEBRON, 5000);
+ events.ScheduleEvent(EVENT_HATCH_EGGS, 30000);
+ events.ScheduleEvent(EVENT_SHADOW_BREATH_TENEBRON, 20000);
+ }
+
+ void KilledUnit(Unit* /*victim*/) OVERRIDE
+ {
+ Talk(SAY_SLAY);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ //if no target, update dummy and return
+ if (!UpdateVictim())
+ {
+ dummy_dragonAI::UpdateAI(diff);
+ return;
+ }
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHADOW_FISSURE_TENEBRON:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE));
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE_TENEBRON, urand(15000, 20000));
+ break;
+ case EVENT_HATCH_EGGS:
+ OpenPortal();
+ events.ScheduleEvent(EVENT_HATCH_EGGS, 30000);
+ break;
+ case EVENT_SHADOW_BREATH_TENEBRON:
+ Talk(SAY_BREATH);
+ DoCastVictim(RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
+ events.ScheduleEvent(EVENT_SHADOW_BREATH_TENEBRON, urand(20000, 25000));
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_tenebronAI(creature);
+ }
+};
+
+/*######
+## Shadron
+######*/
+
+enum ShadronEvents
+{
+ EVENT_SHADOW_FISSURE_SHADRON = 5,
+ EVENT_ACOLYTE_SHADRON = 6,
+ EVENT_SHADOW_BREATH_SHADRON = 7
+};
+
+class npc_shadron : public CreatureScript
+{
+public:
+ npc_shadron() : CreatureScript("npc_shadron") { }
+
+ struct npc_shadronAI : public dummy_dragonAI
+ {
+ npc_shadronAI(Creature* creature) : dummy_dragonAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() OVERRIDE
+ {
+ dummy_dragonAI::Reset();
+
+ if (me->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
+ me->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
+
+ if (me->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
+ me->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
+
+ if (instance)
+ instance->SetBossState(DATA_PORTAL_OPEN, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ Talk(SAY_AGGRO);
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE_SHADRON, 5000);
+ events.ScheduleEvent(EVENT_ACOLYTE_SHADRON, 60000);
+ events.ScheduleEvent(EVENT_SHADOW_BREATH_SHADRON, 20000);
+ }
+
+ void KilledUnit(Unit* /*victim*/) OVERRIDE
+ {
+ Talk(SAY_SLAY);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ //if no target, update dummy and return
+ if (!UpdateVictim())
+ {
+ dummy_dragonAI::UpdateAI(diff);
+ return;
+ }
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHADOW_FISSURE_SHADRON:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE_H));
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE_SHADRON, urand(15000, 20000));
+ break;
+ case EVENT_ACOLYTE_SHADRON:
+ if (instance->GetBossState(DATA_PORTAL_OPEN) == NOT_STARTED)
+ events.ScheduleEvent(EVENT_ACOLYTE_SHADRON, 10000);
+ else
+ {
+ if (me->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
+ return;
+
+ OpenPortal();
+
+ if (instance)
+ instance->SetBossState(DATA_PORTAL_OPEN, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_ACOLYTE_SHADRON, urand(60000, 65000));
+ }
+ break;
+ case EVENT_SHADOW_BREATH_SHADRON:
+ Talk(SAY_BREATH);
+ DoCastVictim(RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
+ events.ScheduleEvent(EVENT_SHADOW_BREATH_SHADRON, urand(20000, 25000));
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_shadronAI(creature);
+ }
+};
+
+/*######
+## Vesperon
+######*/
+
+enum VesperonEvents
+{
+ EVENT_SHADOW_FISSURE_VESPERON = 8,
+ EVENT_ACOLYTE_VESPERON = 9,
+ EVENT_SHADOW_BREATH_VESPERON = 10
+};
+
+class npc_vesperon : public CreatureScript
+{
+public:
+ npc_vesperon() : CreatureScript("npc_vesperon") { }
+
+ struct npc_vesperonAI : public dummy_dragonAI
+ {
+ npc_vesperonAI(Creature* creature) : dummy_dragonAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() OVERRIDE
+ {
+ dummy_dragonAI::Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ Talk(SAY_AGGRO);
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE_VESPERON, 5000);
+ events.ScheduleEvent(EVENT_ACOLYTE_VESPERON, 60000);
+ events.ScheduleEvent(EVENT_SHADOW_BREATH_VESPERON, 20000);
+ }
+
+ void KilledUnit(Unit* /*victim*/) OVERRIDE
+ {
+ Talk(SAY_SLAY);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ //if no target, update dummy and return
+ if (!UpdateVictim())
+ {
+ dummy_dragonAI::UpdateAI(diff);
+ return;
+ }
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHADOW_FISSURE_VESPERON:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE_H));
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE_VESPERON, urand(15000, 20000));
+ break;
+ case EVENT_ACOLYTE_VESPERON:
+ if (instance->GetBossState(DATA_PORTAL_OPEN) == IN_PROGRESS)
+ events.ScheduleEvent(EVENT_ACOLYTE_VESPERON, 10000);
+ else
+ {
+ OpenPortal();
+ DoCastVictim(SPELL_TWILIGHT_TORMENT_VESP);
+ events.ScheduleEvent(EVENT_ACOLYTE_VESPERON, urand(60000, 70000));
+ }
+ break;
+ case EVENT_SHADOW_BREATH_VESPERON:
+ Talk(SAY_BREATH);
+ DoCastVictim(RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
+ events.ScheduleEvent(EVENT_SHADOW_BREATH_VESPERON, urand(20000, 25000));
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_vesperonAI(creature);
+ }
+};
+
+/*######
+## Acolyte of Shadron
+######*/
+
+class npc_acolyte_of_shadron : public CreatureScript
+{
+public:
+ npc_acolyte_of_shadron() : CreatureScript("npc_acolyte_of_shadron") { }
+
+ struct npc_acolyte_of_shadronAI : public ScriptedAI
+ {
+ npc_acolyte_of_shadronAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() OVERRIDE
+ {
+ // Despawn the NPC automatically after 28 seconds
+ me->DespawnOrUnsummon(28000);
+
+ if (instance)
+ {
+ //if not solo fight, buff main boss, else place debuff on mini-boss. both spells TARGET_SCRIPT
+ if (instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ {
+ if (Creature* sartharion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SARTHARION)))
+ sartharion->AddAura(SPELL_GIFT_OF_TWILIGTH_SAR, sartharion);
+ }
+ else
+ {
+ if (Creature* shadron = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SHADRON)))
+ shadron->AddAura(SPELL_GIFT_OF_TWILIGTH_SHA, shadron);
+ }
+ }
+
+ me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER, me);
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ if (instance)
+ {
+ if (ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SHADRON)))
+ instance->SetBossState(DATA_PORTAL_OPEN, NOT_STARTED);
+
+ Map* map = me->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->GetSource()->IsAlive() && i->GetSource()->HasAura(SPELL_TWILIGHT_SHIFT, 0) && !i->GetSource()->GetVictim())
+ {
+ i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_SHIFT_REMOVAL_ALL, true);
+ i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_RESIDUE, true);
+ i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
+ i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_ENTER);
+ }
+ }
+ }
+
+ // not solo fight, so main boss has debuff
+ if (Creature* debuffTarget = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SARTHARION)))
+ if (debuffTarget->IsAlive() && debuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SAR))
+ debuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SAR);
+
+ // event not in progress, then solo fight and must remove debuff mini-boss
+ if (Creature* debuffTarget = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SHADRON)))
+ if (debuffTarget->IsAlive() && debuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
+ debuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
+ }
+ }
+
+ void UpdateAI(uint32 /*diff*/) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_acolyte_of_shadronAI(creature);
+ }
+};
+
+/*######
+## Acolyte of Vesperon
+######*/
+
+class npc_acolyte_of_vesperon : public CreatureScript
+{
+public:
+ npc_acolyte_of_vesperon() : CreatureScript("npc_acolyte_of_vesperon") { }
+
+ struct npc_acolyte_of_vesperonAI : public ScriptedAI
+ {
+ npc_acolyte_of_vesperonAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() OVERRIDE
+ {
+ // Despawn the NPC automatically after 28 seconds
+ me->DespawnOrUnsummon(28000);
+
+ if (instance)
+ me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER, me);
+
+ DoCast(me, SPELL_TWILIGHT_TORMENT_VESP_ACO);
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ me->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP_ACO);
+
+ // remove twilight torment on Vesperon
+ if (instance)
+ {
+ if (Creature* vesperon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VESPERON)))
+ {
+ instance->SetBossState(DATA_PORTAL_OPEN, NOT_STARTED);
+
+ if (vesperon->IsAlive() && vesperon->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
+ vesperon->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
+ }
+
+ Map* map = me->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->GetSource()->IsAlive() && i->GetSource()->HasAura(SPELL_TWILIGHT_SHIFT, 0) && !i->GetSource()->GetVictim())
+ {
+ i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_SHIFT_REMOVAL_ALL, true);
+ i->GetSource()->CastSpell(i->GetSource(), SPELL_TWILIGHT_RESIDUE, true);
+ i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
+ i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_ENTER);
+ }
+ if (i->GetSource()->IsAlive() && i->GetSource()->HasAura(SPELL_TWILIGHT_TORMENT_VESP, 0) && !i->GetSource()->GetVictim())
+ i->GetSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
+ }
+ }
+
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_TWILIGHT_TORMENT_VESP_ACO);
+ instance->DoRemoveAurasDueToSpellOnPlayers(57935);
+ instance->DoRemoveAurasDueToSpellOnPlayers(58835); // Components of spell Twilight Torment
+ }
+ }
+
+ void UpdateAI(uint32 /*diff*/) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_acolyte_of_vesperonAI(creature);
+ }
+};
+
+/*######
+## Twilight Eggs
+######*/
+
+enum TwilightEggs
+{
+ EVENT_TWILIGHT_EGGS = 11
+};
+
+class npc_twilight_eggs : public CreatureScript
+{
+public:
+ npc_twilight_eggs() : CreatureScript("npc_twilight_eggs") { }
+
+ struct npc_twilight_eggsAI : public ScriptedAI
+ {
+ npc_twilight_eggsAI(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ instance = creature->GetInstanceScript();
+ }
+
+ void Reset() OVERRIDE
+ {
+ if (instance)
+ me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER, me);
+
+ events.ScheduleEvent(EVENT_TWILIGHT_EGGS, 20000);
+ }
+
+ void SpawnWhelps()
+ {
+ me->RemoveAllAuras();
+
+ if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ me->SummonCreature(NPC_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
+ else
+ me->SummonCreature(NPC_SHARTHARION_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
+ me->DealDamage(me, me->GetHealth());
+ }
+
+ void JustSummoned(Creature* who) OVERRIDE
+ {
+ who->SetInCombatWithZone();
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_TWILIGHT_EGGS)
+ {
+ if (ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TENEBRON)))
+ instance->SetBossState(DATA_PORTAL_OPEN, NOT_STARTED);
+
+ SpawnWhelps();
+ }
+ }
+
+ private:
+ InstanceScript* instance;
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_twilight_eggsAI(creature);
+ }
+};
+
+/*######
+## Flame Tsunami
+######*/
+
+enum FlameTsunami
+{
+ EVENT_TSUNAMI_TIMER = 12,
+ EVENT_TSUNAMI_BUFF = 13
+};
+
+class npc_flame_tsunami : public CreatureScript
+{
+public:
+ npc_flame_tsunami() : CreatureScript("npc_flame_tsunami") { }
+
+ struct npc_flame_tsunamiAI : public ScriptedAI
+ {
+ npc_flame_tsunamiAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetDisplayId(11686);
+ me->AddAura(SPELL_FLAME_TSUNAMI, me);
+ }
+
+ void Reset() OVERRIDE
+ {
+ me->SetReactState(REACT_PASSIVE);
+ events.ScheduleEvent(EVENT_TSUNAMI_TIMER, 100);
+ events.ScheduleEvent(EVENT_TSUNAMI_BUFF, 1000);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_TSUNAMI_TIMER:
+ DoCast(me, SPELL_FLAME_TSUNAMI_DMG_AURA);
+ events.ScheduleEvent(EVENT_TSUNAMI_TIMER, 500);
+ break;
+ case EVENT_TSUNAMI_BUFF:
+ if (Unit* lavaBlaze = GetClosestCreatureWithEntry(me, NPC_LAVA_BLAZE, 10.0f, true))
+ lavaBlaze->CastSpell(lavaBlaze, SPELL_FLAME_TSUNAMI_BUFF, true);
+ events.ScheduleEvent(EVENT_TSUNAMI_BUFF, 1000);
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_flame_tsunamiAI(creature);
+ }
+};
+
+/*######
+## Twilight Fissure
+######*/
+
+enum TwilightFissure
+{
+ EVENT_VOID_BLAST = 14
+};
+
+class npc_twilight_fissure : public CreatureScript
+{
+public:
+ npc_twilight_fissure() : CreatureScript("npc_twilight_fissure") { }
+
+ struct npc_twilight_fissureAI : public ScriptedAI
+ {
+ npc_twilight_fissureAI(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ }
+
+ void Reset() OVERRIDE
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->AddAura(46265, me); // Wrong, can't find proper visual
+ me->AddAura(69422, me);
+ events.ScheduleEvent(EVENT_VOID_BLAST, 5000);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_VOID_BLAST)
+ {
+ DoCastAOE(RAID_MODE(SPELL_VOID_BLAST, SPELL_VOID_BLAST_H));
+ ////twilight realm
+ //DoCastVictim(57620, true);
+ //DoCastVictim(57874, true);
+ me->RemoveAllAuras();
+ me->Kill(me);
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_twilight_fissureAI(creature);
+ }
+};
+
+/*######
+## Twilight Whelps
+######*/
+
+enum TwilightWhelps
+{
+ EVENT_FADE_ARMOR = 15
+};
+
+class npc_twilight_whelp : public CreatureScript
+{
+public:
+ npc_twilight_whelp() : CreatureScript("npc_twilight_whelp") { }
+
+ struct npc_twilight_whelpAI : public ScriptedAI
+ {
+ npc_twilight_whelpAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Reset();
+ }
+
+ void Reset() OVERRIDE
+ {
+ me->RemoveAllAuras();
+ me->SetInCombatWithZone();
+ events.ScheduleEvent(EVENT_FADE_ARMOR, 1000);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ // twilight torment
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_FADE_ARMOR)
+ {
+ DoCastVictim(SPELL_FADE_ARMOR);
+ events.ScheduleEvent(EVENT_FADE_ARMOR, urand(5000, 10000));
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_twilight_whelpAI(creature);
+ }
+};
+
+class achievement_twilight_assist : public AchievementCriteriaScript
+{
+ public:
+ achievement_twilight_assist() : AchievementCriteriaScript("achievement_twilight_assist") { }
+
+ bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
+ {
+ return target && target->GetAI()->GetData(TWILIGHT_ACHIEVEMENTS) >= 1;
+ }
+};
+
+class achievement_twilight_duo : public AchievementCriteriaScript
+{
+ public:
+ achievement_twilight_duo() : AchievementCriteriaScript("achievement_twilight_duo") { }
+
+ bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
+ {
+ return target && target->GetAI()->GetData(TWILIGHT_ACHIEVEMENTS) >= 2;
+ }
+};
+
+class achievement_twilight_zone : public AchievementCriteriaScript
+{
+ public:
+ achievement_twilight_zone() : AchievementCriteriaScript("achievement_twilight_zone") { }
+
+ bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
+ {
+ return target && target->GetAI()->GetData(TWILIGHT_ACHIEVEMENTS) == 3;
+ }
+};
+
+void AddSC_obsidian_sanctum()
+{
+ new npc_vesperon();
+ new npc_shadron();
+ new npc_tenebron();
+ new npc_acolyte_of_shadron();
+ new npc_acolyte_of_vesperon();
+ new npc_twilight_eggs();
+ new npc_flame_tsunami();
+ new npc_twilight_fissure();
+ new npc_twilight_whelp();
+ new achievement_twilight_assist();
+ new achievement_twilight_duo();
+ new achievement_twilight_zone();
+}
+
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h
index 7d2403be469..8cfb3931372 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.h
@@ -18,17 +18,18 @@
#ifndef DEF_OBSIDIAN_SANCTUM_H
#define DEF_OBSIDIAN_SANCTUM_H
+#define OSScriptName "instance_obsidian_sanctum"
+
+uint32 const EncounterCount = 5;
+
enum DataTypes
{
- TYPE_SARTHARION_EVENT = 1,
- TYPE_TENEBRON_PREKILLED = 2,
- TYPE_SHADRON_PREKILLED = 3,
- TYPE_VESPERON_PREKILLED = 4,
-
- DATA_SARTHARION = 10,
- DATA_TENEBRON = 11,
- DATA_SHADRON = 12,
- DATA_VESPERON = 13
+ DATA_SARTHARION = 0,
+ DATA_TENEBRON = 1,
+ DATA_SHADRON = 2,
+ DATA_VESPERON = 3,
+ DATA_PORTAL_OPEN = 4,
+ TWILIGHT_ACHIEVEMENTS = 5
};
enum CreaturesIds
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
index 8f6b951d524..3fdfc0c8ae3 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -310,8 +310,6 @@ class npc_snobold_vassal : public CreatureScript
_targetGUID = 0;
_targetDied = false;
- if (_instance)
- _bossGUID = _instance->GetData64(NPC_GORMOK);
//Workaround for Snobold
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
}
@@ -450,7 +448,6 @@ class npc_snobold_vassal : public CreatureScript
private:
EventMap _events;
InstanceScript* _instance;
- uint64 _bossGUID;
uint64 _targetGUID;
bool _targetDied;
};
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
index 9e401c4f962..a72d3917004 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
@@ -366,7 +366,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
if (type < MAX_ENCOUNTERS)
{
- TC_LOG_INFO(LOG_FILTER_TSCR, "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state);
+ TC_LOG_INFO("scripts", "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state);
if (state == FAIL)
{
if (instance->IsHeroic())
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
index ae57732e9e2..b1339b13119 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/instance_forge_of_souls.cpp
@@ -43,12 +43,21 @@ class instance_forge_of_souls : public InstanceMapScript
teamInInstance = 0;
}
+ void OnPlayerEnter(Player* player) OVERRIDE
+ {
+ if (!teamInInstance)
+ teamInInstance = player->GetTeam();
+ }
+
void OnCreatureCreate(Creature* creature) OVERRIDE
{
- Map::PlayerList const &players = instance->GetPlayers();
- if (!players.isEmpty())
- if (Player* player = players.begin()->GetSource())
- teamInInstance = player->GetTeam();
+ if (!teamInInstance)
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+ if (!players.isEmpty())
+ if (Player* player = players.begin()->GetSource())
+ teamInInstance = player->GetTeam();
+ }
switch (creature->GetEntry())
{
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index 1b82de35f54..96b772df5a9 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -1089,9 +1089,9 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript
break;
case EVENT_ESCAPE_27:
if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
- me->SummonGameObject(GO_CAPTAIN_CHEST_1, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000);
+ me->SummonGameObject(IsHeroic() ? GO_CAPTAIN_CHEST_ALLIANCE_HEROIC : GO_CAPTAIN_CHEST_ALLIANCE_NORMAL, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000);
else
- me->SummonGameObject(GO_CAPTAIN_CHEST_3, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000);
+ me->SummonGameObject(IsHeroic() ? GO_CAPTAIN_CHEST_HORDE_HEROIC : GO_CAPTAIN_CHEST_HORDE_NORMAL, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000);
me->SummonGameObject(GO_PORTAL, FinalPortalPos.GetPositionX(), FinalPortalPos.GetPositionY(), FinalPortalPos.GetPositionZ(), FinalPortalPos.GetOrientation(), 0, 0, 0, 0, 720000);
if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID))
lichking->DespawnOrUnsummon(1);
@@ -1121,6 +1121,7 @@ enum TrashSpells
SPELL_FROSTBOLT = 72166,
SPELL_CHAINS_OF_ICE = 72121,
SPELL_HALLUCINATION = 72342,
+ AURA_HALLUCINATION = 72343,
// Phantom Hallucination (same as phantom mage + HALLUCINATION_2 when dies)
SPELL_HALLUCINATION_2 = 72344,
@@ -1180,13 +1181,11 @@ enum TrashEvents
struct npc_gauntlet_trash : public ScriptedAI
{
- npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
+ npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
void Reset() OVERRIDE
{
+ InternalWaveId = 0;
me->CastSpell(me, SPELL_WELL_OF_SOULS, true);
_events.Reset();
}
@@ -1226,9 +1225,7 @@ public:
struct npc_ghostly_priestAI : public npc_gauntlet_trash
{
- npc_ghostly_priestAI(Creature* creature) : npc_gauntlet_trash(creature)
- {
- }
+ npc_ghostly_priestAI(Creature* creature) : npc_gauntlet_trash(creature) { }
void EnterCombat(Unit* /*who*/) OVERRIDE
{
@@ -1297,8 +1294,12 @@ public:
struct npc_phantom_mageAI : public npc_gauntlet_trash
{
- npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature)
+ npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature) { }
+
+ void EnterEvadeMode() OVERRIDE
{
+ if (!me->HasAura(AURA_HALLUCINATION))
+ npc_gauntlet_trash::EnterEvadeMode();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
@@ -1342,6 +1343,8 @@ public:
_events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000);
break;
case EVENT_HALLUCINATION:
+ // removing any dots on mage or else the invisibility spell will break duration
+ me->RemoveAllAuras();
DoCast(SPELL_HALLUCINATION);
break;
}
@@ -1365,6 +1368,19 @@ public:
{
npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature) { }
+ void Reset() OVERRIDE
+ {
+ if (Unit* unit = me->SelectNearestTarget())
+ AttackStart(unit);
+ DoZoneInCombat();
+ }
+
+ void EnterEvadeMode() OVERRIDE
+ {
+ if (!me->GetOwner()->HasAura(AURA_HALLUCINATION))
+ npc_phantom_mage::npc_phantom_mageAI::EnterEvadeMode();
+ }
+
void JustDied(Unit* /*killer*/) OVERRIDE
{
DoCast(SPELL_HALLUCINATION_2);
@@ -1384,9 +1400,7 @@ public:
struct npc_shadowy_mercenaryAI : public npc_gauntlet_trash
{
- npc_shadowy_mercenaryAI(Creature* creature) : npc_gauntlet_trash(creature)
- {
- }
+ npc_shadowy_mercenaryAI(Creature* creature) : npc_gauntlet_trash(creature) { }
void EnterCombat(Unit* /*who*/) OVERRIDE
{
@@ -1444,9 +1458,7 @@ public:
struct npc_spectral_footmanAI : public npc_gauntlet_trash
{
- npc_spectral_footmanAI(Creature* creature) : npc_gauntlet_trash(creature)
- {
- }
+ npc_spectral_footmanAI(Creature* creature) : npc_gauntlet_trash(creature) { }
void EnterCombat(Unit* /*who*/) OVERRIDE
{
@@ -1498,9 +1510,7 @@ public:
struct npc_tortured_riflemanAI : public npc_gauntlet_trash
{
- npc_tortured_riflemanAI(Creature* creature) : npc_gauntlet_trash(creature)
- {
- }
+ npc_tortured_riflemanAI(Creature* creature) : npc_gauntlet_trash(creature) { }
void EnterCombat(Unit* /*who*/) OVERRIDE
{
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
index d8d4f2d5524..9c40cb70141 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
@@ -95,10 +95,10 @@ enum GameObjects
GO_ORGRIM_HAMMER = 201599,
GO_PORTAL = 202079,
- GO_CAPTAIN_CHEST_1 = 202212, //3145
- GO_CAPTAIN_CHEST_2 = 201710, //30357
- GO_CAPTAIN_CHEST_3 = 202337, //3246
- GO_CAPTAIN_CHEST_4 = 202336, //3333
+ GO_CAPTAIN_CHEST_HORDE_NORMAL = 202212, //3145
+ GO_CAPTAIN_CHEST_ALLIANCE_NORMAL = 201710, //30357
+ GO_CAPTAIN_CHEST_HORDE_HEROIC = 202337, //3246
+ GO_CAPTAIN_CHEST_ALLIANCE_HEROIC = 202336, //3333
};
enum HorWorldStates
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
index 0599596fc0a..955f4fb1568 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp
@@ -110,10 +110,13 @@ public:
void OnCreatureCreate(Creature* creature) OVERRIDE
{
- Map::PlayerList const& players = instance->GetPlayers();
- if (!players.isEmpty())
- if (Player* player = players.begin()->GetSource())
- _teamInInstance = player->GetTeam();
+ if (!_teamInInstance)
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+ if (!players.isEmpty())
+ if (Player* player = players.begin()->GetSource())
+ _teamInInstance = player->GetTeam();
+ }
switch (creature->GetEntry())
{
@@ -184,7 +187,7 @@ public:
case GO_ARTHAS_DOOR:
_arthasDoorGUID = go->GetGUID();
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
- if (GetBossState(DATA_FROSWORN_EVENT) == DONE)
+ if (GetData(DATA_FROSWORN_EVENT) == DONE)
HandleGameObject(0, true, go);
else
HandleGameObject(0, false, go);
@@ -511,13 +514,13 @@ public:
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
- saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral << _escapeevent;
+ saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral << ' ' << _escapeevent;
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
- void Load(char const* in) OVERRIDE OVERRIDE
+ void Load(char const* in) OVERRIDE
{
if (!in)
{
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
index 20b7d39815f..4a9a41f6f8e 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
@@ -187,7 +187,7 @@ class boss_garfrost : public CreatureScript
switch (eventId)
{
case EVENT_THROW_SARONITE:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
Talk(SAY_THROW_SARONITE, target->GetGUID());
DoCast(target, SPELL_THROW_SARONITE);
@@ -199,7 +199,7 @@ class boss_garfrost : public CreatureScript
events.ScheduleEvent(EVENT_CHILLING_WAVE, 40000, 0, PHASE_TWO);
break;
case EVENT_DEEP_FREEZE:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
Talk(SAY_CAST_DEEP_FREEZE, target->GetGUID());
DoCast(target, SPELL_DEEP_FREEZE);
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index d8a4dd01f90..48cc6f89a13 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -385,32 +385,25 @@ class boss_rimefang : public CreatureScript
class player_overlord_brandAI : public PlayerAI
{
public:
- player_overlord_brandAI(Player* player) : PlayerAI(player), _tyrannus(0)
- {
- }
-
- void SetGUID(uint64 guid, int32 /*type*/) OVERRIDE
- {
- _tyrannus = guid;
- }
+ player_overlord_brandAI(Player* player, uint64 casterGUID) : PlayerAI(player), _tyrannusGUID(casterGUID) { }
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/) OVERRIDE
{
- if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannus))
- if (tyrannus->GetVictim())
- me->CastCustomSpell(SPELL_OVERLORD_BRAND_DAMAGE, SPELLVALUE_BASE_POINT0, damage, tyrannus->GetVictim(), true, NULL, NULL, tyrannus->GetGUID());
+ if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID))
+ if (Unit* victim = tyrannus->GetVictim())
+ me->CastCustomSpell(SPELL_OVERLORD_BRAND_DAMAGE, SPELLVALUE_BASE_POINT0, damage, victim, true, NULL, NULL, tyrannus->GetGUID());
}
void HealDone(Unit* /*target*/, uint32& addHealth) OVERRIDE
{
- if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannus))
- me->CastCustomSpell(SPELL_OVERLORD_BRAND_HEAL, SPELLVALUE_BASE_POINT0, int32(addHealth*5.5f), tyrannus, true, NULL, NULL, tyrannus->GetGUID());
+ if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannusGUID))
+ me->CastCustomSpell(SPELL_OVERLORD_BRAND_HEAL, SPELLVALUE_BASE_POINT0, int32(addHealth * 5.5f), tyrannus, true, NULL, NULL, tyrannus->GetGUID());
}
void UpdateAI(uint32 /*diff*/) OVERRIDE { }
private:
- uint64 _tyrannus;
+ uint64 _tyrannusGUID;
};
class spell_tyrannus_overlord_brand : public SpellScriptLoader
@@ -434,8 +427,8 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
oldAI = GetTarget()->GetAI();
oldAIState = GetTarget()->IsAIEnabled;
- GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer()));
- GetTarget()->GetAI()->SetGUID(GetCasterGUID());
+ GetTarget()->SetAI(new player_overlord_brandAI(GetTarget()->ToPlayer(), GetCasterGUID()));
+ GetTarget()->IsAIEnabled = true;
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
index 7aa8b123f98..d61fc69a0ae 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp
@@ -63,7 +63,7 @@ class instance_pit_of_saron : public InstanceMapScript
{
if (!_teamInInstance)
{
- Map::PlayerList const &players = instance->GetPlayers();
+ Map::PlayerList const& players = instance->GetPlayers();
if (!players.isEmpty())
if (Player* player = players.begin()->GetSource())
_teamInInstance = player->GetTeam();
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
index a5c35650032..f76c46d96ff 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
@@ -200,7 +200,7 @@ class boss_gothik : public CreatureScript
if (LiveTriggerGUID.size() < POS_LIVE || DeadTriggerGUID.size() < POS_DEAD)
{
- TC_LOG_ERROR(LOG_FILTER_TSCR, "Script Gothik: cannot summon triggers!");
+ TC_LOG_ERROR("scripts", "Script Gothik: cannot summon triggers!");
EnterEvadeMode();
return;
}
@@ -514,6 +514,7 @@ class npc_gothik_minion : public CreatureScript
npc_gothik_minionAI(Creature* creature) : CombatAI(creature)
{
liveSide = IN_LIVE_SIDE(me);
+ gateClose = false;
}
bool liveSide;
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 a1511fb3dd8..4777b451e4e 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
@@ -165,7 +165,7 @@ public:
unit->SetControlled(true, UNIT_STATE_ROOT);
}
- void ProcessEvent(WorldObject* /*obj*/, uint32 eventId)
+ void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) OVERRIDE
{
if (eventId == EVENT_FOCUSING_IRIS)
{
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_drakos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_drakos.cpp
index 25091a457f2..d22a0bcc79f 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_drakos.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_drakos.cpp
@@ -52,141 +52,141 @@ enum DrakosEvents
class boss_drakos : public CreatureScript
{
-public:
- boss_drakos() : CreatureScript("boss_drakos") { }
+ public:
+ boss_drakos() : CreatureScript("boss_drakos") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_drakosAI(creature);
- }
-
- struct boss_drakosAI : public BossAI
- {
- boss_drakosAI(Creature* creature) : BossAI(creature, DATA_DRAKOS_EVENT) { }
-
- void Reset() OVERRIDE
+ struct boss_drakosAI : public BossAI
{
- _Reset();
+ boss_drakosAI(Creature* creature) : BossAI(creature, DATA_DRAKOS) { }
- events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
- events.ScheduleEvent(EVENT_STOMP, 17000);
- events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
+ void Reset() OVERRIDE
+ {
+ _Reset();
- postPull = false;
- }
+ events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
+ events.ScheduleEvent(EVENT_STOMP, 17000);
+ events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- Talk(SAY_AGGRO);
- }
+ postPull = false;
+ }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
- events.Update(diff);
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ events.Update(diff);
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_BOMB_SUMMON:
- {
- Position pPosition;
- me->GetPosition(&pPosition);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- for (uint8 i = 0; i <= (postPull ? 3 : 0); i++)
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BOMB_SUMMON:
{
- me->GetRandomNearPosition(pPosition, float(urand(0, 10)));
- me->SummonCreature(NPC_UNSTABLE_SPHERE, pPosition);
+ Position position;
+ me->GetPosition(&position);
+
+ for (uint8 i = 0; i <= (postPull ? 3 : 0); i++)
+ {
+ me->GetRandomNearPosition(position, frand(0.0f, 10.0f));
+ me->SummonCreature(NPC_UNSTABLE_SPHERE, position);
+ }
}
- }
- events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
- break;
- case EVENT_MAGIC_PULL:
- DoCast(SPELL_MAGIC_PULL);
- postPull = true;
- events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
- break;
- case EVENT_STOMP:
- Talk(SAY_STOMP);
- DoCast(SPELL_THUNDERING_STOMP);
- events.ScheduleEvent(EVENT_STOMP, 17000);
- break;
+ events.ScheduleEvent(EVENT_BOMB_SUMMON, 2000);
+ break;
+ case EVENT_MAGIC_PULL:
+ DoCast(SPELL_MAGIC_PULL);
+ postPull = true;
+ events.ScheduleEvent(EVENT_MAGIC_PULL, 15000);
+ break;
+ case EVENT_STOMP:
+ Talk(SAY_STOMP);
+ DoCast(SPELL_THUNDERING_STOMP);
+ events.ScheduleEvent(EVENT_STOMP, 17000);
+ break;
+ default:
+ break;
+ }
}
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
- }
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
+ Talk(SAY_DEATH);
- Talk(SAY_DEATH);
+ // start achievement timer (kill Eregos within 20 min)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
- // start achievement timer (kill Eregos within 20 min)
- instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
- }
+ void KilledUnit(Unit* /*victim*/) OVERRIDE
+ {
+ Talk(SAY_KILL);
+ }
+
+ private:
+ bool postPull;
+ };
- void KilledUnit(Unit* /*victim*/) OVERRIDE
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- Talk(SAY_KILL);
+ return GetOculusAI<boss_drakosAI>(creature);
}
- private:
- bool postPull;
- };
};
class npc_unstable_sphere : public CreatureScript
{
-public:
- npc_unstable_sphere() : CreatureScript("npc_unstable_sphere") { }
+ public:
+ npc_unstable_sphere() : CreatureScript("npc_unstable_sphere") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_unstable_sphereAI(creature);
- }
+ struct npc_unstable_sphereAI : public ScriptedAI
+ {
+ npc_unstable_sphereAI(Creature* creature) : ScriptedAI(creature) { }
- struct npc_unstable_sphereAI : public ScriptedAI
- {
- npc_unstable_sphereAI(Creature* creature) : ScriptedAI(creature) { }
+ void Reset() OVERRIDE
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MoveRandom(40.0f);
- void Reset() OVERRIDE
- {
- me->SetReactState(REACT_PASSIVE);
- me->GetMotionMaster()->MoveRandom(40.0f);
+ me->AddAura(SPELL_UNSTABLE_SPHERE_PASSIVE, me);
+ me->AddAura(SPELL_UNSTABLE_SPHERE_TIMER, me);
- me->AddAura(SPELL_UNSTABLE_SPHERE_PASSIVE, me);
- me->AddAura(SPELL_UNSTABLE_SPHERE_TIMER, me);
+ pulseTimer = 3000;
- pulseTimer = 3000;
- deathTimer = 19000;
- }
+ me->DespawnOrUnsummon(19000);
+ }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (pulseTimer <= diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
- DoCast(SPELL_UNSTABLE_SPHERE_PULSE);
- pulseTimer = 3*IN_MILLISECONDS;
- } else pulseTimer -= diff;
+ if (pulseTimer <= diff)
+ {
+ DoCast(SPELL_UNSTABLE_SPHERE_PULSE);
+ pulseTimer = 3 * IN_MILLISECONDS;
+ }
+ else
+ pulseTimer -= diff;
+ }
- if (deathTimer <= diff)
- me->DisappearAndDie();
- else deathTimer -= diff;
- }
- private:
- uint32 pulseTimer;
- uint32 deathTimer;
- };
+ private:
+ uint32 pulseTimer;
+ };
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_unstable_sphereAI(creature);
+ }
};
void AddSC_boss_drakos()
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp
index abf0d6537c3..ca6f580633c 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_eregos.cpp
@@ -21,8 +21,8 @@
#include "SpellAuraEffects.h"
#include "oculus.h"
-//Types of drake mounts: Ruby(Tank), Amber(DPS), Emerald(Healer)
-//Two Repeating phases
+// Types of drake mounts: Ruby (Tank), Amber (DPS), Emerald (Healer)
+// Two Repeating phases
enum Events
{
@@ -61,8 +61,8 @@ enum Npcs
enum Phases
{
- PHASE_NORMAL = 1,
- PHASE_FIRST_PLANAR = 2,
+ PHASE_NORMAL = 1,
+ PHASE_FIRST_PLANAR = 2,
PHASE_SECOND_PLANAR = 3
};
@@ -80,172 +80,174 @@ enum EregosData
class boss_eregos : public CreatureScript
{
-public:
- boss_eregos() : CreatureScript("boss_eregos") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_eregosAI(creature);
- }
-
- struct boss_eregosAI : public BossAI
- {
- boss_eregosAI(Creature* creature) : BossAI(creature, DATA_EREGOS_EVENT) { }
+ public:
+ boss_eregos() : CreatureScript("boss_eregos") { }
- void Reset() OVERRIDE
+ struct boss_eregosAI : public BossAI
{
- _Reset();
- _phase = PHASE_NORMAL;
-
- _rubyVoid = true;
- _emeraldVoid = true;
- _amberVoid = true;
+ boss_eregosAI(Creature* creature) : BossAI(creature, DATA_EREGOS) { }
- DoAction(ACTION_SET_NORMAL_EVENTS);
- }
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ _phase = PHASE_NORMAL;
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- Talk(SAY_KILL);
- }
+ _rubyVoid = true;
+ _emeraldVoid = true;
+ _amberVoid = true;
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
-
- Talk(SAY_AGGRO);
- /* Checks for present drakes vehicles from each type and deactivate achievement that corresponds to each found
- The checks are so big in case some party try weird things like pulling boss down or hiding out of check range, the only thing player need is to get the boss kill credit after the check /even if he or his drake die/
- Drakes mechanic would despawn all after unmount and also drakes should be auto mounted after item use, item use after Eregos is engaged leads to his despawn - based on retail data. */
- if (me->FindNearestCreature(NPC_RUBY_DRAKE_VEHICLE, 500.0f, true))
- _rubyVoid = false;
- if (me->FindNearestCreature(NPC_EMERALD_DRAKE_VEHICLE, 500.0f, true))
- _emeraldVoid = false;
- if (me->FindNearestCreature(NPC_AMBER_DRAKE_VEHICLE, 500.0f, true))
- _amberVoid = false;
- }
+ DoAction(ACTION_SET_NORMAL_EVENTS);
+ }
- uint32 GetData(uint32 type) const OVERRIDE
- {
- switch (type)
- {
- case DATA_RUBY_VOID:
- return _rubyVoid;
- case DATA_EMERALD_VOID:
- return _emeraldVoid;
- case DATA_AMBER_VOID:
- return _amberVoid;
- default:
- break;
+ void KilledUnit(Unit* /*victim*/) OVERRIDE
+ {
+ Talk(SAY_KILL);
}
- return 0;
- }
- void DoAction(int32 action) OVERRIDE
- {
- if (action != ACTION_SET_NORMAL_EVENTS)
- return;
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+
+ Talk(SAY_AGGRO);
+ /* Checks for present drakes vehicles from each type and deactivate achievement that corresponds to each found
+ The checks are so big in case some party try weird things like pulling boss down or hiding out of check range, the only thing player need is to get the boss kill credit after the check /even if he or his drake die/
+ Drakes mechanic would despawn all after unmount and also drakes should be auto mounted after item use, item use after Eregos is engaged leads to his despawn - based on retail data. */
+ if (me->FindNearestCreature(NPC_RUBY_DRAKE_VEHICLE, 500.0f, true))
+ _rubyVoid = false;
+ if (me->FindNearestCreature(NPC_EMERALD_DRAKE_VEHICLE, 500.0f, true))
+ _emeraldVoid = false;
+ if (me->FindNearestCreature(NPC_AMBER_DRAKE_VEHICLE, 500.0f, true))
+ _amberVoid = false;
+ }
- events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- }
+ uint32 GetData(uint32 type) const OVERRIDE
+ {
+ switch (type)
+ {
+ case DATA_RUBY_VOID:
+ return _rubyVoid;
+ case DATA_EMERALD_VOID:
+ return _emeraldVoid;
+ case DATA_AMBER_VOID:
+ return _amberVoid;
+ default:
+ break;
+ }
+ return 0;
+ }
- void JustSummoned(Creature* summon) OVERRIDE
- {
- BossAI::JustSummoned(summon);
+ void DoAction(int32 action) OVERRIDE
+ {
+ if (action != ACTION_SET_NORMAL_EVENTS)
+ return;
+
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ }
- if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
- return;
+ void JustSummoned(Creature* summon) OVERRIDE
+ {
+ BossAI::JustSummoned(summon);
- summon->CombatStop(true);
- summon->SetReactState(REACT_PASSIVE);
- summon->GetMotionMaster()->MoveRandom(100.0f);
- }
+ if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
+ return;
- void SummonedCreatureDespawn(Creature* summon) OVERRIDE
- {
- if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
- return;
+ summon->CombatStop(true);
+ summon->SetReactState(REACT_PASSIVE);
+ summon->GetMotionMaster()->MoveRandom(100.0f);
+ }
- // TO-DO: See why the spell is not casted
- summon->CastSpell(summon, SPELL_PLANAR_BLAST, true);
- }
+ void SummonedCreatureDespawn(Creature* summon) OVERRIDE
+ {
+ if (summon->GetEntry() != NPC_PLANAR_ANOMALY)
+ return;
- void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
- {
- if (!me->GetMap()->IsHeroic())
- return;
+ /// @todo: See why the spell is not casted
+ summon->CastSpell(summon, SPELL_PLANAR_BLAST, true);
+ }
- if ( (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f && _phase < PHASE_FIRST_PLANAR)
- || (me->GetHealthPct() < 20.0f && _phase < PHASE_SECOND_PLANAR) )
+ void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
{
- events.Reset();
- _phase = (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f) ? PHASE_FIRST_PLANAR : PHASE_SECOND_PLANAR;
+ if (!IsHeroic())
+ return;
- Talk(SAY_SHIELD);
- DoCast(SPELL_PLANAR_SHIFT);
+ if ( (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f && _phase < PHASE_FIRST_PLANAR)
+ || (me->GetHealthPct() < 20.0f && _phase < PHASE_SECOND_PLANAR) )
+ {
+ events.Reset();
+ _phase = (me->GetHealthPct() < 60.0f && me->GetHealthPct() > 20.0f) ? PHASE_FIRST_PLANAR : PHASE_SECOND_PLANAR;
- // not sure about the amount, and if we should despawn previous spawns (dragon trashs)
- summons.DespawnAll();
- for (uint8 i = 0; i < 6; i++)
- DoCast(SPELL_PLANAR_ANOMALIES);
+ Talk(SAY_SHIELD);
+ DoCast(SPELL_PLANAR_SHIFT);
+
+ // not sure about the amount, and if we should despawn previous spawns (dragon trashs)
+ summons.DespawnAll();
+ for (uint8 i = 0; i < 6; i++)
+ DoCast(SPELL_PLANAR_ANOMALIES);
+ }
}
- }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
- events.Update(diff);
+ events.Update(diff);
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
+ while (uint32 eventId = events.ExecuteEvent())
{
- case EVENT_ARCANE_BARRAGE:
- DoCastVictim(SPELL_ARCANE_BARRAGE);
- events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- break;
- case EVENT_ARCANE_VOLLEY:
- DoCastAOE(SPELL_ARCANE_VOLLEY);
- events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- break;
- case EVENT_ENRAGED_ASSAULT:
- Talk(SAY_ENRAGE);
- DoCast(SPELL_ENRAGED_ASSAULT);
- events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- break;
- case EVENT_SUMMON_LEY_WHELP:
- for (uint8 i = 0; i < 3; i++)
- DoCast(SPELL_SUMMON_LEY_WHELP);
- events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
- break;
+ switch (eventId)
+ {
+ case EVENT_ARCANE_BARRAGE:
+ DoCastVictim(SPELL_ARCANE_BARRAGE);
+ events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(3, 10) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ break;
+ case EVENT_ARCANE_VOLLEY:
+ DoCastAOE(SPELL_ARCANE_VOLLEY);
+ events.ScheduleEvent(EVENT_ARCANE_VOLLEY, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ break;
+ case EVENT_ENRAGED_ASSAULT:
+ Talk(SAY_ENRAGE);
+ DoCast(SPELL_ENRAGED_ASSAULT);
+ events.ScheduleEvent(EVENT_ENRAGED_ASSAULT, urand(35, 50) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ break;
+ case EVENT_SUMMON_LEY_WHELP:
+ for (uint8 i = 0; i < 3; i++)
+ DoCast(SPELL_SUMMON_LEY_WHELP);
+ events.ScheduleEvent(EVENT_SUMMON_LEY_WHELP, urand(15, 30) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ break;
+ default:
+ break;
+ }
}
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
- }
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ Talk(SAY_DEATH);
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- Talk(SAY_DEATH);
+ _JustDied();
+ }
- _JustDied();
- }
+ private:
+ uint8 _phase;
+ bool _rubyVoid;
+ bool _emeraldVoid;
+ bool _amberVoid;
+ };
- private:
- uint8 _phase;
- bool _rubyVoid;
- bool _emeraldVoid;
- bool _amberVoid;
- };
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new boss_eregosAI(creature);
+ }
};
class spell_eregos_planar_shift : public SpellScriptLoader
@@ -259,9 +261,8 @@ class spell_eregos_planar_shift : public SpellScriptLoader
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (Unit* caster = GetCaster())
- if (Creature* creatureCaster = caster->ToCreature())
- creatureCaster->AI()->DoAction(ACTION_SET_NORMAL_EVENTS);
+ if (Creature* creature = GetTarget()->ToCreature())
+ creature->AI()->DoAction(ACTION_SET_NORMAL_EVENTS);
}
void Register() OVERRIDE
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
index 678748b1f01..f7c558879d1 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
@@ -29,7 +29,6 @@ EndScriptData */
enum Spells
{
-
SPELL_ARCANE_SHIELD = 53813, //Dummy --> Channeled, shields the caster from damage.
SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377,
@@ -89,274 +88,242 @@ static uint32 TeleportSpells[]=
class boss_urom : public CreatureScript
{
-public:
- boss_urom() : CreatureScript("boss_urom") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_uromAI(creature);
- }
-
- struct boss_uromAI : public BossAI
- {
- boss_uromAI(Creature* creature) : BossAI(creature, DATA_UROM_EVENT) { }
+ public:
+ boss_urom() : CreatureScript("boss_urom") { }
- void Reset() OVERRIDE
+ struct boss_uromAI : public BossAI
{
- me->CastSpell(me, SPELL_EVOCATE);
-
- _Reset();
-
- if (instance->GetData(DATA_UROM_PLATAFORM) == 0)
+ boss_uromAI(Creature* creature) : BossAI(creature, DATA_UROM)
{
- for (uint8 i = 0; i < 3; i++)
- group[i] = 0;
- }
+ platform = 0;
- x = 0.0f;
- y = 0.0f;
- canCast = false;
- canGoBack = false;
+ for (uint8 i = 0; i < 3; ++i)
+ group[i] = i;
- me->GetMotionMaster()->MoveIdle();
-
- teleportTimer = urand(30000, 35000);
- arcaneExplosionTimer = 9000;
- castArcaneExplosionTimer = 2000;
- frostBombTimer = urand(5000, 8000);
- timeBombTimer = urand(20000, 25000);
- }
+ std::random_shuffle(group, group + 3);
+ }
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
+ void Reset() OVERRIDE
+ {
+ me->CastSpell(me, SPELL_EVOCATE);
- SetGroups();
- SummonGroups();
- CastTeleport();
+ _Reset();
- if (instance->GetData(DATA_UROM_PLATAFORM) != 3)
- instance->SetData(DATA_UROM_PLATAFORM, instance->GetData(DATA_UROM_PLATAFORM)+1);
- }
+ x = 0.0f;
+ y = 0.0f;
+ canCast = false;
+ canGoBack = false;
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!who)
- return;
+ me->GetMotionMaster()->MoveIdle();
- if (me->GetPositionZ() > 518.63f)
- DoStartNoMovement(who);
+ teleportTimer = urand(30000, 35000);
+ arcaneExplosionTimer = 9000;
+ castArcaneExplosionTimer = 2000;
+ frostBombTimer = urand(5000, 8000);
+ timeBombTimer = urand(20000, 25000);
+ }
- if (me->GetPositionZ() < 518.63f)
+ void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (me->Attack(who, true))
- {
- Talk(SAY_AGGRO);
-
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
+ _EnterCombat();
- me->GetMotionMaster()->MoveChase(who, 0, 0);
- }
+ StartAttack();
}
- }
-
- void SetGroups()
- {
- if (!instance || instance->GetData(DATA_UROM_PLATAFORM) != 0)
- return;
- while (group[0] == group[1] || group[0] == group[2] || group[1] == group[2])
+ void AttackStart(Unit* who) OVERRIDE
{
- for (uint8 i = 0; i < 3; i++)
- group[i] = urand(0, 2);
- }
- }
+ if (!who)
+ return;
- void SetPosition(uint8 i)
- {
- switch (i)
- {
- case 0:
- x = me->GetPositionX() + 4;
- y = me->GetPositionY() - 4;
- break;
- case 1:
- x = me->GetPositionX() + 4;
- y = me->GetPositionY() + 4;
- break;
- case 2:
- x = me->GetPositionX() - 4;
- y = me->GetPositionY() + 4;
- break;
- case 3:
- x = me->GetPositionX() - 4;
- y = me->GetPositionY() - 4;
- break;
- default:
- break;
+ if (me->GetPositionZ() > 518.63f)
+ DoStartNoMovement(who);
+ else
+ BossAI::AttackStart(who);
}
- }
- void SummonGroups()
- {
- if (!instance || instance->GetData(DATA_UROM_PLATAFORM) > 2)
- return;
-
- for (uint8 i = 0; i < 4; i++)
+ void SetPosition(uint8 i)
{
- SetPosition(i);
- me->SummonCreature(Group[group[instance->GetData(DATA_UROM_PLATAFORM)]].entry[i], x, y, me->GetPositionZ(), me->GetOrientation());
-
- // teleport to next platform and spawn adds
- switch (instance->GetData(DATA_UROM_PLATAFORM))
+ switch (i)
{
+ case 0:
+ x = me->GetPositionX() + 4;
+ y = me->GetPositionY() - 4;
+ break;
case 1:
- Talk(SAY_SUMMON_1);
+ x = me->GetPositionX() + 4;
+ y = me->GetPositionY() + 4;
break;
case 2:
- Talk(SAY_SUMMON_2);
+ x = me->GetPositionX() - 4;
+ y = me->GetPositionY() + 4;
break;
case 3:
- Talk(SAY_SUMMON_3);
+ x = me->GetPositionX() - 4;
+ y = me->GetPositionY() - 4;
break;
default:
break;
}
}
- }
- void CastTeleport()
- {
- if (!instance || instance->GetData(DATA_UROM_PLATAFORM) > 2)
- return;
-
- Talk(instance->GetData(DATA_UROM_PLATAFORM) < 5 ? instance->GetData(DATA_UROM_PLATAFORM) : 0);
- DoCast(TeleportSpells[instance->GetData(DATA_UROM_PLATAFORM)]);
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- Talk(SAY_PLAYER_KILL);
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
+ void StartAttack()
+ {
+ if (platform > 2)
+ {
+ Talk(SAY_AGGRO);
+ return;
+ }
- if (!instance || instance->GetData(DATA_UROM_PLATAFORM) < 2)
- return;
+ // summon guards and jump to next platform
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ SetPosition(i);
+ me->SummonCreature(Group[group[platform]].entry[i], x, y, me->GetPositionZ(), me->GetOrientation());
+ }
- if (teleportTimer <= uiDiff)
- {
- me->InterruptNonMeleeSpells(false);
- me->GetMotionMaster()->MoveIdle();
- DoCast(SPELL_TELEPORT);
- teleportTimer = urand(30000, 35000);
+ Talk(platform);
+ DoCast(TeleportSpells[platform]);
- } else teleportTimer -= uiDiff;
+ ++platform;
+ }
- if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION))
+ void KilledUnit(Unit* who) OVERRIDE
{
- if (castArcaneExplosionTimer <= uiDiff)
- {
- canCast = false;
- canGoBack = true;
- DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
- castArcaneExplosionTimer = 2000;
- }else castArcaneExplosionTimer -= uiDiff;
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
- if (canGoBack)
+ void UpdateAI(uint32 diff) OVERRIDE
{
- if (arcaneExplosionTimer <= uiDiff)
- {
- Position pPos;
- me->GetVictim()->GetPosition(&pPos);
+ if (!UpdateVictim())
+ return;
- me->NearTeleportTo(pPos.GetPositionX(), pPos.GetPositionY(), pPos.GetPositionZ(), pPos.GetOrientation());
- me->GetMotionMaster()->MoveChase(me->GetVictim(), 0, 0);
- me->SetWalk(true);
+ if (platform < 3)
+ return;
- Talk(EMOTE_ARCANE_EXPLOSION);
- Talk(SAY_ARCANE_EXPLOSION);
+ events.Update(diff);
- canCast = false;
- canGoBack = false;
- arcaneExplosionTimer = 9000;
- } else arcaneExplosionTimer -= uiDiff;
- }
+ if (teleportTimer <= diff)
+ {
+ me->InterruptNonMeleeSpells(false);
+ me->GetMotionMaster()->MoveIdle();
+ DoCast(SPELL_TELEPORT);
+ teleportTimer = urand(30000, 35000);
+ }
+ else
+ teleportTimer -= diff;
- if (!me->IsNonMeleeSpellCasted(false, true, true))
- {
- if (frostBombTimer <= uiDiff)
+ if (canCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION))
{
- DoCastVictim(SPELL_FROSTBOMB);
- frostBombTimer = urand(5000, 8000);
- } else frostBombTimer -= uiDiff;
+ if (castArcaneExplosionTimer <= diff)
+ {
+ canCast = false;
+ canGoBack = true;
+ DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
+ castArcaneExplosionTimer = 2000;
+ }
+ else
+ castArcaneExplosionTimer -= diff;
+ }
- if (timeBombTimer <= uiDiff)
+ if (canGoBack)
{
- if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(unit, SPELL_TIME_BOMB);
+ if (arcaneExplosionTimer <= diff)
+ {
+ Position pos;
+ me->GetVictim()->GetPosition(&pos);
+
+ me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
+ me->SetWalk(true);
+
+ Talk(EMOTE_ARCANE_EXPLOSION);
+ Talk(SAY_ARCANE_EXPLOSION);
+
+ canCast = false;
+ canGoBack = false;
+ arcaneExplosionTimer = 9000;
+ }
+ else
+ arcaneExplosionTimer -= diff;
+ }
- timeBombTimer = urand(20000, 25000);
- } else timeBombTimer -= uiDiff;
- }
+ if (!me->IsNonMeleeSpellCasted(false, true, true))
+ {
+ if (frostBombTimer <= diff)
+ {
+ DoCastVictim(SPELL_FROSTBOMB);
+ frostBombTimer = urand(5000, 8000);
+ }
+ else
+ frostBombTimer -= diff;
+
+ if (timeBombTimer <= diff)
+ {
+ if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(unit, SPELL_TIME_BOMB);
+
+ timeBombTimer = urand(20000, 25000);
+ }
+ else
+ timeBombTimer -= diff;
+ }
- DoMeleeAttackIfReady();
- }
+ DoMeleeAttackIfReady();
+ }
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- Talk(SAY_DEATH);
- DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
- }
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+ DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
+ }
- void LeaveCombat()
- {
- me->RemoveAllAuras();
- me->CombatStop(false);
- me->DeleteThreatList();
- }
+ void LeaveCombat()
+ {
+ me->RemoveAllAuras();
+ me->CombatStop(false);
+ me->DeleteThreatList();
+ }
- void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) OVERRIDE
- {
- switch (pSpell->Id)
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) OVERRIDE
{
- case SPELL_SUMMON_MENAGERIE:
- me->SetHomePosition(968.66f, 1042.53f, 527.32f, 0.077f);
- LeaveCombat();
- me->CastSpell(me, SPELL_EVOCATE);
- break;
- case SPELL_SUMMON_MENAGERIE_2:
- me->SetHomePosition(1164.02f, 1170.85f, 527.321f, 3.66f);
- LeaveCombat();
- me->CastSpell(me, SPELL_EVOCATE);
- break;
- case SPELL_SUMMON_MENAGERIE_3:
- me->SetHomePosition(1118.31f, 1080.377f, 508.361f, 4.25f);
- LeaveCombat();
- me->CastSpell(me, SPELL_EVOCATE);
- break;
- case SPELL_TELEPORT:
- //! Unconfirmed, previous below
- me->SetDisableGravity(true);
- //me->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); // with out it the npc will fall down while is casting
- canCast = true;
- break;
- default:
- break;
+ switch (spellInfo->Id)
+ {
+ case SPELL_SUMMON_MENAGERIE:
+ me->SetHomePosition(968.66f, 1042.53f, 527.32f, 0.077f);
+ LeaveCombat();
+ me->CastSpell(me, SPELL_EVOCATE);
+ break;
+ case SPELL_SUMMON_MENAGERIE_2:
+ me->SetHomePosition(1164.02f, 1170.85f, 527.321f, 3.66f);
+ LeaveCombat();
+ me->CastSpell(me, SPELL_EVOCATE);
+ break;
+ case SPELL_SUMMON_MENAGERIE_3:
+ me->SetHomePosition(1118.31f, 1080.377f, 508.361f, 4.25f);
+ LeaveCombat();
+ me->CastSpell(me, SPELL_EVOCATE);
+ break;
+ case SPELL_TELEPORT:
+ //! Unconfirmed, previous below
+ me->SetDisableGravity(true);
+ //me->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY); // with out it the npc will fall down while is casting
+ canCast = true;
+ break;
+ default:
+ break;
+ }
}
- }
+
private:
float x, y;
bool canCast;
bool canGoBack;
+ uint8 platform;
+
uint8 group[3];
uint32 teleportTimer;
@@ -364,7 +331,12 @@ public:
uint32 castArcaneExplosionTimer;
uint32 frostBombTimer;
uint32 timeBombTimer;
- };
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetOculusAI<boss_uromAI>(creature);
+ }
};
void AddSC_boss_urom()
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
index bc72c808a6f..385f80ae37d 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
@@ -54,105 +54,111 @@ enum Events
class boss_varos : public CreatureScript
{
-public:
- boss_varos() : CreatureScript("boss_varos") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_varosAI(creature);
- }
+ public:
+ boss_varos() : CreatureScript("boss_varos") { }
- struct boss_varosAI : public BossAI
- {
- boss_varosAI(Creature* creature) : BossAI(creature, DATA_VAROS_EVENT)
+ struct boss_varosAI : public BossAI
{
- if (instance->GetBossState(DATA_DRAKOS_EVENT) != DONE)
- DoCast(me, SPELL_CENTRIFUGE_SHIELD);
- }
+ boss_varosAI(Creature* creature) : BossAI(creature, DATA_VAROS) { }
- void Reset() OVERRIDE
- {
- _Reset();
+ void InitializeAI() OVERRIDE
+ {
+ BossAI::InitializeAI();
+ if (instance->GetBossState(DATA_DRAKOS) != DONE)
+ DoCast(me, SPELL_CENTRIFUGE_SHIELD);
+ }
- events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(20, 25) * IN_MILLISECONDS);
- events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
- // not sure if this is handled by a timer or hp percentage
- events.ScheduleEvent(EVENT_CALL_AZURE, urand(15, 30) * IN_MILLISECONDS);
+ void Reset() OVERRIDE
+ {
+ _Reset();
- firstCoreEnergize = false;
- coreEnergizeOrientation = 0.0f;
- }
+ events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(20, 25) * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
+ // not sure if this is handled by a timer or hp percentage
+ events.ScheduleEvent(EVENT_CALL_AZURE, urand(15, 30) * IN_MILLISECONDS);
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
+ firstCoreEnergize = false;
+ coreEnergizeOrientation = 0.0f;
+ }
- Talk(SAY_AGGRO);
- }
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
- float GetCoreEnergizeOrientation()
- {
- return coreEnergizeOrientation;
- }
+ Talk(SAY_AGGRO);
+ }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ float GetCoreEnergizeOrientation()
+ {
+ return coreEnergizeOrientation;
+ }
- events.Update(diff);
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ events.Update(diff);
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- case EVENT_ENERGIZE_CORES:
- DoCast(me, SPELL_ENERGIZE_CORES);
- events.CancelEvent(EVENT_ENERGIZE_CORES);
- break;
- case EVENT_ENERGIZE_CORES_VISUAL:
- if (!firstCoreEnergize)
- {
- coreEnergizeOrientation = me->GetOrientation();
- firstCoreEnergize = true;
- } else
- coreEnergizeOrientation = Position::NormalizeOrientation(coreEnergizeOrientation - 2.0f);
-
- DoCast(me, SPELL_ENERGIZE_CORES_VISUAL);
- events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
- events.ScheduleEvent(EVENT_ENERGIZE_CORES, 4000);
- break;
- case EVENT_CALL_AZURE:
- // not sure how blizz handles this, i cant see any pattern between the differnt spells
- DoCast(me, SPELL_CALL_AZURE_RING_CAPTAIN);
- Talk(SAY_AZURE);
- Talk(SAY_AZURE_EMOTE);
- events.ScheduleEvent(EVENT_CALL_AZURE, urand(20, 25) * IN_MILLISECONDS);
- break;
- case EVENT_AMPLIFY_MAGIC:
- DoCastVictim(SPELL_CALL_AMPLIFY_MAGIC);
- events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(17, 20) * IN_MILLISECONDS);
- break;
+ switch (eventId)
+ {
+ case EVENT_ENERGIZE_CORES:
+ DoCast(me, SPELL_ENERGIZE_CORES);
+ events.CancelEvent(EVENT_ENERGIZE_CORES);
+ break;
+ case EVENT_ENERGIZE_CORES_VISUAL:
+ if (!firstCoreEnergize)
+ {
+ coreEnergizeOrientation = me->GetOrientation();
+ firstCoreEnergize = true;
+ }
+ else
+ coreEnergizeOrientation = Position::NormalizeOrientation(coreEnergizeOrientation - 2.0f);
+
+ DoCast(me, SPELL_ENERGIZE_CORES_VISUAL);
+ events.ScheduleEvent(EVENT_ENERGIZE_CORES_VISUAL, 5000);
+ events.ScheduleEvent(EVENT_ENERGIZE_CORES, 4000);
+ break;
+ case EVENT_CALL_AZURE:
+ // not sure how blizz handles this, i cant see any pattern between the differnt spells
+ DoCast(me, SPELL_CALL_AZURE_RING_CAPTAIN);
+ Talk(SAY_AZURE);
+ Talk(SAY_AZURE_EMOTE);
+ events.ScheduleEvent(EVENT_CALL_AZURE, urand(20, 25) * IN_MILLISECONDS);
+ break;
+ case EVENT_AMPLIFY_MAGIC:
+ DoCastVictim(SPELL_CALL_AMPLIFY_MAGIC);
+ events.ScheduleEvent(EVENT_AMPLIFY_MAGIC, urand(17, 20) * IN_MILLISECONDS);
+ break;
+ default:
+ break;
+ }
}
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
- }
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+ DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
+ }
- void JustDied(Unit* /*killer*/) OVERRIDE
+ private:
+ bool firstCoreEnergize;
+ float coreEnergizeOrientation;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- _JustDied();
- Talk(SAY_DEATH);
- DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur
+ return GetOculusAI<boss_varosAI>(creature);
}
- private:
- bool firstCoreEnergize;
- float coreEnergizeOrientation;
- };
};
class npc_azure_ring_captain : public CreatureScript
@@ -259,7 +265,6 @@ class spell_varos_centrifuge_shield : public SpellScriptLoader
if (Unit* caster = GetCaster())
{
// flags taken from sniffs
- // UNIT_FLAG_UNK_9 -> means passive but it is not yet implemented in core
if (caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_15|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_UNK_6))
{
caster->ToCreature()->SetReactState(REACT_PASSIVE);
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
index 70424119a0a..b108378910e 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp
@@ -18,354 +18,336 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
+#include "WorldPacket.h"
#include "oculus.h"
-#include "Player.h"
-#define MAX_ENCOUNTER 4
+DoorData const doorData[] =
+{
+ { GO_DRAGON_CAGE_DOOR, DATA_DRAKOS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
+};
-/* The Occulus encounters:
-0 - Drakos the Interrogator
-1 - Varos Cloudstrider
-2 - Mage-Lord Urom
-3 - Ley-Guardian Eregos */
+Position const VerdisaMove = { 949.188f, 1032.91f, 359.967f, 1.093027f };
+Position const BelgaristraszMove = { 941.453f, 1044.1f, 359.967f, 0.1984709f };
+Position const EternosMove = { 943.202f, 1059.35f, 359.967f, 5.757278f };
class instance_oculus : public InstanceMapScript
{
-public:
- instance_oculus() : InstanceMapScript("instance_oculus", 578) { }
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
- {
- return new instance_oculus_InstanceMapScript(map);
- }
-
- struct instance_oculus_InstanceMapScript : public InstanceScript
- {
- instance_oculus_InstanceMapScript(Map* map) : InstanceScript(map) { }
+ public:
+ instance_oculus() : InstanceMapScript(OculusScriptName, 578) { }
- void Initialize() OVERRIDE
+ struct instance_oculus_InstanceMapScript : public InstanceScript
{
- SetBossNumber(MAX_ENCOUNTER);
-
- drakosGUID = 0;
- varosGUID = 0;
- uromGUID = 0;
- eregosGUID = 0;
-
- platformUrom = 0;
- centrifugueConstructCounter = 0;
-
- eregosCacheGUID = 0;
-
- gwhelpList.clear();
- gameObjectList.clear();
+ instance_oculus_InstanceMapScript(Map* map) : InstanceScript(map)
+ {
+ SetBossNumber(EncounterCount);
+ LoadDoorData(doorData);
- belgaristraszGUID = 0;
- eternosGUID = 0;
- verdisaGUID = 0;
-}
+ DrakosGUID = 0;
+ VarosGUID = 0;
+ UromGUID = 0;
+ EregosGUID = 0;
- void OnUnitDeath(Unit* unit) OVERRIDE
- {
- Creature* creature = unit->ToCreature();
- if (!creature)
- return;
+ CentrifugueConstructCounter = 0;
- if (creature->GetEntry() != NPC_CENTRIFUGE_CONSTRUCT)
- return;
+ EregosCacheGUID = 0;
- DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, --centrifugueConstructCounter);
+ GreaterWhelpList.clear();
- if (!centrifugueConstructCounter)
- if (Creature* varos = instance->GetCreature(varosGUID))
- varos->RemoveAllAuras();
- }
+ BelgaristraszGUID = 0;
+ EternosGUID = 0;
+ VerdisaGUID = 0;
+ }
- void OnPlayerEnter(Player* player) OVERRIDE
- {
- if (GetBossState(DATA_DRAKOS_EVENT) == DONE && GetBossState(DATA_VAROS_EVENT) != DONE)
+ void OnCreatureCreate(Creature* creature) OVERRIDE
{
- player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
- player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, centrifugueConstructCounter);
- } else
+ switch (creature->GetEntry())
+ {
+ case NPC_DRAKOS:
+ DrakosGUID = creature->GetGUID();
+ break;
+ case NPC_VAROS:
+ VarosGUID = creature->GetGUID();
+ if (GetBossState(DATA_DRAKOS) == DONE)
+ creature->SetPhaseMask(1, true);
+ break;
+ case NPC_UROM:
+ UromGUID = creature->GetGUID();
+ if (GetBossState(DATA_VAROS) == DONE)
+ creature->SetPhaseMask(1, true);
+ break;
+ case NPC_EREGOS:
+ EregosGUID = creature->GetGUID();
+ if (GetBossState(DATA_UROM) == DONE)
+ creature->SetPhaseMask(1, true);
+ break;
+ case NPC_CENTRIFUGE_CONSTRUCT:
+ if (creature->IsAlive())
+ DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, ++CentrifugueConstructCounter);
+ break;
+ case NPC_BELGARISTRASZ:
+ BelgaristraszGUID = creature->GetGUID();
+ if (GetBossState(DATA_DRAKOS) == DONE)
+ {
+ creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ creature->Relocate(BelgaristraszMove);
+ }
+ break;
+ case NPC_ETERNOS:
+ EternosGUID = creature->GetGUID();
+ if (GetBossState(DATA_DRAKOS) == DONE)
+ {
+ creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ creature->Relocate(EternosMove);
+ }
+ break;
+ case NPC_VERDISA:
+ VerdisaGUID = creature->GetGUID();
+ if (GetBossState(DATA_DRAKOS) == DONE)
+ {
+ creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ creature->Relocate(VerdisaMove);
+ }
+ break;
+ case NPC_GREATER_WHELP:
+ if (GetBossState(DATA_UROM) == DONE)
+ {
+ creature->SetPhaseMask(1, true);
+ GreaterWhelpList.push_back(creature->GetGUID());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* go) OVERRIDE
{
- player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
- player->SendUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, 0);
+ switch (go->GetEntry())
+ {
+ case GO_DRAGON_CAGE_DOOR:
+ AddDoor(go, true);
+ break;
+ case GO_EREGOS_CACHE_N:
+ case GO_EREGOS_CACHE_H:
+ EregosCacheGUID = go->GetGUID();
+ break;
+ default:
+ break;
+ }
}
- }
- void ProcessEvent(WorldObject* /*unit*/, uint32 eventId)
- {
- if (eventId != EVENT_CALL_DRAGON)
- return;
+ void OnGameObjectRemove(GameObject* go) OVERRIDE
+ {
+ switch (go->GetEntry())
+ {
+ case GO_DRAGON_CAGE_DOOR:
+ AddDoor(go, false);
+ break;
+ default:
+ break;
+ }
+ }
- Creature* varos = instance->GetCreature(varosGUID);
+ void OnUnitDeath(Unit* unit) OVERRIDE
+ {
+ Creature* creature = unit->ToCreature();
+ if (!creature)
+ return;
- if (!varos)
- return;
+ if (creature->GetEntry() == NPC_CENTRIFUGE_CONSTRUCT)
+ {
+ DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, --CentrifugueConstructCounter);
- if (Creature* drake = varos->SummonCreature(NPC_AZURE_RING_GUARDIAN, varos->GetPositionX(), varos->GetPositionY(), varos->GetPositionZ()+40))
- drake->AI()->DoAction(ACTION_CALL_DRAGON_EVENT);
- }
+ if (!CentrifugueConstructCounter)
+ if (Creature* varos = instance->GetCreature(VarosGUID))
+ varos->RemoveAllAuras();
+ }
+ }
- void OnCreatureCreate(Creature* creature) OVERRIDE
- {
- switch (creature->GetEntry())
+ void FillInitialWorldStates(WorldPacket& data) OVERRIDE
{
- case NPC_DRAKOS:
- drakosGUID = creature->GetGUID();
- break;
- case NPC_VAROS:
- varosGUID = creature->GetGUID();
- if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
- creature->SetPhaseMask(1, true);
- break;
- case NPC_UROM:
- uromGUID = creature->GetGUID();
- if (GetBossState(DATA_VAROS_EVENT) == DONE)
- creature->SetPhaseMask(1, true);
- break;
- case NPC_EREGOS:
- eregosGUID = creature->GetGUID();
- if (GetBossState(DATA_UROM_EVENT) == DONE)
- creature->SetPhaseMask(1, true);
- break;
- case NPC_CENTRIFUGE_CONSTRUCT:
- if (creature->IsAlive())
- DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, ++centrifugueConstructCounter);
- break;
- case NPC_BELGARISTRASZ:
- belgaristraszGUID = creature->GetGUID();
- if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
- {
- creature->SetWalk(true),
- creature->GetMotionMaster()->MovePoint(0, 941.453f, 1044.1f, 359.967f),
- creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
- break;
- case NPC_ETERNOS:
- eternosGUID = creature->GetGUID();
- if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
- {
- creature->SetWalk(true),
- creature->GetMotionMaster()->MovePoint(0, 943.202f, 1059.35f, 359.967f),
- creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
- break;
- case NPC_VERDISA:
- verdisaGUID = creature->GetGUID();
- if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
- {
- creature->SetWalk(true),
- creature->GetMotionMaster()->MovePoint(0, 949.188f, 1032.91f, 359.967f),
- creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
- break;
- case NPC_GREATER_WHELP:
- if (GetBossState(DATA_UROM_EVENT) == DONE)
- {
- creature->SetPhaseMask(1, true);
- gwhelpList.push_back(creature->GetGUID());
- }
- break;
+ if (GetBossState(DATA_DRAKOS) == DONE && GetBossState(DATA_VAROS) != DONE)
+ {
+ data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW) << uint32(1);
+ data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT) << uint32(CentrifugueConstructCounter);
+ }
+ else
+ {
+ data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW) << uint32(0);
+ data << uint32(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT) << uint32(0);
+ }
}
- }
- void OnGameObjectCreate(GameObject* go) OVERRIDE
- {
- switch (go->GetEntry())
+ void ProcessEvent(WorldObject* /*unit*/, uint32 eventId) OVERRIDE
{
- case GO_DRAGON_CAGE_DOOR:
- if (GetBossState(DATA_DRAKOS_EVENT) == DONE)
- go->SetGoState(GO_STATE_ACTIVE);
- else
- go->SetGoState(GO_STATE_READY);
- gameObjectList.push_back(go->GetGUID());
- break;
- case GO_EREGOS_CACHE_N:
- case GO_EREGOS_CACHE_H:
- eregosCacheGUID = go->GetGUID();
- break;
- default:
- break;
- }
- }
+ if (eventId != EVENT_CALL_DRAGON)
+ return;
- bool SetBossState(uint32 type, EncounterState state) OVERRIDE
- {
- if (!InstanceScript::SetBossState(type, state))
- return false;
+ if (Creature* varos = instance->GetCreature(VarosGUID))
+ if (Creature* drake = varos->SummonCreature(NPC_AZURE_RING_GUARDIAN, varos->GetPositionX(), varos->GetPositionY(), varos->GetPositionZ() + 40))
+ drake->AI()->DoAction(ACTION_CALL_DRAGON_EVENT);
+ }
- switch (type)
+ bool SetBossState(uint32 type, EncounterState state) OVERRIDE
{
- case DATA_DRAKOS_EVENT:
- if (state == DONE)
- {
- DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
- DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, centrifugueConstructCounter);
- OpenCageDoors();
- FreeDragons();
- if (Creature* varos = instance->GetCreature(varosGUID))
- varos->SetPhaseMask(1, true);
- }
- break;
- case DATA_VAROS_EVENT:
- if (state == DONE)
- DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
- if (Creature* urom = instance->GetCreature(uromGUID))
- urom->SetPhaseMask(1, true);
- break;
- case DATA_UROM_EVENT:
- if (state == DONE)
- {
- if (Creature* eregos = instance->GetCreature(eregosGUID))
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ switch (type)
+ {
+ case DATA_DRAKOS:
+ if (state == DONE)
{
- eregos->SetPhaseMask(1, true);
- GreaterWhelps();
+ DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 1);
+ DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_AMOUNT, CentrifugueConstructCounter);
+ FreeDragons();
+ if (Creature* varos = instance->GetCreature(VarosGUID))
+ varos->SetPhaseMask(1, true);
}
- }
- break;
- case DATA_EREGOS_EVENT:
- if (state == DONE)
- DoRespawnGameObject(eregosCacheGUID, 7*DAY);
- break;
- }
-
- return true;
- }
+ break;
+ case DATA_VAROS:
+ if (state == DONE)
+ DoUpdateWorldState(WORLD_STATE_CENTRIFUGE_CONSTRUCT_SHOW, 0);
+ if (Creature* urom = instance->GetCreature(UromGUID))
+ urom->SetPhaseMask(1, true);
+ break;
+ case DATA_UROM:
+ if (state == DONE)
+ {
+ if (Creature* eregos = instance->GetCreature(EregosGUID))
+ {
+ eregos->SetPhaseMask(1, true);
+ GreaterWhelps();
+ }
+ }
+ break;
+ case DATA_EREGOS:
+ if (state == DONE)
+ {
+ if (GameObject* cache = instance->GetGameObject(EregosCacheGUID))
+ {
+ cache->SetRespawnTime(cache->GetRespawnDelay());
+ cache->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ }
+ break;
+ }
- void SetData(uint32 type, uint32 data) OVERRIDE
- {
- switch (type)
- {
- case DATA_UROM_PLATAFORM:
- platformUrom = data;
- break;
+ return true;
}
- }
- uint32 GetData(uint32 type) const OVERRIDE
- {
- switch (type)
+ uint64 GetData64(uint32 type) const OVERRIDE
{
- case DATA_UROM_PLATAFORM: return platformUrom;
- // used by condition system
- case DATA_UROM_EVENT: return GetBossState(DATA_UROM_EVENT);
- }
+ switch (type)
+ {
+ case DATA_DRAKOS:
+ return DrakosGUID;
+ case DATA_VAROS:
+ return VarosGUID;
+ case DATA_UROM:
+ return UromGUID;
+ case DATA_EREGOS:
+ return EregosGUID;
+ default:
+ break;
+ }
- return 0;
- }
+ return 0;
+ }
- uint64 GetData64(uint32 identifier) const OVERRIDE
- {
- switch (identifier)
+ void FreeDragons()
{
- case DATA_DRAKOS: return drakosGUID;
- case DATA_VAROS: return varosGUID;
- case DATA_UROM: return uromGUID;
- case DATA_EREGOS: return eregosGUID;
- }
+ if (Creature* belgaristrasz = instance->GetCreature(BelgaristraszGUID))
+ {
+ belgaristrasz->SetWalk(true);
+ belgaristrasz->GetMotionMaster()->MovePoint(POINT_MOVE_OUT, BelgaristraszMove);
+ }
- return 0;
- }
+ if (Creature* eternos = instance->GetCreature(EternosGUID))
+ {
+ eternos->SetWalk(true);
+ eternos->GetMotionMaster()->MovePoint(POINT_MOVE_OUT, EternosMove);
+ }
- void OpenCageDoors()
- {
- if (gameObjectList.empty())
- return;
+ if (Creature* verdisa = instance->GetCreature(VerdisaGUID))
+ {
+ verdisa->SetWalk(true);
+ verdisa->GetMotionMaster()->MovePoint(POINT_MOVE_OUT, VerdisaMove);
+ }
+ }
- for (std::list<uint64>::const_iterator itr = gameObjectList.begin(); itr != gameObjectList.end(); ++itr)
+ void GreaterWhelps()
{
- if (GameObject* go = instance->GetGameObject(*itr))
- go->SetGoState(GO_STATE_ACTIVE);
+ for (std::list<uint64>::const_iterator itr = GreaterWhelpList.begin(); itr != GreaterWhelpList.end(); ++itr)
+ if (Creature* gwhelp = instance->GetCreature(*itr))
+ gwhelp->SetPhaseMask(1, true);
}
- }
-
- void FreeDragons()
- {
- if (Creature* belgaristrasz = instance->GetCreature(belgaristraszGUID))
- belgaristrasz->SetWalk(true),
- belgaristrasz->GetMotionMaster()->MovePoint(0, 941.453f, 1044.1f, 359.967f);
- if (Creature* eternos = instance->GetCreature(eternosGUID))
- eternos->SetWalk(true),
- eternos->GetMotionMaster()->MovePoint(0, 943.202f, 1059.35f, 359.967f);
- if (Creature* verdisa = instance->GetCreature(verdisaGUID))
- verdisa->SetWalk(true),
- verdisa->GetMotionMaster()->MovePoint(0, 949.188f, 1032.91f, 359.967f);
- }
- void GreaterWhelps()
- {
- if (gwhelpList.empty())
- return;
-
- for (std::list<uint64>::const_iterator itr = gwhelpList.begin(); itr != gwhelpList.end(); ++itr)
- if (Creature* gwhelp = instance->GetCreature(*itr))
- gwhelp->SetPhaseMask(1, true);
- }
-
- std::string GetSaveData() OVERRIDE
- {
- OUT_SAVE_INST_DATA;
-
- std::ostringstream saveStream;
- saveStream << "T O " << GetBossSaveData();
+ std::string GetSaveData() OVERRIDE
+ {
+ OUT_SAVE_INST_DATA;
- str_data = saveStream.str();
+ std::ostringstream saveStream;
+ saveStream << "T O " << GetBossSaveData();
- OUT_SAVE_INST_DATA_COMPLETE;
- return str_data;
- }
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
- void Load(const char* in) OVERRIDE
- {
- if (!in)
+ void Load(char const* str) OVERRIDE
{
- OUT_LOAD_INST_DATA_FAIL;
- return;
- }
+ if (!str)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
- OUT_LOAD_INST_DATA(in);
+ OUT_LOAD_INST_DATA(str);
- char dataHead1, dataHead2;
+ char dataHead1, dataHead2;
- std::istringstream loadStream(in);
- loadStream >> dataHead1 >> dataHead2;
+ std::istringstream loadStream(str);
+ loadStream >> dataHead1 >> dataHead2;
- if (dataHead1 == 'T' && dataHead2 == 'O')
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (dataHead1 == 'T' && dataHead2 == 'O')
{
- uint32 tmpState;
- loadStream >> tmpState;
- if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
- tmpState = NOT_STARTED;
- SetBossState(i, EncounterState(tmpState));
+ for (uint32 i = 0; i < EncounterCount; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+ SetBossState(i, EncounterState(tmpState));
+ }
}
- } else OUT_LOAD_INST_DATA_FAIL;
+ else
+ OUT_LOAD_INST_DATA_FAIL;
- OUT_LOAD_INST_DATA_COMPLETE;
- }
- private:
- uint64 drakosGUID;
- uint64 varosGUID;
- uint64 uromGUID;
- uint64 eregosGUID;
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
- uint64 belgaristraszGUID;
- uint64 eternosGUID;
- uint64 verdisaGUID;
+ protected:
+ uint64 DrakosGUID;
+ uint64 VarosGUID;
+ uint64 UromGUID;
+ uint64 EregosGUID;
- uint8 platformUrom;
- uint8 centrifugueConstructCounter;
+ uint64 BelgaristraszGUID;
+ uint64 EternosGUID;
+ uint64 VerdisaGUID;
- uint64 eregosCacheGUID;
+ uint8 CentrifugueConstructCounter;
- std::string str_data;
+ uint64 EregosCacheGUID;
- std::list<uint64> gameObjectList;
- std::list<uint64> gwhelpList;
- };
+ std::list<uint64> GreaterWhelpList;
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
+ {
+ return new instance_oculus_InstanceMapScript(map);
+ }
};
void AddSC_instance_oculus()
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index fd15cd19b37..1230868c020 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -20,77 +20,73 @@
#include "ScriptedGossip.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
-#include "Vehicle.h"
#include "CombatAI.h"
-#include "oculus.h"
#include "Player.h"
-
-#define GOSSIP_ITEM_DRAKES "So where do we go from here?"
-#define GOSSIP_ITEM_BELGARISTRASZ1 "I want to fly on the wings of the Red Flight"
-#define GOSSIP_ITEM_BELGARISTRASZ2 "What abilities do Ruby Drakes have?"
-#define GOSSIP_ITEM_VERDISA1 "I want to fly on the wings of the Green Flight"
-#define GOSSIP_ITEM_VERDISA2 "What abilities do Emerald Drakes have?"
-#define GOSSIP_ITEM_ETERNOS1 "I want to fly on the wings of the Bronze Flight"
-#define GOSSIP_ITEM_ETERNOS2 "What abilities do Amber Drakes have?"
-
-#define HAS_ESSENCE(a) ((a)->HasItemCount(ITEM_EMERALD_ESSENCE) || (a)->HasItemCount(ITEM_AMBER_ESSENCE) || (a)->HasItemCount(ITEM_RUBY_ESSENCE))
+#include "Vehicle.h"
+#include "oculus.h"
enum GossipNPCs
{
- GOSSIP_TEXTID_DRAKES = 13267,
- GOSSIP_TEXTID_BELGARISTRASZ1 = 12916,
- GOSSIP_TEXTID_BELGARISTRASZ2 = 13466,
- GOSSIP_TEXTID_BELGARISTRASZ3 = 13254,
- GOSSIP_TEXTID_VERDISA1 = 1,
- GOSSIP_TEXTID_VERDISA2 = 1,
- GOSSIP_TEXTID_VERDISA3 = 1,
- GOSSIP_TEXTID_ETERNOS1 = 1,
- GOSSIP_TEXTID_ETERNOS2 = 1,
- GOSSIP_TEXTID_ETERNOS3 = 13256,
-
- ITEM_EMERALD_ESSENCE = 37815,
- ITEM_AMBER_ESSENCE = 37859,
- ITEM_RUBY_ESSENCE = 37860,
-
- SPELL_SHOCK_CHARGE = 49836
+ GOSSIP_MENU_VERDISA = 9573,
+ GOSSIP_MENU_ETERNOS = 9574,
+ GOSSIP_MENU_BELGARISTRASZ = 9575,
+
+ ITEM_EMERALD_ESSENCE = 37815,
+ ITEM_AMBER_ESSENCE = 37859,
+ ITEM_RUBY_ESSENCE = 37860
};
enum Drakes
{
-/*Ruby Drake,
-(npc 27756) (item 37860)
-(summoned by spell Ruby Essence = 37860 ---> Call Amber Drake == 49462 ---> Summon 27756)
-*/
- SPELL_RIDE_RUBY_DRAKE_QUE = 49463, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49464
- SPELL_RUBY_DRAKE_SADDLE = 49464, //Allows you to ride on the back of an Amber Drake. ---> Dummy
- SPELL_RUBY_SEARING_WRATH = 50232, //(60 yds) - Instant - Breathes a stream of fire at an enemy dragon, dealing 6800 to 9200 Fire damage and then jumping to additional dragons within 30 yards. Each jump increases the damage by 50%. Affects up to 5 total targets
- SPELL_RUBY_EVASIVE_AURA = 50248, //Instant - Allows the Ruby Drake to generate Evasive Charges when hit by hostile attacks and spells.
- SPELL_RUBY_EVASIVE_MANEUVERS = 50240, //Instant - 5 sec. cooldown - Allows your drake to dodge all incoming attacks and spells. Requires Evasive Charges to use. Each attack or spell dodged while this ability is active burns one Evasive Charge. Lasts 30 sec. or until all charges are exhausted.
- //you do not have acces to until you kill Mage-Lord Urom
- SPELL_RUBY_MARTYR = 50253, //Instant - 10 sec. cooldown - Redirect all harmful spells cast at friendly drakes to yourself for 10 sec.
-
-/*Amber Drake,
-(npc 27755) (item 37859)
-(summoned by spell Amber Essence = 37859 ---> Call Amber Drake == 49461 ---> Summon 27755)
-*/
-
- SPELL_RIDE_AMBER_DRAKE_QUE = 49459, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49460
- SPELL_AMBER_DRAKE_SADDLE = 49460, //Allows you to ride on the back of an Amber Drake. ---> Dummy
- SPELL_AMBER_SHOCK_LANCE = 49840, //(60 yds) - Instant - Deals 4822 to 5602 Arcane damage and detonates all Shock Charges on an enemy dragon. Damage is increased by 6525 for each detonated.
- // SPELL_AMBER_STOP_TIME //Instant - 1 min cooldown - Halts the passage of time, freezing all enemy dragons in place for 10 sec. This attack applies 5 Shock Charges to each affected target.
- //you do not have access to until you kill the Mage-Lord Urom.
- SPELL_AMBER_TEMPORAL_RIFT = 49592, //(60 yds) - Channeled - Channels a temporal rift on an enemy dragon for 10 sec. While trapped in the rift, all damage done to the target is increased by 100%. In addition, for every 15, 000 damage done to a target affected by Temporal Rift, 1 Shock Charge is generated.
-
-/*Emerald Drake,
-(npc 27692) (item 37815),
- (summoned by spell Emerald Essence = 37815 ---> Call Emerald Drake == 49345 ---> Summon 27692)
-*/
- SPELL_RIDE_EMERALD_DRAKE_QUE = 49427, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49346
- SPELL_EMERALD_DRAKE_SADDLE = 49346, //Allows you to ride on the back of an Amber Drake. ---> Dummy
- SPELL_EMERALD_LEECHING_POISON = 50328, //(60 yds) - Instant - Poisons the enemy dragon, leeching 1300 to the caster every 2 sec. for 12 sec. Stacks up to 3 times.
- SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, //(60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25, 000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
+/*
+ * Ruby Drake (27756)
+ * (summoned by spell Ruby Essence (37860) --> Call Amber Drake (49462) --> Summon 27756)
+ */
+ SPELL_RIDE_RUBY_DRAKE_QUE = 49463, // Apply Aura: Periodic Trigger, Interval: 3 seconds --> 49464
+ SPELL_RUBY_DRAKE_SADDLE = 49464, // Allows you to ride on the back of an Amber Drake. --> Dummy
+ SPELL_RUBY_SEARING_WRATH = 50232, // (60 yds) - Instant - Breathes a stream of fire at an enemy dragon, dealing 6800 to 9200 Fire damage and then jumping to additional dragons within 30 yards. Each jump increases the damage by 50%. Affects up to 5 total targets
+ SPELL_RUBY_EVASIVE_AURA = 50248, // Instant - Allows the Ruby Drake to generate Evasive Charges when hit by hostile attacks and spells.
+ SPELL_RUBY_EVASIVE_CHARGES = 50241,
+ SPELL_RUBY_EVASIVE_MANEUVERS = 50240, // Instant - 5 sec. cooldown - Allows your drake to dodge all incoming attacks and spells. Requires Evasive Charges to use. Each attack or spell dodged while this ability is active burns one Evasive Charge. Lasts 30 sec. or until all charges are exhausted.
+ // you do not have acces to until you kill Mage-Lord Urom
+ SPELL_RUBY_MARTYR = 50253, // Instant - 10 sec. cooldown - Redirect all harmful spells cast at friendly drakes to yourself for 10 sec.
+
+/*
+ * Amber Drake (27755)
+ * (summoned by spell Amber Essence (37859) --> Call Amber Drake (49461) --> Summon 27755)
+ */
+ SPELL_RIDE_AMBER_DRAKE_QUE = 49459, // Apply Aura: Periodic Trigger, Interval: 3 seconds --> 49460
+ SPELL_AMBER_DRAKE_SADDLE = 49460, // Allows you to ride on the back of an Amber Drake. --> Dummy
+ SPELL_AMBER_SHOCK_CHARGE = 49836,
+ SPELL_AMBER_SHOCK_LANCE = 49840, // (60 yds) - Instant - Deals 4822 to 5602 Arcane damage and detonates all Shock Charges on an enemy dragon. Damage is increased by 6525 for each detonated.
+ SPELL_AMBER_STOP_TIME = 49838, // Instant - 1 min cooldown - Halts the passage of time, freezing all enemy dragons in place for 10 sec. This attack applies 5 Shock Charges to each affected target.
+ // you do not have access to until you kill the Mage-Lord Urom.
+ SPELL_AMBER_TEMPORAL_RIFT = 49592, // (60 yds) - Channeled - Channels a temporal rift on an enemy dragon for 10 sec. While trapped in the rift, all damage done to the target is increased by 100%. In addition, for every 15, 000 damage done to a target affected by Temporal Rift, 1 Shock Charge is generated.
+
+/*
+ * Emerald Drake (27692)
+ * (summoned by spell Emerald Essence (37815) --> Call Emerald Drake (49345) --> Summon 27692)
+ */
+ SPELL_RIDE_EMERALD_DRAKE_QUE = 49427, // Apply Aura: Periodic Trigger, Interval: 3 seconds --> 49346
+ SPELL_EMERALD_DRAKE_SADDLE = 49346, // Allows you to ride on the back of an Amber Drake. --> Dummy
+ SPELL_EMERALD_LEECHING_POISON = 50328, // (60 yds) - Instant - Poisons the enemy dragon, leeching 1300 to the caster every 2 sec. for 12 sec. Stacks up to 3 times.
+ SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, // (60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25, 000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
// you do not have access to until you kill the Mage-Lord Urom
- SPELL_EMERALD_DREAM_FUNNEL = 50344, //(60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
+ SPELL_EMERALD_DREAM_FUNNEL = 50344, // (60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
+
+ // Misc
+ POINT_LAND = 2,
+ POINT_TAKE_OFF = 3
+};
+
+enum DrakeEvents
+{
+ EVENT_WELCOME = 1,
+ EVENT_ABILITIES,
+ EVENT_SPECIAL_ATTACK,
+ EVENT_LOW_HEALTH,
+ EVENT_RESET_LOW_HEALTH,
+ EVENT_TAKE_OFF
};
enum Says
@@ -107,420 +103,500 @@ enum Says
class npc_verdisa_beglaristrasz_eternos : public CreatureScript
{
-public:
- npc_verdisa_beglaristrasz_eternos() : CreatureScript("npc_verdisa_beglaristrasz_eternos") { }
+ public:
+ npc_verdisa_beglaristrasz_eternos() : CreatureScript("npc_verdisa_beglaristrasz_eternos") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (creature->GetEntry())
+ struct npc_verdisa_beglaristrasz_eternosAI : public ScriptedAI
{
- case NPC_VERDISA: //Verdisa
+ npc_verdisa_beglaristrasz_eternosAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void StoreEssence(Player* player, uint32 itemId)
{
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF + 1:
- if (!HAS_ESSENCE(player))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA1, creature->GetGUID());
- }
- else
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA2, creature->GetGUID());
- }
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_EMERALD_ESSENCE, 1);
- if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, ITEM_EMERALD_ESSENCE, true);
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA3, creature->GetGUID());
- break;
- }
- break;
+ /// @todo: should be handled by spell, but not found in dbc (49450 and other?)
+ uint32 count = 1;
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count);
+ if (msg == EQUIP_ERR_OK)
+ if (Item* item = player->StoreNewItem(dest, itemId, true))
+ player->SendNewItem(item, count, true, true);
}
- case NPC_BELGARISTRASZ: //Belgaristrasz
+
+ void RemoveEssence(Player* player, uint32 itemId)
{
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF + 1:
- if (!HAS_ESSENCE(player))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ1, creature->GetGUID());
- }
- else
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ2, creature->GetGUID());
- }
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_RUBY_ESSENCE, 1);
- if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, ITEM_RUBY_ESSENCE, true);
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ3, creature->GetGUID());
- break;
- }
- break;
+ player->DestroyItemCount(itemId, 1, true, false);
}
- case NPC_ETERNOS: //Eternos
+
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) OVERRIDE
{
- switch (action)
+ switch (menuId)
{
- case GOSSIP_ACTION_INFO_DEF + 1:
- if (!HAS_ESSENCE(player))
+ case GOSSIP_MENU_VERDISA:
+ if (gossipListId >= 1 && gossipListId <= 3)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS1, creature->GetGUID());
+ if (gossipListId == 2)
+ RemoveEssence(player, ITEM_AMBER_ESSENCE);
+ else if (gossipListId == 3)
+ RemoveEssence(player, ITEM_RUBY_ESSENCE);
+
+ StoreEssence(player, ITEM_EMERALD_ESSENCE);
+ break;
}
- else
+ return;
+ case GOSSIP_MENU_ETERNOS:
+ if (gossipListId >= 1 && gossipListId <= 3)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS2, creature->GetGUID());
+ if (gossipListId == 2)
+ RemoveEssence(player, ITEM_EMERALD_ESSENCE);
+ else if (gossipListId == 3)
+ RemoveEssence(player, ITEM_RUBY_ESSENCE);
+
+ StoreEssence(player, ITEM_AMBER_ESSENCE);
+ break;
}
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_AMBER_ESSENCE, 1);
- if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, ITEM_AMBER_ESSENCE, true);
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS3, creature->GetGUID());
- break;
+ return;
+ case GOSSIP_MENU_BELGARISTRASZ:
+ if (gossipListId <= 2)
+ {
+ if (gossipListId == 1)
+ RemoveEssence(player, ITEM_AMBER_ESSENCE);
+ else if (gossipListId == 2)
+ RemoveEssence(player, ITEM_EMERALD_ESSENCE);
+
+ StoreEssence(player, ITEM_RUBY_ESSENCE);
+ break;
+ }
+ return;
+ default:
+ return;
}
- break;
+ player->PlayerTalkClass->SendCloseGossip();
}
- }
-
- return true;
- }
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (InstanceScript* instance = creature->GetInstanceScript())
- {
- if (instance->GetBossState(DATA_DRAKOS_EVENT) == DONE)
+ void MovementInform(uint32 /*type*/, uint32 id) OVERRIDE
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DRAKES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DRAKES, creature->GetGUID());
- }
- }
+ if (id != POINT_MOVE_OUT)
+ return;
- return true;
- }
+ // When Belgaristraz finish his moving say grateful text
+ if (me->GetEntry() == NPC_BELGARISTRASZ)
+ Talk(SAY_BELGARISTRASZ);
- struct npc_verdisa_beglaristrasz_eternosAI : public ScriptedAI
- {
- npc_verdisa_beglaristrasz_eternosAI(Creature* creature) : ScriptedAI(creature) { }
+ // The gossip flag should activate when Drakos die and not from DB
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+ };
- void MovementInform(uint32 /*type*/, uint32 id) OVERRIDE
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- if (id)
- return;
-
- // When Belgaristraz finish his moving say grateful text
- if (me->GetEntry() == NPC_BELGARISTRASZ)
- Talk(SAY_BELGARISTRASZ);
-
- // The gossip flag should activate when Drakos die and not from DB
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ return GetOculusAI<npc_verdisa_beglaristrasz_eternosAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_verdisa_beglaristrasz_eternosAI(creature);
- }
};
class npc_image_belgaristrasz : public CreatureScript
{
-public:
- npc_image_belgaristrasz() : CreatureScript("npc_image_belgaristrasz") { }
-
- struct npc_image_belgaristraszAI : public ScriptedAI
- {
- npc_image_belgaristraszAI(Creature* creature) : ScriptedAI(creature) { }
+ public:
+ npc_image_belgaristrasz() : CreatureScript("npc_image_belgaristrasz") { }
- void IsSummonedBy(Unit* summoner) OVERRIDE
+ struct npc_image_belgaristraszAI : public ScriptedAI
{
- if (summoner->GetEntry() == NPC_VAROS)
- {
- Talk(SAY_VAROS);
- me->DespawnOrUnsummon(60000);
- }
- if (summoner->GetEntry() == NPC_UROM)
+ npc_image_belgaristraszAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void IsSummonedBy(Unit* summoner) OVERRIDE
{
- Talk(SAY_UROM);
- me->DespawnOrUnsummon(60000);
+ if (summoner->GetEntry() == NPC_VAROS)
+ {
+ Talk(SAY_VAROS);
+ me->DespawnOrUnsummon(60000);
+ }
+
+ if (summoner->GetEntry() == NPC_UROM)
+ {
+ Talk(SAY_UROM);
+ me->DespawnOrUnsummon(60000);
+ }
}
- }
- };
+ };
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_image_belgaristraszAI(creature);
- }
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetOculusAI<npc_image_belgaristraszAI>(creature);
+ }
};
class npc_ruby_emerald_amber_drake : public CreatureScript
{
-public:
- npc_ruby_emerald_amber_drake() : CreatureScript("npc_ruby_emerald_amber_drake") { }
+ public:
+ npc_ruby_emerald_amber_drake() : CreatureScript("npc_ruby_emerald_amber_drake") { }
- struct npc_ruby_emerald_amber_drakeAI : public VehicleAI
- {
- npc_ruby_emerald_amber_drakeAI(Creature* creature) : VehicleAI(creature)
+ struct npc_ruby_emerald_amber_drakeAI : public VehicleAI
{
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
+ npc_ruby_emerald_amber_drakeAI(Creature* creature) : VehicleAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- uint64 summonerGUID;
- uint32 WelcomeTimer;
- uint32 WelcomeSequelTimer;
- uint32 SpecialTimer;
- uint32 WarningTimer;
- uint32 TakeOffTimer;
+ void Reset() OVERRIDE
+ {
+ _events.Reset();
+ _healthWarning = true;
+ }
- bool WelcomeOff;
- bool WelcomeSequelOff;
- bool SpecialOff;
- bool HealthWarningOff;
- bool DisableTakeOff;
+ void IsSummonedBy(Unit* summoner) OVERRIDE
+ {
+ if (_instance->GetBossState(DATA_EREGOS) == IN_PROGRESS)
+ if (Creature* eregos = me->FindNearestCreature(NPC_EREGOS, 450.0f, true))
+ eregos->DespawnOrUnsummon(); // On retail this kills abusive call of drake during engaged Eregos
- void Reset() OVERRIDE
- {
- summonerGUID = 0;
- WelcomeTimer = 4500;
- WelcomeSequelTimer = 4500;
- SpecialTimer = 10000;
- WarningTimer = 25000;
- TakeOffTimer = 3500;
-
- WelcomeOff = false;
- WelcomeSequelOff = false;
- SpecialOff = false;
- HealthWarningOff = false;
- DisableTakeOff = false;
- }
+ me->SetFacingToObject(summoner);
- void IsSummonedBy(Unit* summoner) OVERRIDE
- {
- if (instance->GetBossState(DATA_EREGOS_EVENT) == IN_PROGRESS)
- if (Creature* eregos = me->FindNearestCreature(NPC_EREGOS, 450.0f, true))
+ switch (me->GetEntry())
{
- eregos->DespawnOrUnsummon(); // On retail this kills abusive call of drake during engaged Eregos
+ case NPC_RUBY_DRAKE_VEHICLE:
+ me->CastSpell(summoner, SPELL_RIDE_RUBY_DRAKE_QUE);
+ break;
+ case NPC_EMERALD_DRAKE_VEHICLE:
+ me->CastSpell(summoner, SPELL_RIDE_EMERALD_DRAKE_QUE);
+ break;
+ case NPC_AMBER_DRAKE_VEHICLE:
+ me->CastSpell(summoner, SPELL_RIDE_AMBER_DRAKE_QUE);
+ break;
+ default:
+ return;
}
- summonerGUID = summoner->GetGUID();
- me->SetFacingToObject(summoner);
- // TO DO: Drake Ques should be casted from vehicle to player, however the way core handle triggered spells from auras break it no matter the conditions. So this change the caster and give the same result until someone fix triggered spells from auras that involve implicit targets or make exception for this case.
- if (me->GetEntry() == NPC_RUBY_DRAKE_VEHICLE)
- summoner->CastSpell(summoner, SPELL_RIDE_RUBY_DRAKE_QUE);
- if (me->GetEntry() == NPC_EMERALD_DRAKE_VEHICLE)
- summoner->CastSpell(summoner, SPELL_RIDE_EMERALD_DRAKE_QUE);
- if (me->GetEntry() == NPC_AMBER_DRAKE_VEHICLE)
- summoner->CastSpell(summoner, SPELL_RIDE_AMBER_DRAKE_QUE);
- Position pos;
- summoner->GetPosition(&pos);
- me->GetMotionMaster()->MovePoint(0, pos);
- }
- void MovementInform(uint32 type, uint32 id) OVERRIDE
- {
- if (type == POINT_MOTION_TYPE && id == 0)
- me->SetDisableGravity(false); // Needed this for proper animation after spawn, the summon in air fall to ground bug leave no other option for now, if this isn't used the drake will only walk on move.
- }
+ Position pos;
+ summoner->GetPosition(&pos);
+ me->GetMotionMaster()->MovePoint(POINT_LAND, pos);
+ }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!(instance->GetBossState(DATA_VAROS_EVENT) == DONE))
+ void MovementInform(uint32 type, uint32 id) OVERRIDE
{
- if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
- {
- if (!(WelcomeOff))
- {
- if (WelcomeTimer <= diff)
- {
- Talk(WHISPER_DRAKES_WELCOME, me->GetCreatorGUID());
- WelcomeOff = true;
- WelcomeSequelOff = true;
- }
- else WelcomeTimer -= diff;
- }
- }
+ if (type == POINT_MOTION_TYPE && id == POINT_LAND)
+ me->SetDisableGravity(false); // Needed this for proper animation after spawn, the summon in air fall to ground bug leave no other option for now, if this isn't used the drake will only walk on move.
}
- if (me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
+
+ void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) OVERRIDE
{
- if (WelcomeSequelOff)
+ if (passenger->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (apply)
{
- if (WelcomeSequelTimer <= diff)
- {
- Talk(WHISPER_DRAKES_ABILITIES, me->GetCreatorGUID());
- WelcomeSequelOff = false;
- }
- else WelcomeSequelTimer -= diff;
- }
+ if (_instance->GetBossState(DATA_VAROS) != DONE)
+ _events.ScheduleEvent(EVENT_WELCOME, 10 * IN_MILLISECONDS);
- if (instance->GetBossState(DATA_UROM_EVENT) == DONE)
+ else if (_instance->GetBossState(DATA_UROM) == DONE)
+ _events.ScheduleEvent(EVENT_SPECIAL_ATTACK, 10 * IN_MILLISECONDS);
+ }
+ else
{
- if (!(SpecialOff))
- {
- if (SpecialTimer <= diff)
- {
- Talk(WHISPER_DRAKES_SPECIAL, me->GetCreatorGUID());
- SpecialOff = true;
- }
- else SpecialTimer -= diff;
- }
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_TAKE_OFF, 2 * IN_MILLISECONDS);
}
+ }
- if (!(HealthWarningOff))
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (_healthWarning)
{
if (me->GetHealthPct() <= 40.0f)
- {
- Talk(WHISPER_DRAKES_LOWHEALTH, me->GetCreatorGUID());
- HealthWarningOff = true;
- }
+ _events.ScheduleEvent(EVENT_LOW_HEALTH, 0);
}
- if (HealthWarningOff)
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (WarningTimer <= diff)
+ switch (eventId)
{
- HealthWarningOff = false;
- WarningTimer = 25000;
+ case EVENT_WELCOME:
+ Talk(WHISPER_DRAKES_WELCOME, me->GetCreatorGUID());
+ _events.ScheduleEvent(EVENT_ABILITIES, 5 * IN_MILLISECONDS);
+ break;
+ case EVENT_ABILITIES:
+ Talk(WHISPER_DRAKES_ABILITIES, me->GetCreatorGUID());
+ break;
+ case EVENT_SPECIAL_ATTACK:
+ Talk(WHISPER_DRAKES_SPECIAL, me->GetCreatorGUID());
+ break;
+ case EVENT_LOW_HEALTH:
+ Talk(WHISPER_DRAKES_LOWHEALTH, me->GetCreatorGUID());
+ _healthWarning = false;
+ _events.ScheduleEvent(EVENT_RESET_LOW_HEALTH, 25000);
+ break;
+ case EVENT_RESET_LOW_HEALTH:
+ _healthWarning = true;
+ break;
+ case EVENT_TAKE_OFF:
+ {
+ me->DespawnOrUnsummon(2050);
+ me->SetOrientation(2.5f);
+ me->SetSpeed(MOVE_FLIGHT, 1.0f, true);
+ Talk(SAY_DRAKES_TAKEOFF);
+ Position pos;
+ me->GetPosition(&pos);
+ Position offset = { 10.0f, 10.0f, 12.0f, 0.0f };
+ pos.RelocateOffset(offset);
+ me->SetDisableGravity(true);
+ me->GetMotionMaster()->MovePoint(POINT_TAKE_OFF, pos);
+ break;
+ }
+ default:
+ break;
}
- else WarningTimer -= diff;
}
+ };
+
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ bool _healthWarning;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetOculusAI<npc_ruby_emerald_amber_drakeAI>(creature);
+ }
+};
+
+// 49345 - Call Emerald Drake
+// 49461 - Call Amber Drake
+// 49462 - Call Ruby Drake
+class spell_oculus_call_ruby_emerald_amber_drake : public SpellScriptLoader
+{
+ public:
+ spell_oculus_call_ruby_emerald_amber_drake() : SpellScriptLoader("spell_oculus_call_ruby_emerald_amber_drake") { }
+
+ class spell_oculus_call_ruby_emerald_amber_drake_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_oculus_call_ruby_emerald_amber_drake_SpellScript);
+
+ void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ {
+ // Adjust effect summon position
+ WorldLocation summonPos = *GetExplTargetDest();
+ Position offset = { 0.0f, 0.0f, 12.0f, 0.0f };
+ summonPos.RelocateOffset(offset);
+ SetExplTargetDest(summonPos);
+ GetHitDest()->RelocateOffset(offset);
}
- if (!(me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE)))
+ void ModDestHeight(SpellEffIndex /*effIndex*/)
{
- if (!(DisableTakeOff))
- {
- if (TakeOffTimer <= diff)
- {
- me->DespawnOrUnsummon(2050);
- me->SetOrientation(2.5f);
- me->SetSpeed(MOVE_FLIGHT, 1.0f, true);
- Talk(SAY_DRAKES_TAKEOFF);
- Position pos;
- me->GetPosition(&pos);
- pos.m_positionX += 10.0f;
- pos.m_positionY += 10.0f;
- pos.m_positionZ += 12.0f;
- me->GetMotionMaster()->MovePoint(1, pos);
- DisableTakeOff = true;
- }
- else TakeOffTimer -= diff;
- }
+ // Used to cast visual effect at proper position
+ Position offset = { 0.0f, 0.0f, 12.0f, 0.0f };
+ const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHit += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnEffectLaunch += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
}
};
- };
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ruby_emerald_amber_drakeAI(creature);
- }
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_oculus_call_ruby_emerald_amber_drake_SpellScript();
+ }
};
-class spell_gen_stop_time : public SpellScriptLoader
+// 49427 - Ride Emerald Drake Que
+// 49459 - Ride Amber Drake Que
+// 49463 - Ride Ruby Drake Que
+class spell_oculus_ride_ruby_emerald_amber_drake_que : public SpellScriptLoader
{
-public:
- spell_gen_stop_time() : SpellScriptLoader("spell_gen_stop_time") { }
+ public:
+ spell_oculus_ride_ruby_emerald_amber_drake_que() : SpellScriptLoader("spell_oculus_ride_ruby_emerald_amber_drake_que") { }
- class spell_gen_stop_time_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_gen_stop_time_AuraScript);
+ class spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript);
+
+ void HandlePeriodic(AuraEffect const* aurEff)
+ {
+ // caster of the triggered spell is wrong for an unknown reason, handle it here correctly
+ PreventDefaultAction();
+ if (Unit* caster = GetCaster())
+ GetTarget()->CastSpell(caster, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
+ }
- void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void Register() OVERRIDE
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
{
- Unit* caster = GetCaster();
- if (!caster)
- return;
- Unit* target = GetTarget();
- for (uint32 i = 0; i < 5; ++i)
- caster->CastSpell(target, SPELL_SHOCK_CHARGE, false);
+ return new spell_oculus_ride_ruby_emerald_amber_drake_que_AuraScript();
}
+};
+
+// 50240 - Evasive Maneuvers
+class spell_oculus_evasive_maneuvers : public SpellScriptLoader
+{
+ public:
+ spell_oculus_evasive_maneuvers() : SpellScriptLoader("spell_oculus_evasive_maneuvers") { }
- void Register() OVERRIDE
+ class spell_oculus_evasive_maneuvers_AuraScript : public AuraScript
{
- AfterEffectApply += AuraEffectApplyFn(spell_gen_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
- }
- };
+ PrepareAuraScript(spell_oculus_evasive_maneuvers_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RUBY_EVASIVE_CHARGES))
+ return false;
+ return true;
+ }
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_gen_stop_time_AuraScript();
- }
+ void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->RemoveAuraFromStack(SPELL_RUBY_EVASIVE_CHARGES);
+ if (!GetTarget()->HasAura(SPELL_RUBY_EVASIVE_CHARGES))
+ Remove();
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_oculus_evasive_maneuvers_AuraScript::HandleProc, EFFECT_2, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_oculus_evasive_maneuvers_AuraScript();
+ }
};
-class spell_call_ruby_emerald_amber_drake : public SpellScriptLoader
+// 49840 - Shock Lance
+class spell_oculus_shock_lance : public SpellScriptLoader
{
-public:
- spell_call_ruby_emerald_amber_drake() : SpellScriptLoader("spell_call_ruby_emerald_amber_drake") { }
+ public:
+ spell_oculus_shock_lance() : SpellScriptLoader("spell_oculus_shock_lance") { }
+
+ class spell_oculus_shock_lance_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_oculus_shock_lance_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_AMBER_SHOCK_CHARGE))
+ return false;
+ return true;
+ }
- class spell_call_ruby_emerald_amber_drake_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_call_ruby_emerald_amber_drake_SpellScript);
+ void CalcDamage()
+ {
+ int32 damage = GetHitDamage();
+ if (Unit* target = GetHitUnit())
+ if (AuraEffect const* shockCharges = target->GetAuraEffect(SPELL_AMBER_SHOCK_CHARGE, EFFECT_0, GetCaster()->GetGUID()))
+ {
+ damage += shockCharges->GetAmount();
+ shockCharges->GetBase()->Remove();
+ }
+
+ SetHitDamage(damage);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnHit += SpellHitFn(spell_oculus_shock_lance_SpellScript::CalcDamage);
+ }
+ };
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ SpellScript* GetSpellScript() const OVERRIDE
{
- // Adjust effect summon position
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = {0.0f, 0.0f, 12.0f, 0.0f};
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ return new spell_oculus_shock_lance_SpellScript();
}
+};
+
+// 49838 - Stop Time
+class spell_oculus_stop_time : public SpellScriptLoader
+{
+ public:
+ spell_oculus_stop_time() : SpellScriptLoader("spell_oculus_stop_time") { }
- void ModDestHeight(SpellEffIndex /*effIndex*/)
+ class spell_oculus_stop_time_AuraScript : public AuraScript
{
- // Used to cast visual effect at proper position
- Position offset = {0.0f, 0.0f, 12.0f, 0.0f};
- const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
- }
+ PrepareAuraScript(spell_oculus_stop_time_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_AMBER_SHOCK_CHARGE))
+ return false;
+ return true;
+ }
+
+ void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ Unit* target = GetTarget();
+ for (uint32 i = 0; i < 5; ++i)
+ caster->CastSpell(target, SPELL_AMBER_SHOCK_CHARGE, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_oculus_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
- void Register() OVERRIDE
+ AuraScript* GetAuraScript() const OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_call_ruby_emerald_amber_drake_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
- OnEffectLaunch += SpellEffectFn(spell_call_ruby_emerald_amber_drake_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
+ return new spell_oculus_stop_time_AuraScript();
}
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_call_ruby_emerald_amber_drake_SpellScript();
- }
};
+// 49592 - Temporal Rift
+class spell_oculus_temporal_rift : public SpellScriptLoader
+{
+ public:
+ spell_oculus_temporal_rift() : SpellScriptLoader("spell_oculus_temporal_rift") { }
+
+ class spell_oculus_temporal_rift_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_oculus_temporal_rift_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_AMBER_SHOCK_CHARGE))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 amount = aurEff->GetAmount() + eventInfo.GetDamageInfo()->GetDamage();
+
+ if (amount >= 15000)
+ {
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(GetTarget(), SPELL_AMBER_SHOCK_CHARGE, true);
+ amount -= 15000;
+ }
+
+ const_cast<AuraEffect*>(aurEff)->SetAmount(amount);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_oculus_temporal_rift_AuraScript::HandleProc, EFFECT_2, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_oculus_temporal_rift_AuraScript();
+ }
+};
+// 50341 - Touch the Nightmare
class spell_oculus_touch_the_nightmare : public SpellScriptLoader
{
public:
@@ -547,7 +623,8 @@ class spell_oculus_touch_the_nightmare : public SpellScriptLoader
}
};
-class spell_oculus_dream_funnel: public SpellScriptLoader
+// 50344 - Dream Funnel
+class spell_oculus_dream_funnel : public SpellScriptLoader
{
public:
spell_oculus_dream_funnel() : SpellScriptLoader("spell_oculus_dream_funnel") { }
@@ -582,8 +659,12 @@ void AddSC_oculus()
new npc_verdisa_beglaristrasz_eternos();
new npc_image_belgaristrasz();
new npc_ruby_emerald_amber_drake();
- new spell_gen_stop_time();
- new spell_call_ruby_emerald_amber_drake();
+ new spell_oculus_call_ruby_emerald_amber_drake();
+ new spell_oculus_ride_ruby_emerald_amber_drake_que();
+ new spell_oculus_evasive_maneuvers();
+ new spell_oculus_shock_lance();
+ new spell_oculus_stop_time();
+ new spell_oculus_temporal_rift();
new spell_oculus_touch_the_nightmare();
new spell_oculus_dream_funnel();
}
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
index 2dd5df3bc3b..6f34cfbf6e5 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h
@@ -15,59 +15,55 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DEF_OCULUS_H
-#define DEF_OCULUS_H
+#ifndef OCULUS_H_
+#define OCULUS_H_
-enum Data
-{
- DATA_DRAKOS_EVENT,
- DATA_VAROS_EVENT,
- DATA_UROM_EVENT,
- DATA_EREGOS_EVENT,
- DATA_UROM_PLATAFORM
-};
+#define OculusScriptName "instance_oculus"
+
+uint32 const EncounterCount = 4;
-enum Data64
+enum DataTypes
{
- DATA_DRAKOS,
- DATA_VAROS,
- DATA_UROM,
- DATA_EREGOS
+ // Encounter States/Boss GUIDs
+ DATA_DRAKOS = 0,
+ DATA_VAROS = 1,
+ DATA_UROM = 2,
+ DATA_EREGOS = 3
};
-enum Bosses_NPCs
+enum CreatureIds
{
NPC_DRAKOS = 27654,
NPC_VAROS = 27447,
NPC_UROM = 27655,
NPC_EREGOS = 27656,
- NPC_AZURE_RING_GUARDIAN = 28236,
- NPC_CENTRIFUGE_CONSTRUCT = 27641,
- NPC_RUBY_DRAKE_VEHICLE = 27756,
- NPC_EMERALD_DRAKE_VEHICLE = 27692,
- NPC_AMBER_DRAKE_VEHICLE = 27755,
- NPC_VERDISA = 27657,
- NPC_BELGARISTRASZ = 27658,
- NPC_ETERNOS = 27659,
- NPC_GREATER_WHELP = 28276
+ NPC_AZURE_RING_GUARDIAN = 28236,
+ NPC_CENTRIFUGE_CONSTRUCT = 27641,
+ NPC_RUBY_DRAKE_VEHICLE = 27756,
+ NPC_EMERALD_DRAKE_VEHICLE = 27692,
+ NPC_AMBER_DRAKE_VEHICLE = 27755,
+ NPC_VERDISA = 27657,
+ NPC_BELGARISTRASZ = 27658,
+ NPC_ETERNOS = 27659,
+ NPC_GREATER_WHELP = 28276
};
-enum GameObjects
+enum GameObjectIds
{
- GO_DRAGON_CAGE_DOOR = 193995,
- GO_EREGOS_CACHE_N = 191349,
- GO_EREGOS_CACHE_H = 193603
+ GO_DRAGON_CAGE_DOOR = 193995,
+ GO_EREGOS_CACHE_N = 191349,
+ GO_EREGOS_CACHE_H = 193603
};
enum SpellEvents
{
- EVENT_CALL_DRAGON = 12229
+ EVENT_CALL_DRAGON = 12229
};
enum CreatureActions
{
- ACTION_CALL_DRAGON_EVENT = 1
+ ACTION_CALL_DRAGON_EVENT = 1
};
enum OculusWorldStates
@@ -78,7 +74,19 @@ enum OculusWorldStates
enum OculusSpells
{
- SPELL_CENTRIFUGE_SHIELD = 50053,
- SPELL_DEATH_SPELL = 50415
+ SPELL_CENTRIFUGE_SHIELD = 50053,
+ SPELL_DEATH_SPELL = 50415
};
-#endif
+
+enum Misc
+{
+ POINT_MOVE_OUT = 1
+};
+
+template<class AI>
+AI* GetOculusAI(Creature* creature)
+{
+ return GetInstanceAI<AI>(creature, OculusScriptName);
+}
+
+#endif // OCULUS_H_
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
index b70bda76d76..77c19422da0 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
@@ -58,19 +58,14 @@ enum Creatures
NPC_STASIS_CONTROLLER = 26688
};
-struct Locations
+Position const moveLocs[] =
{
- float x, y, z;
-};
-
-struct Locations moveLocs[]=
-{
- {261.6f, -449.3f, 109.5f},
- {263.3f, -454.0f, 109.5f},
- {291.5f, -450.4f, 109.5f},
- {291.5f, -454.0f, 109.5f},
- {310.0f, -453.4f, 109.5f},
- {238.6f, -460.7f, 109.5f}
+ { 261.6f, -449.3f, 109.5f, 0.0f },
+ { 263.3f, -454.0f, 109.5f, 0.0f },
+ { 291.5f, -450.4f, 109.5f, 0.0f },
+ { 291.5f, -454.0f, 109.5f, 0.0f },
+ { 310.0f, -453.4f, 109.5f, 0.0f },
+ { 238.6f, -460.7f, 109.5f, 0.0f }
};
enum Phase
@@ -83,21 +78,20 @@ enum Phase
PHASE_NONE
};
+enum Misc
+{
+ ACTION_NEXT_PHASE,
+};
+
class boss_palehoof : public CreatureScript
{
public:
boss_palehoof() : CreatureScript("boss_palehoof") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ struct boss_palehoofAI : public BossAI
{
- return new boss_palehoofAI(creature);
- }
-
- struct boss_palehoofAI : public ScriptedAI
- {
- boss_palehoofAI(Creature* creature) : ScriptedAI(creature)
+ boss_palehoofAI(Creature* creature) : BossAI(creature, DATA_GORTOK_PALEHOOF)
{
- instance = creature->GetInstanceScript();
}
uint32 uiArcingSmashTimer;
@@ -108,10 +102,10 @@ public:
uint8 AddCount;
Phase Sequence[4];
- InstanceScript* instance;
-
void Reset() OVERRIDE
{
+ _Reset();
+
/// There is a good reason to store them like this, we are going to shuffle the order.
for (uint32 i = PHASE_FRENZIED_WORGEN; i < PHASE_GORTOK_PALEHOOF; ++i)
Sequence[i] = Phase(i);
@@ -129,32 +123,15 @@ public:
currentPhase = PHASE_NONE;
- if (instance)
- {
- instance->SetData(DATA_GORTOK_PALEHOOF_EVENT, NOT_STARTED);
-
- Creature* temp = Unit::GetCreature((*me), instance->GetData64(DATA_NPC_FRENZIED_WORGEN));
- if (temp && !temp->IsAlive())
- temp->Respawn();
+ for (uint8 i = DATA_FRENZIED_WORGEN; i <= DATA_FEROCIOUS_RHINO; ++i)
+ if (Creature* temp = ObjectAccessor::GetCreature(*me, instance->GetData64(i)))
+ if (!temp->IsAlive())
+ temp->Respawn();
- temp = Unit::GetCreature((*me), instance->GetData64(DATA_NPC_FEROCIOUS_RHINO));
- if (temp && !temp->IsAlive())
- temp->Respawn();
-
- temp = Unit::GetCreature((*me), instance->GetData64(DATA_NPC_MASSIVE_JORMUNGAR));
- if (temp && !temp->IsAlive())
- temp->Respawn();
-
- temp = Unit::GetCreature((*me), instance->GetData64(DATA_NPC_RAVENOUS_FURBOLG));
- if (temp && !temp->IsAlive())
- temp->Respawn();
-
- GameObject* go = instance->instance->GetGameObject(instance->GetData64(DATA_GORTOK_PALEHOOF_SPHERE));
- if (go)
- {
- go->SetGoState(GO_STATE_READY);
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
+ if (GameObject* go = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_GORTOK_PALEHOOF_SPHERE)))
+ {
+ go->SetGoState(GO_STATE_READY);
+ go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
}
}
@@ -185,14 +162,9 @@ public:
if (currentPhase != PHASE_GORTOK_PALEHOOF)
return;
- //Return since we have no target
if (!UpdateVictim())
return;
- Creature* temp = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_ORB) : 0);
- if (temp && temp->IsAlive())
- temp->DisappearAndDie();
-
if (uiArcingSmashTimer <= diff)
{
DoCast(me, SPELL_ARCING_SMASH);
@@ -217,12 +189,8 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- //Talk(SAY_DEATH);
- if (instance)
- instance->SetData(DATA_GORTOK_PALEHOOF_EVENT, DONE);
- Creature* temp = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_ORB) : 0);
- if (temp && temp->IsAlive())
- temp->DisappearAndDie();
+ _JustDied();
+ //Talk(SAY_DEATH);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
@@ -230,28 +198,30 @@ public:
Talk(SAY_SLAY);
}
- void NextPhase()
+ void DoAction(int32 actionId) OVERRIDE
{
+ if (actionId != ACTION_NEXT_PHASE)
+ return;
+
if (currentPhase == PHASE_NONE)
{
- if (instance)
- instance->SetData(DATA_GORTOK_PALEHOOF_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_GORTOK_PALEHOOF, IN_PROGRESS);
- me->SummonCreature(NPC_STASIS_CONTROLLER, moveLocs[5].x, moveLocs[5].y, moveLocs[5].z, 0, TEMPSUMMON_CORPSE_DESPAWN);
+ if (Creature* orb = me->SummonCreature(NPC_STASIS_CONTROLLER, moveLocs[5], TEMPSUMMON_CORPSE_DESPAWN))
+ orb->CastSpell(me, SPELL_ORB_VISUAL, true);
}
+
Phase move = PHASE_NONE;
if (AddCount >= DUNGEON_MODE(2, 4))
move = PHASE_GORTOK_PALEHOOF;
else
move = Sequence[AddCount++];
- //send orb to summon spot
- Creature* pOrb = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_ORB) : 0);
- if (pOrb && pOrb->IsAlive())
- {
- if (currentPhase == PHASE_NONE)
- pOrb->CastSpell(me, SPELL_ORB_VISUAL, true);
- pOrb->GetMotionMaster()->MovePoint(move, moveLocs[move].x, moveLocs[move].y, moveLocs[move].z);
- }
+
+ // send orb to summon spot
+ if (Creature* orb = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_ORB)))
+ if (orb->IsAlive())
+ orb->GetMotionMaster()->MovePoint(move, moveLocs[move]);
+
currentPhase = move;
}
@@ -263,6 +233,10 @@ public:
}
};
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetUtgardePinnacleAI<boss_palehoofAI>(creature);
+ }
};
//ravenous furbolg's spells
@@ -305,13 +279,12 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
- if (instance)
- if (instance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof && pPalehoof->IsAlive())
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->Reset();
- }
+ if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS)
+ {
+ Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF));
+ if (palehoof && palehoof->IsAlive())
+ palehoof->AI()->Reset();
+ }
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -360,12 +333,8 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof)
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->NextPhase();
- }
+ if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF)))
+ palehoof->AI()->DoAction(ACTION_NEXT_PHASE);
}
void JustReachedHome() OVERRIDE
@@ -418,13 +387,12 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
- if (instance)
- if (instance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof && pPalehoof->IsAlive())
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->Reset();
- }
+ if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS)
+ {
+ Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF));
+ if (palehoof && palehoof->IsAlive())
+ palehoof->AI()->Reset();
+ }
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -470,17 +438,13 @@ public:
DoStartMovement(who);
}
if (instance)
- instance->SetData(DATA_GORTOK_PALEHOOF_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_GORTOK_PALEHOOF, IN_PROGRESS);
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance->GetData64(DATA_GORTOK_PALEHOOF));
- if (pPalehoof)
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->NextPhase();
- }
+ if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF)))
+ palehoof->AI()->DoAction(ACTION_NEXT_PHASE);
}
void JustReachedHome() OVERRIDE
@@ -534,13 +498,12 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
- if (instance)
- if (instance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof && pPalehoof->IsAlive())
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->Reset();
- }
+ if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS)
+ {
+ Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF));
+ if (palehoof && palehoof->IsAlive())
+ palehoof->AI()->Reset();
+ }
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -590,12 +553,8 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof)
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->NextPhase();
- }
+ if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF)))
+ palehoof->AI()->DoAction(ACTION_NEXT_PHASE);
}
void JustReachedHome() OVERRIDE
@@ -654,13 +613,12 @@ public:
me->GetMotionMaster()->MoveTargetedHome();
- if (instance)
- if (instance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof && pPalehoof->IsAlive())
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->Reset();
- }
+ if (instance->GetBossState(DATA_GORTOK_PALEHOOF) == IN_PROGRESS)
+ {
+ Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF));
+ if (palehoof && palehoof->IsAlive())
+ palehoof->AI()->Reset();
+ }
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -711,12 +669,8 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance)
- {
- Creature* pPalehoof = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof)
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->NextPhase();
- }
+ if (Creature* palehoof = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GORTOK_PALEHOOF)))
+ palehoof->AI()->DoAction(ACTION_NEXT_PHASE);
}
void JustReachedHome() OVERRIDE
@@ -767,52 +721,76 @@ public:
if (SummonTimer <= diff)
{
- if (currentPhase<5&&currentPhase >= 0)
+ uint8 nextBossId = 0;
+ switch (currentPhase)
{
- Creature* pNext = NULL;
- switch (currentPhase)
- {
- case PHASE_FRENZIED_WORGEN: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_FRENZIED_WORGEN) : 0); break;
- case PHASE_RAVENOUS_FURLBORG: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_RAVENOUS_FURBOLG) : 0); break;
- case PHASE_MASSIVE_JORMUNGAR: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_MASSIVE_JORMUNGAR) : 0); break;
- case PHASE_FEROCIOUS_RHINO: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_FEROCIOUS_RHINO) : 0); break;
- case PHASE_GORTOK_PALEHOOF: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0); break;
- default: break;
- }
-
- if (pNext)
- {
- pNext->RemoveAurasDueToSpell(SPELL_FREEZE);
- pNext->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC);
- pNext->SetStandState(UNIT_STAND_STATE_STAND);
- pNext->SetInCombatWithZone();
- pNext->Attack(pNext->SelectNearestTarget(100), true);
-
- }
- currentPhase = PHASE_NONE;
+ case PHASE_FRENZIED_WORGEN:
+ nextBossId = DATA_FRENZIED_WORGEN;
+ break;
+ case PHASE_RAVENOUS_FURLBORG:
+ nextBossId = DATA_RAVENOUS_FURBOLG;
+ break;
+ case PHASE_MASSIVE_JORMUNGAR:
+ nextBossId = DATA_MASSIVE_JORMUNGAR;
+ break;
+ case PHASE_FEROCIOUS_RHINO:
+ nextBossId = DATA_FEROCIOUS_RHINO;
+ break;
+ case PHASE_GORTOK_PALEHOOF:
+ nextBossId = DATA_GORTOK_PALEHOOF;
+ break;
+ default:
+ return;
}
- } else SummonTimer -= diff;
+
+ if (Creature* nextBoss = ObjectAccessor::GetCreature(*me, instance->GetData64(nextBossId)))
+ {
+ nextBoss->RemoveAurasDueToSpell(SPELL_FREEZE);
+ nextBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC);
+ nextBoss->SetStandState(UNIT_STAND_STATE_STAND);
+ nextBoss->SetInCombatWithZone();
+ nextBoss->Attack(nextBoss->SelectNearestTarget(100), true);
+ }
+ currentPhase = PHASE_NONE;
+
+ if (nextBossId == DATA_GORTOK_PALEHOOF)
+ me->DespawnOrUnsummon();
+ }
+ else
+ SummonTimer -= diff;
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
{
if (type != POINT_MOTION_TYPE)
return;
- if (id > 4)
- return;
- Creature* pNext = NULL;
+
+ uint8 nextBossId = 0;
switch (id)
{
- case PHASE_FRENZIED_WORGEN: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_FRENZIED_WORGEN) : 0); break;
- case PHASE_RAVENOUS_FURLBORG: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_RAVENOUS_FURBOLG) : 0); break;
- case PHASE_MASSIVE_JORMUNGAR: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_MASSIVE_JORMUNGAR) : 0); break;
- case PHASE_FEROCIOUS_RHINO: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_NPC_FEROCIOUS_RHINO) : 0); break;
- case PHASE_GORTOK_PALEHOOF: pNext = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0); break;
- default: break;
+ case PHASE_FRENZIED_WORGEN:
+ nextBossId = DATA_FRENZIED_WORGEN;
+ break;
+ case PHASE_RAVENOUS_FURLBORG:
+ nextBossId = DATA_RAVENOUS_FURBOLG;
+ break;
+ case PHASE_MASSIVE_JORMUNGAR:
+ nextBossId = DATA_MASSIVE_JORMUNGAR;
+ break;
+ case PHASE_FEROCIOUS_RHINO:
+ nextBossId = DATA_FEROCIOUS_RHINO;
+ break;
+ case PHASE_GORTOK_PALEHOOF:
+ nextBossId = DATA_GORTOK_PALEHOOF;
+ break;
+ default:
+ return;
}
- if (pNext)
- DoCast(pNext, SPELL_ORB_CHANNEL, false);
- currentPhase = (Phase)id;
+
+ if (Creature* nextBoss = ObjectAccessor::GetCreature(*me, instance->GetData64(nextBossId)))
+ DoCast(nextBoss, SPELL_ORB_CHANNEL, false);
+
+ currentPhase = Phase(id);
SummonTimer = 5000;
}
};
@@ -821,23 +799,25 @@ public:
class go_palehoof_sphere : public GameObjectScript
{
-public:
- go_palehoof_sphere() : GameObjectScript("go_palehoof_sphere") { }
-
- bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE
- {
- InstanceScript* instance = go->GetInstanceScript();
+ public:
+ go_palehoof_sphere() : GameObjectScript("go_palehoof_sphere") { }
- Creature* pPalehoof = Unit::GetCreature(*go, instance ? instance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
- if (pPalehoof && pPalehoof->IsAlive())
+ bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE
{
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- go->SetGoState(GO_STATE_ACTIVE);
+ InstanceScript* instance = go->GetInstanceScript();
+ if (!instance)
+ return false;
+
+ Creature* palehoof = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_GORTOK_PALEHOOF));
+ if (palehoof && palehoof->IsAlive())
+ {
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ go->SetGoState(GO_STATE_ACTIVE);
- CAST_AI(boss_palehoof::boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ palehoof->AI()->DoAction(ACTION_NEXT_PHASE);
+ }
+ return true;
}
- return true;
- }
};
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
index 08670af939a..01fcd9a665d 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
@@ -210,7 +210,7 @@ public:
me->SummonCreature(NPC_GRAUF, Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 3.0f);
if (instance)
{
- instance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_SKADI_THE_RUTHLESS, NOT_STARTED);
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
}
}
@@ -237,7 +237,7 @@ public:
me->SetInCombatWithZone();
if (instance)
{
- instance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_SKADI_THE_RUTHLESS, IN_PROGRESS);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
me->GetMotionMaster()->MoveJump(Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 5.0f, 10.0f);
me->SetWalk(false);
@@ -412,7 +412,7 @@ public:
Talk(SAY_DEATH);
Summons.DespawnAll();
if (instance)
- instance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, DONE);
+ instance->SetBossState(DATA_SKADI_THE_RUTHLESS, DONE);
}
void KilledUnit(Unit* /*victim*/) OVERRIDE
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
index 818631788b6..f7e8d9ea7d6 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
@@ -74,7 +74,6 @@ enum Yells
enum Creatures
{
NPC_ARTHAS = 29280, // Image of Arthas
- NPC_SVALA_SORROWGRAVE = 26668, // Svala after transformation
NPC_RITUAL_CHANNELER = 27281,
NPC_SPECTATOR = 26667,
NPC_RITUAL_TARGET = 27327,
@@ -82,258 +81,238 @@ enum Creatures
NPC_SCOURGE_HULK = 26555
};
-enum GameObjects
+enum Phases
{
- GO_UTGARDE_MIRROR = 191745
-};
-
-enum SvalaPhase
-{
- IDLE,
+ IDLE = 1,
INTRO,
NORMAL,
SACRIFICING,
SVALADEAD
};
+enum Events
+{
+ //INTRO
+ EVENT_INTRO_SVALA_TALK_0 = 1,
+ EVENT_INTRO_ARTHAS_TALK_0,
+ EVENT_INTRO_TRANSFORM_0,
+ EVENT_INTRO_TRANSFORM_1,
+ EVENT_INTRO_TRANSFORM_2,
+ EVENT_INTRO_SVALA_TALK_1,
+ EVENT_INTRO_ARTHAS_TALK_1,
+ EVENT_INTRO_SVALA_TALK_2,
+ EVENT_INTRO_RELOCATE_SVALA,
+ EVENT_INTRO_DESPAWN_ARTHAS,
+
+ //NORMAL
+ EVENT_SINISTER_STRIKE,
+ EVENT_CALL_FLAMES,
+ EVENT_RITUAL_PREPARATION,
+
+ //SACRIFICING
+ EVENT_SPAWN_RITUAL_CHANNELERS,
+ EVENT_RITUAL_STRIKE,
+ EVENT_RITUAL_DISARM
+};
+
enum Misc
{
DATA_INCREDIBLE_HULK = 2043
};
-static const float spectatorWP[2][3] =
+Position const spectatorWP[2] =
{
- {296.95f, -312.76f, 86.36f},
- {297.69f, -275.81f, 86.36f}
+ {296.95f, -312.76f, 86.36f, 0.0f },
+ {297.69f, -275.81f, 86.36f, 0.0f }
};
-static Position ArthasPos = { 295.81f, -366.16f, 92.57f, 1.58f };
+Position const ArthasPos = { 295.81f, -366.16f, 92.57f, 1.58f };
class boss_svala : public CreatureScript
{
-public:
- boss_svala() : CreatureScript("boss_svala") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_svalaAI(creature);
- }
-
- struct boss_svalaAI : public ScriptedAI
- {
- boss_svalaAI(Creature* creature) : ScriptedAI(creature), summons(creature)
- {
- instance = creature->GetInstanceScript();
- Phase = IDLE;
-
- me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_RITUAL_STRIKE_EFF_1, true);
- me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_RITUAL_STRIKE_EFF_2, true);
- }
-
- InstanceScript* instance;
- SummonList summons;
- SvalaPhase Phase;
-
- Position pos;
- float x, y, z;
-
- uint32 introTimer;
- uint8 introPhase;
- uint8 sacrePhase;
-
- TempSummon* arthas;
- uint64 arthasGUID;
-
- uint32 sinsterStrikeTimer;
- uint32 callFlamesTimer;
- uint32 sacrificeTimer;
-
- bool sacrificed;
+ public:
+ boss_svala() : CreatureScript("boss_svala") { }
- void Reset() OVERRIDE
+ struct boss_svalaAI : public BossAI
{
- sacrificed = false;
- SetCombatMovement(true);
+ boss_svalaAI(Creature* creature) : BossAI(creature, DATA_SVALA_SORROWGRAVE)
+ {
+ _introCompleted = false;
+ }
- summons.DespawnAll();
- me->RemoveAllAuras();
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ _sacrificed = false;
+ SetCombatMovement(true);
- if (Phase > NORMAL)
- Phase = NORMAL;
+ if (_introCompleted)
+ events.SetPhase(NORMAL);
+ else
+ events.SetPhase(IDLE);
- me->SetDisableGravity(Phase == NORMAL);
+ me->SetDisableGravity(events.IsInPhase(NORMAL));
- introTimer = 1 * IN_MILLISECONDS;
- introPhase = 0;
- arthasGUID = 0;
+ _arthasGUID = 0;
- if (instance)
- {
- instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
instance->SetData64(DATA_SACRIFICED_PLAYER, 0);
}
- }
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- Talk(SAY_AGGRO);
-
- sinsterStrikeTimer = 7 * IN_MILLISECONDS;
- callFlamesTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
-
- if (instance)
- instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
- }
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
- void JustSummoned(Creature* summon) OVERRIDE
- {
- if (summon->GetEntry() == NPC_RITUAL_CHANNELER)
- summon->CastSpell(summon, SPELL_SUMMONED_VIS, true);
+ void JustSummoned(Creature* summon) OVERRIDE
+ {
+ if (summon->GetEntry() == NPC_RITUAL_CHANNELER)
+ summon->CastSpell(summon, SPELL_SUMMONED_VIS, true);
+ summons.Summon(summon);
+ }
- summons.Summon(summon);
- }
+ void MoveInLineOfSight(Unit* who) OVERRIDE
+ {
+ if (!who)
+ return;
- void SummonedCreatureDespawn(Creature* summon) OVERRIDE
- {
- summons.Despawn(summon);
- }
+ if (events.IsInPhase(IDLE) && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 40))
+ {
+ events.SetPhase(INTRO);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- void MoveInLineOfSight(Unit* who) OVERRIDE
+ if (GameObject* mirror = ObjectAccessor::GetGameObject(*me, DATA_UTGARDE_MIRROR))
+ mirror->SetGoState(GO_STATE_READY);
- {
- if (!who)
- return;
+ if (Creature* arthas = me->SummonCreature(NPC_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ arthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ _arthasGUID = arthas->GetGUID();
+ }
+ events.ScheduleEvent(EVENT_INTRO_SVALA_TALK_0, 1 * IN_MILLISECONDS, 0, INTRO);
+ }
+ }
- if (Phase == IDLE && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 40))
+ void KilledUnit(Unit* who) OVERRIDE
{
- Phase = INTRO;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- if (GameObject* mirror = GetClosestGameObjectWithEntry(me, GO_UTGARDE_MIRROR, 100.0f))
- mirror->SetGoState(GO_STATE_READY);
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ if (events.IsInPhase(SACRIFICING))
+ SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
+ _JustDied();
+ Talk(SAY_DEATH);
+ }
- if (Creature* arthas = me->SummonCreature(NPC_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
+ void SpellHitTarget(Unit* /*target*/, SpellInfo const* spellInfo) OVERRIDE
+ {
+ if (spellInfo->Id == SPELL_RITUAL_STRIKE_EFF_1 && !events.IsInPhase(NORMAL) && !events.IsInPhase(SVALADEAD))
{
- arthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- arthasGUID = arthas->GetGUID();
+ events.SetPhase(NORMAL);
+ events.ScheduleEvent(EVENT_SINISTER_STRIKE, 7 * IN_MILLISECONDS, 0, NORMAL);
+ events.ScheduleEvent(EVENT_CALL_FLAMES, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, NORMAL);
+ SetCombatMovement(true);
+
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 300.0f, true))
+ me->GetMotionMaster()->MoveChase(target);
}
}
- }
-
- void KilledUnit(Unit* victim) OVERRIDE
- {
- if (victim != me)
- Talk(SAY_SLAY);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (Phase == SACRIFICING)
- SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
-
- me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
-
- summons.DespawnAll();
-
- if (instance)
- instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, DONE);
-
- Talk(SAY_DEATH);
- }
- void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell) OVERRIDE
- {
- if (spell->Id == SPELL_RITUAL_STRIKE_EFF_1 && Phase != NORMAL && Phase != SVALADEAD)
+ void UpdateAI(uint32 diff) OVERRIDE
{
- Phase = NORMAL;
- SetCombatMovement(true);
+ if (events.IsInPhase(IDLE))
+ return;
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 300.0f, true))
- me->GetMotionMaster()->MoveChase(target);
- }
- }
+ if (events.IsInPhase(NORMAL) && !UpdateVictim())
+ return;
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (Phase == IDLE)
- return;
+ events.Update(diff);
- if (Phase == INTRO)
- {
- if (introTimer <= diff)
+ if (!_sacrificed && HealthBelowPct(50))
{
- Creature* arthas = Unit::GetCreature(*me, arthasGUID);
- if (!arthas)
- return;
+ _sacrificed = true;
+ events.SetPhase(SACRIFICING);
+ events.ScheduleEvent(EVENT_RITUAL_PREPARATION, 0, 0, SACRIFICING);
+ }
+
+ if (events.IsInPhase(NORMAL))
+ DoMeleeAttackIfReady();
- switch (introPhase)
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- case 0:
+ case EVENT_INTRO_SVALA_TALK_0:
Talk(SAY_SVALA_INTRO_0);
- ++introPhase;
- introTimer = 8100;
+ events.ScheduleEvent(EVENT_INTRO_ARTHAS_TALK_0, 8.1 * IN_MILLISECONDS, 0, INTRO);
break;
- case 1:
- arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_1);
- ++introPhase;
- introTimer = 10000;
+ case EVENT_INTRO_ARTHAS_TALK_0:
+ if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID))
+ arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_1);
+ events.ScheduleEvent(EVENT_INTRO_TRANSFORM_0, 10 * IN_MILLISECONDS, 0, INTRO);
break;
- case 2:
- arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
+ case EVENT_INTRO_TRANSFORM_0:
+ {
+ if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID))
+ arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
+ Position pos;
pos.Relocate(me);
pos.m_positionZ += 8.0f;
me->GetMotionMaster()->MoveTakeoff(0, pos);
// spectators flee event
- if (instance)
+ std::list<Creature*> lspectatorList;
+ GetCreatureListWithEntryInGrid(lspectatorList, me, NPC_SPECTATOR, 100.0f);
+ for (std::list<Creature*>::iterator itr = lspectatorList.begin(); itr != lspectatorList.end(); ++itr)
{
- std::list<Creature*> lspectatorList;
- GetCreatureListWithEntryInGrid(lspectatorList, me, NPC_SPECTATOR, 100.0f);
- for (std::list<Creature*>::iterator itr = lspectatorList.begin(); itr != lspectatorList.end(); ++itr)
+ if ((*itr)->IsAlive())
{
- if ((*itr)->IsAlive())
- {
- (*itr)->SetStandState(UNIT_STAND_STATE_STAND);
- (*itr)->SetWalk(false);
- (*itr)->GetMotionMaster()->MovePoint(1, spectatorWP[0][0], spectatorWP[0][1], spectatorWP[0][2]);
- }
+ (*itr)->SetStandState(UNIT_STAND_STATE_STAND);
+ (*itr)->SetWalk(false);
+ (*itr)->GetMotionMaster()->MovePoint(1, spectatorWP[0]);
}
}
- ++introPhase;
- introTimer = 4200;
+ events.ScheduleEvent(EVENT_INTRO_TRANSFORM_1, 4.2 * IN_MILLISECONDS, 0, INTRO);
break;
- case 3:
+ }
+ case EVENT_INTRO_TRANSFORM_1:
me->CastSpell(me, SPELL_SVALA_TRANSFORMING1, false);
- ++introPhase;
- introTimer = 6200;
+ events.ScheduleEvent(EVENT_INTRO_TRANSFORM_2, 6.2 * IN_MILLISECONDS, 0, INTRO);
break;
- case 4:
+ case EVENT_INTRO_TRANSFORM_2:
me->CastSpell(me, SPELL_SVALA_TRANSFORMING2, false);
- arthas->InterruptNonMeleeSpells(true);
+ if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID))
+ {
+ arthas->InterruptNonMeleeSpells(true);
+ me->SetFacingToObject(arthas);
+ }
me->RemoveAllAuras();
me->UpdateEntry(NPC_SVALA_SORROWGRAVE);
- me->SetFacingToObject(arthas);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- ++introPhase;
- introTimer = 3200;
+ events.ScheduleEvent(EVENT_INTRO_SVALA_TALK_1, 10 * IN_MILLISECONDS, 0, INTRO);
break;
- case 5:
+ case EVENT_INTRO_SVALA_TALK_1:
Talk(SAY_SVALA_INTRO_1);
- ++introPhase;
- introTimer = 10000;
+ events.ScheduleEvent(EVENT_INTRO_ARTHAS_TALK_1, 3.2 * IN_MILLISECONDS, 0, INTRO);
break;
- case 6:
- arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_2);
- ++introPhase;
- introTimer = 7200;
+ case EVENT_INTRO_ARTHAS_TALK_1:
+ if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID))
+ arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_2);
+ events.ScheduleEvent(EVENT_INTRO_SVALA_TALK_2, 7.2 * IN_MILLISECONDS, 0, INTRO);
break;
- case 7:
+ case EVENT_INTRO_SVALA_TALK_2:
Talk(SAY_SVALA_INTRO_2);
me->SetFacingTo(1.58f);
- arthas->SetVisible(false);
- ++introPhase;
- introTimer = 13800;
+ if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID))
+ arthas->SetVisible(false);
+ events.ScheduleEvent(EVENT_INTRO_RELOCATE_SVALA, 13.8 * IN_MILLISECONDS, 0, INTRO);
break;
- case 8:
+ case EVENT_INTRO_RELOCATE_SVALA:
+ {
+ Position pos;
pos.Relocate(me);
pos.m_positionX = me->GetHomePosition().GetPositionX();
pos.m_positionY = me->GetHomePosition().GetPositionY();
@@ -341,210 +320,165 @@ public:
me->GetMotionMaster()->MoveLand(0, pos);
me->SetDisableGravity(false, true);
me->SetHover(true);
- ++introPhase;
- introTimer = 3000;
+ events.ScheduleEvent(EVENT_INTRO_DESPAWN_ARTHAS, 3 * IN_MILLISECONDS, 0, INTRO);
break;
- case 9:
- if (GameObject* mirror = GetClosestGameObjectWithEntry(me, GO_UTGARDE_MIRROR, 100.0f))
+ }
+ case EVENT_INTRO_DESPAWN_ARTHAS:
+ if (GameObject* mirror = ObjectAccessor::GetGameObject(*me, DATA_UTGARDE_MIRROR))
mirror->SetGoState(GO_STATE_ACTIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- arthas->DespawnOrUnsummon();
- arthasGUID = 0;
- Phase = NORMAL;
+ if (Creature* arthas = ObjectAccessor::GetCreature(*me, _arthasGUID))
+ arthas->DespawnOrUnsummon();
+ _arthasGUID = 0;
+ events.SetPhase(NORMAL);
+ _introCompleted = true;
+ events.ScheduleEvent(EVENT_SINISTER_STRIKE, 7 * IN_MILLISECONDS, 0, NORMAL);
+ events.ScheduleEvent(EVENT_CALL_FLAMES, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, NORMAL);
break;
- }
- }
- else
- introTimer -= diff;
-
- return;
- }
-
- if (Phase == NORMAL)
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- if (sinsterStrikeTimer <= diff)
- {
- DoCastVictim(SPELL_SINSTER_STRIKE);
- sinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS);
- }
- else
- sinsterStrikeTimer -= diff;
-
- if (callFlamesTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
- {
- DoCast(target, SPELL_CALL_FLAMES);
- callFlamesTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
- }
- }
- else callFlamesTimer -= diff;
-
- if (!sacrificed)
- {
- if (HealthBelowPct(50))
- {
- if (Unit* sacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true))
- {
- if (instance)
- instance->SetData64(DATA_SACRIFICED_PLAYER, sacrificeTarget->GetGUID());
-
- Talk(SAY_SACRIFICE_PLAYER);
-
- DoCast(sacrificeTarget, SPELL_RITUAL_PREPARATION);
-
- SetCombatMovement(false);
-
- Phase = SACRIFICING;
- sacrePhase = 0;
- sacrificeTimer = 1 * IN_MILLISECONDS;
-
- DoCast(me, SPELL_RITUAL_OF_THE_SWORD);
- sacrificed = true;
- }
- }
- }
-
- DoMeleeAttackIfReady();
- }
- else //SACRIFICING
- {
- if (sacrificeTimer <= diff)
- {
- switch (sacrePhase)
- {
- case 0:
- // spawn ritual channelers
- if (instance)
+ case EVENT_SINISTER_STRIKE:
+ DoCastVictim(SPELL_SINSTER_STRIKE);
+ events.ScheduleEvent(EVENT_SINISTER_STRIKE, urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS), 0, NORMAL);
+ break;
+ case EVENT_CALL_FLAMES:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_CALL_FLAMES);
+ events.ScheduleEvent(EVENT_CALL_FLAMES, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, NORMAL);
+ break;
+ case EVENT_RITUAL_PREPARATION:
+ if (Unit* sacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true))
{
- DoCast(me, SPELL_RITUAL_CHANNELER_1, true);
- DoCast(me, SPELL_RITUAL_CHANNELER_2, true);
- DoCast(me, SPELL_RITUAL_CHANNELER_3, true);
+ instance->SetData64(DATA_SACRIFICED_PLAYER, sacrificeTarget->GetGUID());
+ Talk(SAY_SACRIFICE_PLAYER);
+ DoCast(sacrificeTarget, SPELL_RITUAL_PREPARATION);
+ SetCombatMovement(false);
+ DoCast(me, SPELL_RITUAL_OF_THE_SWORD);
}
- ++sacrePhase;
- sacrificeTimer = 2 * IN_MILLISECONDS;
+ events.ScheduleEvent(EVENT_SPAWN_RITUAL_CHANNELERS, 1 * IN_MILLISECONDS, 0, SACRIFICING);
break;
- case 1:
+ case EVENT_SPAWN_RITUAL_CHANNELERS:
+ DoCast(me, SPELL_RITUAL_CHANNELER_1, true);
+ DoCast(me, SPELL_RITUAL_CHANNELER_2, true);
+ DoCast(me, SPELL_RITUAL_CHANNELER_3, true);
+ events.ScheduleEvent(EVENT_RITUAL_STRIKE, 2 * IN_MILLISECONDS, 0, SACRIFICING);
+ break;
+ case EVENT_RITUAL_STRIKE:
me->StopMoving();
me->GetMotionMaster()->MoveIdle();
me->InterruptNonMeleeSpells(true);
DoCast(me, SPELL_RITUAL_STRIKE_TRIGGER, true);
- ++sacrePhase;
- sacrificeTimer = 200;
+ events.ScheduleEvent(EVENT_RITUAL_DISARM, 200, 0, SACRIFICING);
break;
- case 2:
+ case EVENT_RITUAL_DISARM:
DoCast(me, SPELL_RITUAL_DISARM);
- ++sacrePhase;
break;
- case 3:
+ default:
break;
}
}
- else sacrificeTimer -= diff;
}
- }
- };
+ private:
+ uint64 _arthasGUID;
+ bool _sacrificed;
+ bool _introCompleted;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetUtgardePinnacleAI<boss_svalaAI>(creature);
+ }
};
class npc_ritual_channeler : public CreatureScript
{
-public:
- npc_ritual_channeler() : CreatureScript("npc_ritual_channeler") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ritual_channelerAI(creature);
- }
+ public:
+ npc_ritual_channeler() : CreatureScript("npc_ritual_channeler") { }
- struct npc_ritual_channelerAI : public ScriptedAI
- {
- npc_ritual_channelerAI(Creature* creature) :ScriptedAI(creature)
+ struct npc_ritual_channelerAI : public ScriptedAI
{
- instance = creature->GetInstanceScript();
+ npc_ritual_channelerAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
- SetCombatMovement(false);
- }
+ SetCombatMovement(false);
+ }
- InstanceScript* instance;
- uint32 paralyzeTimer;
+ InstanceScript* instance;
+ uint32 paralyzeTimer;
+
+ void Reset() OVERRIDE
+ {
+ paralyzeTimer = 1600;
- void Reset() OVERRIDE
- {
- paralyzeTimer = 1600;
- if (instance)
if (IsHeroic())
DoCast(me, SPELL_SHADOWS_IN_THE_DARK);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ }
- if (paralyzeTimer <= diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
- if (instance)
- if (Unit* victim = me->GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)))
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ if (paralyzeTimer <= diff)
+ {
+ if (Unit* victim = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)))
DoCast(victim, SPELL_PARALYZE, false);
- paralyzeTimer = 200;
+ paralyzeTimer = 200;
+ }
+ else
+ paralyzeTimer -= diff;
}
- else
- paralyzeTimer -= diff;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetUtgardePinnacleAI<npc_ritual_channelerAI>(creature);
}
- };
};
class npc_spectator : public CreatureScript
{
-public:
- npc_spectator() : CreatureScript("npc_spectator") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_spectatorAI(creature);
- }
+ public:
+ npc_spectator() : CreatureScript("npc_spectator") { }
- struct npc_spectatorAI : public ScriptedAI
- {
- npc_spectatorAI(Creature* creature) : ScriptedAI(creature) { }
+ struct npc_spectatorAI : public ScriptedAI
+ {
+ npc_spectatorAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset() OVERRIDE { }
+ void Reset() OVERRIDE { }
- void MovementInform(uint32 motionType, uint32 pointId) OVERRIDE
- {
- if (motionType == POINT_MOTION_TYPE)
+ void MovementInform(uint32 motionType, uint32 pointId) OVERRIDE
{
- if (pointId == 1)
- me->GetMotionMaster()->MovePoint(2, spectatorWP[1][0], spectatorWP[1][1], spectatorWP[1][2]);
- else if (pointId == 2)
- me->DespawnOrUnsummon(1000);
+ if (motionType == POINT_MOTION_TYPE)
+ {
+ if (pointId == 1)
+ me->GetMotionMaster()->MovePoint(2, spectatorWP[1]);
+ else if (pointId == 2)
+ me->DespawnOrUnsummon(1000);
+ }
}
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetUtgardePinnacleAI<npc_spectatorAI>(creature);
}
- };
};
class RitualTargetCheck
{
public:
- explicit RitualTargetCheck(Unit* _caster) : caster(_caster) { }
+ explicit RitualTargetCheck() { }
- bool operator() (WorldObject* unit) const
+ bool operator() (WorldObject* obj) const
{
- if (InstanceScript* instance = caster->GetInstanceScript())
- if (instance->GetData64(DATA_SACRIFICED_PLAYER) == unit->GetGUID())
+ if (InstanceScript* instance = obj->GetInstanceScript())
+ if (instance->GetData64(DATA_SACRIFICED_PLAYER) == obj->GetGUID())
return false;
return true;
}
-
- private:
- Unit* caster;
};
class spell_paralyze_pinnacle : public SpellScriptLoader
@@ -558,7 +492,7 @@ class spell_paralyze_pinnacle : public SpellScriptLoader
void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if(RitualTargetCheck(GetCaster()));
+ unitList.remove_if(RitualTargetCheck());
}
void Register() OVERRIDE
@@ -635,7 +569,7 @@ class npc_scourge_hulk : public CreatureScript
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_scourge_hulkAI(creature);
+ return GetUtgardePinnacleAI<npc_scourge_hulkAI>(creature);
}
};
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
index f592a4b2bb2..f4c306c726a 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
@@ -103,16 +103,10 @@ class boss_ymiron : public CreatureScript
public:
boss_ymiron() : CreatureScript("boss_ymiron") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ struct boss_ymironAI : public BossAI
{
- return new boss_ymironAI(creature);
- }
-
- struct boss_ymironAI : public ScriptedAI
- {
- boss_ymironAI(Creature* creature) : ScriptedAI(creature)
+ boss_ymironAI(Creature* creature) : BossAI(creature, DATA_KING_YMIRON)
{
- instance = creature->GetInstanceScript();
for (int i = 0; i < 4; ++i)
m_uiActiveOrder[i] = i;
for (int i = 0; i < 3; ++i)
@@ -122,9 +116,6 @@ public:
m_uiActiveOrder[i] = m_uiActiveOrder[r];
m_uiActiveOrder[r] = temp;
}
-
- m_uiActivedCreatureGUID = 0;
- m_uiOrbGUID = 0;
}
bool m_bIsWalking;
@@ -155,10 +146,9 @@ public:
uint64 m_uiActivedCreatureGUID;
uint64 m_uiOrbGUID;
- InstanceScript* instance;
-
void Reset() OVERRIDE
{
+ _Reset();
m_bIsWalking = false;
m_bIsPause = false;
m_bIsActiveWithBJORN = false;
@@ -182,19 +172,14 @@ public:
m_uiHealthAmountModifier = 1;
m_uiHealthAmountMultipler = DUNGEON_MODE(20, 25);
- DespawnBoatGhosts(m_uiActivedCreatureGUID);
- DespawnBoatGhosts(m_uiOrbGUID);
-
- if (instance)
- instance->SetData(DATA_KING_YMIRON_EVENT, NOT_STARTED);
+ m_uiActivedCreatureGUID = 0;
+ m_uiOrbGUID = 0;
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
+ _EnterCombat();
Talk(SAY_AGGRO);
-
- if (instance)
- instance->SetData(DATA_KING_YMIRON_EVENT, IN_PROGRESS);
}
void SpellHitTarget(Unit* who, SpellInfo const* spell) OVERRIDE
@@ -371,21 +356,17 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
+ _JustDied();
Talk(SAY_DEATH);
-
- DespawnBoatGhosts(m_uiActivedCreatureGUID);
- DespawnBoatGhosts(m_uiOrbGUID);
-
- if (instance)
- instance->SetData(DATA_KING_YMIRON_EVENT, DONE);
}
- void KilledUnit(Unit* /*victim*/) OVERRIDE
+ void KilledUnit(Unit* who) OVERRIDE
{
- Talk(SAY_SLAY);
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
}
- void DespawnBoatGhosts(uint64 m_uiCreatureGUID)
+ void DespawnBoatGhosts(uint64& m_uiCreatureGUID)
{
if (m_uiCreatureGUID)
if (Creature* temp = Unit::GetCreature(*me, m_uiCreatureGUID))
@@ -395,14 +376,16 @@ public:
}
};
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetUtgardePinnacleAI<boss_ymironAI>(creature);
+ }
};
class achievement_kings_bane : public AchievementCriteriaScript
{
public:
- achievement_kings_bane() : AchievementCriteriaScript("achievement_kings_bane")
- {
- }
+ achievement_kings_bane() : AchievementCriteriaScript("achievement_kings_bane") { }
bool OnCheck(Player* /*player*/, Unit* target) OVERRIDE
{
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
index 4959b3a6b58..46fabe41086 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_utgarde_pinnacle.cpp
@@ -19,246 +19,235 @@
#include "InstanceScript.h"
#include "utgarde_pinnacle.h"
-#define MAX_ENCOUNTER 4
-
-/* Utgarde Pinnacle encounters:
-0 - Svala Sorrowgrave
-1 - Gortok Palehoof
-2 - Skadi the Ruthless
-3 - King Ymiron
-*/
-
-enum GameObjects
+DoorData const doorData[] =
{
- ENTRY_SKADI_THE_RUTHLESS_DOOR = 192173,
- ENTRY_KING_YMIRON_DOOR = 192174,
- ENTRY_GORK_PALEHOOF_SPHERE = 188593
+ { GO_SKADI_THE_RUTHLESS_DOOR, DATA_SKADI_THE_RUTHLESS, DOOR_TYPE_PASSAGE, BOUNDARY_W },
+ { GO_KING_YMIRON_DOOR, DATA_KING_YMIRON, DOOR_TYPE_PASSAGE, BOUNDARY_N },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
};
class instance_utgarde_pinnacle : public InstanceMapScript
{
-public:
- instance_utgarde_pinnacle() : InstanceMapScript("instance_utgarde_pinnacle", 575) { }
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
- {
- return new instance_pinnacle(map);
- }
-
- struct instance_pinnacle : public InstanceScript
- {
- instance_pinnacle(Map* map) : InstanceScript(map) { }
-
- uint64 uiSvalaSorrowgrave;
- uint64 uiGortokPalehoof;
- uint64 uiSkadiTheRuthless;
- uint64 uiKingYmiron;
-
- uint64 uiSkadiTheRuthlessDoor;
- uint64 uiKingYmironDoor;
- uint64 uiGortokPalehoofSphere;
+ public:
+ instance_utgarde_pinnacle() : InstanceMapScript(UPScriptName, 575) { }
- uint64 uiFrenziedWorgen;
- uint64 uiRavenousFurbolg;
- uint64 uiFerociousRhino;
- uint64 uiMassiveJormungar;
- uint64 uiPalehoofOrb;
-
- uint64 uiSvala;
- uint64 uiSacrificedPlayer;
-
- uint32 m_auiEncounter[MAX_ENCOUNTER];
-
- std::string str_data;
-
- void Initialize() OVERRIDE
+ struct instance_utgarde_pinnacle_InstanceMapScript : public InstanceScript
{
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- m_auiEncounter[i] = NOT_STARTED;
-
- uiSvalaSorrowgrave = 0;
- uiGortokPalehoof = 0;
- uiSkadiTheRuthless = 0;
- uiKingYmiron = 0;
-
- uiSkadiTheRuthlessDoor = 0;
- uiKingYmironDoor = 0;
- uiGortokPalehoofSphere = 0;
+ instance_utgarde_pinnacle_InstanceMapScript(Map* map) : InstanceScript(map)
+ {
+ SetBossNumber(EncounterCount);
+ LoadDoorData(doorData);
- uiFrenziedWorgen = 0;
- uiRavenousFurbolg = 0;
- uiFerociousRhino = 0;
- uiMassiveJormungar = 0;
- uiPalehoofOrb = 0;
+ SvalaSorrowgraveGUID = 0;
+ GortokPalehoofGUID = 0;
+ SkadiTheRuthlessGUID = 0;
+ KingYmironGUID = 0;
- uiSvala = 0;
- uiSacrificedPlayer = 0;
- }
+ UtgardeMirrorGUID = 0;
+ GortokPalehoofSphereGUID = 0;
- bool IsEncounterInProgress() const OVERRIDE
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- return true;
+ FrenziedWorgenGUID = 0;
+ RavenousFurbolgGUID = 0;
+ FerociousRhinoGUID = 0;
+ MassiveJormungarGUID = 0;
+ PalehoofOrbGUID = 0;
- return false;
- }
+ SvalaGUID = 0;
+ SacrificedPlayerGUID = 0;
+ }
- void OnCreatureCreate(Creature* creature) OVERRIDE
- {
- switch (creature->GetEntry())
+ void OnCreatureCreate(Creature* creature) OVERRIDE
{
- case BOSS_SVALA_SORROWGRAVE: uiSvalaSorrowgrave = creature->GetGUID(); break;
- case BOSS_GORTOK_PALEHOOF: uiGortokPalehoof = creature->GetGUID(); break;
- case BOSS_SKADI_RUTHLESS: uiSkadiTheRuthless = creature->GetGUID(); break;
- case BOSS_KING_YMIRON: uiKingYmiron = creature->GetGUID(); break;
- case NPC_FRENZIED_WORGEN: uiFrenziedWorgen = creature->GetGUID(); break;
- case NPC_RAVENOUS_FURBOLG: uiRavenousFurbolg = creature->GetGUID(); break;
- case NPC_MASSIVE_JORMUNGAR: uiMassiveJormungar = creature->GetGUID(); break;
- case NPC_FEROCIOUS_RHINO: uiFerociousRhino = creature->GetGUID(); break;
- case NPC_SVALA: uiSvala = creature->GetGUID(); break;
- case NPC_PALEHOOF_ORB: uiPalehoofOrb = creature->GetGUID(); break;
+ switch (creature->GetEntry())
+ {
+ case NPC_SVALA_SORROWGRAVE:
+ SvalaSorrowgraveGUID = creature->GetGUID();
+ break;
+ case NPC_GORTOK_PALEHOOF:
+ GortokPalehoofGUID = creature->GetGUID();
+ break;
+ case NPC_SKADI_THE_RUTHLESS:
+ SkadiTheRuthlessGUID = creature->GetGUID();
+ break;
+ case NPC_KING_YMIRON:
+ KingYmironGUID = creature->GetGUID();
+ break;
+ case NPC_FRENZIED_WORGEN:
+ FrenziedWorgenGUID = creature->GetGUID();
+ break;
+ case NPC_RAVENOUS_FURBOLG:
+ RavenousFurbolgGUID = creature->GetGUID();
+ break;
+ case NPC_MASSIVE_JORMUNGAR:
+ MassiveJormungarGUID = creature->GetGUID();
+ break;
+ case NPC_FEROCIOUS_RHINO:
+ FerociousRhinoGUID = creature->GetGUID();
+ break;
+ case NPC_SVALA:
+ SvalaGUID = creature->GetGUID();
+ break;
+ case NPC_PALEHOOF_ORB:
+ PalehoofOrbGUID = creature->GetGUID();
+ break;
+ default:
+ break;
+ }
}
- }
- void OnGameObjectCreate(GameObject* go) OVERRIDE
- {
- switch (go->GetEntry())
+ void OnGameObjectCreate(GameObject* go) OVERRIDE
{
- case ENTRY_SKADI_THE_RUTHLESS_DOOR:
- uiSkadiTheRuthlessDoor = go->GetGUID();
- if (m_auiEncounter[2] == DONE) HandleGameObject(0, true, go);
- break;
- case ENTRY_KING_YMIRON_DOOR:
- uiKingYmironDoor = go->GetGUID();
- if (m_auiEncounter[3] == DONE) HandleGameObject(0, true, go);
- break;
- case ENTRY_GORK_PALEHOOF_SPHERE:
- uiGortokPalehoofSphere = go->GetGUID();
- if (m_auiEncounter[1] == DONE)
- {
- HandleGameObject(0, true, go);
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
- break;
+ switch (go->GetEntry())
+ {
+ case GO_UTGARDE_MIRROR:
+ UtgardeMirrorGUID = go->GetGUID();
+ break;
+ case GO_GORTOK_PALEHOOF_SPHERE:
+ GortokPalehoofSphereGUID = go->GetGUID();
+ if (GetBossState(DATA_GORTOK_PALEHOOF) == DONE)
+ {
+ HandleGameObject(0, true, go);
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ break;
+ case GO_SKADI_THE_RUTHLESS_DOOR:
+ case GO_KING_YMIRON_DOOR:
+ AddDoor(go, true);
+ break;
+ default:
+ break;
+ }
}
- }
- void SetData(uint32 type, uint32 data) OVERRIDE
- {
- switch (type)
+ void OnGameObjectRemove(GameObject* go) OVERRIDE
{
- case DATA_SVALA_SORROWGRAVE_EVENT:
- m_auiEncounter[0] = data;
- break;
- case DATA_GORTOK_PALEHOOF_EVENT:
- m_auiEncounter[1] = data;
- break;
- case DATA_SKADI_THE_RUTHLESS_EVENT:
- if (data == DONE)
- HandleGameObject(uiSkadiTheRuthlessDoor, true);
- m_auiEncounter[2] = data;
- break;
- case DATA_KING_YMIRON_EVENT:
- if (data == DONE)
- HandleGameObject(uiKingYmironDoor, true);
- m_auiEncounter[3] = data;
- break;
+ switch (go->GetEntry())
+ {
+ case GO_SKADI_THE_RUTHLESS_DOOR:
+ case GO_KING_YMIRON_DOOR:
+ AddDoor(go, false);
+ break;
+ default:
+ break;
+ }
}
- if (data == DONE)
- SaveToDB();
- }
-
- void SetData64(uint32 type, uint64 data) OVERRIDE
- {
- switch (type)
+ void SetData64(uint32 type, uint64 data) OVERRIDE
{
- case DATA_SACRIFICED_PLAYER:
- uiSacrificedPlayer = data;
- break;
+ switch (type)
+ {
+ case DATA_SACRIFICED_PLAYER:
+ SacrificedPlayerGUID = data;
+ break;
+ default:
+ break;
+ }
}
- }
- uint32 GetData(uint32 type) const OVERRIDE
- {
- switch (type)
+ uint64 GetData64(uint32 type) const OVERRIDE
{
- case DATA_SVALA_SORROWGRAVE_EVENT: return m_auiEncounter[0];
- case DATA_GORTOK_PALEHOOF_EVENT: return m_auiEncounter[1];
- case DATA_SKADI_THE_RUTHLESS_EVENT: return m_auiEncounter[2];
- case DATA_KING_YMIRON_EVENT: return m_auiEncounter[3];
+ switch (type)
+ {
+ case DATA_SVALA_SORROWGRAVE:
+ return SvalaSorrowgraveGUID;
+ case DATA_GORTOK_PALEHOOF:
+ return GortokPalehoofGUID;
+ case DATA_SKADI_THE_RUTHLESS:
+ return SkadiTheRuthlessGUID;
+ case DATA_KING_YMIRON:
+ return KingYmironGUID;
+ case DATA_FRENZIED_WORGEN:
+ return FrenziedWorgenGUID;
+ case DATA_RAVENOUS_FURBOLG:
+ return RavenousFurbolgGUID;
+ case DATA_MASSIVE_JORMUNGAR:
+ return MassiveJormungarGUID;
+ case DATA_FEROCIOUS_RHINO:
+ return FerociousRhinoGUID;
+ case DATA_GORTOK_ORB:
+ return PalehoofOrbGUID;
+ case DATA_GORTOK_PALEHOOF_SPHERE:
+ return GortokPalehoofSphereGUID;
+ case DATA_UTGARDE_MIRROR:
+ return UtgardeMirrorGUID;
+ case DATA_SVALA:
+ return SvalaGUID;
+ case DATA_SACRIFICED_PLAYER:
+ return SacrificedPlayerGUID;
+ default:
+ break;
+ }
+
+ return 0;
}
- return 0;
- }
- uint64 GetData64(uint32 identifier) const OVERRIDE
- {
- switch (identifier)
+ std::string GetSaveData() OVERRIDE
{
- case DATA_SVALA_SORROWGRAVE: return uiSvalaSorrowgrave;
- case DATA_GORTOK_PALEHOOF: return uiGortokPalehoof;
- case DATA_SKADI_THE_RUTHLESS: return uiSkadiTheRuthless;
- case DATA_KING_YMIRON: return uiKingYmiron;
- case DATA_NPC_FRENZIED_WORGEN: return uiFrenziedWorgen;
- case DATA_NPC_RAVENOUS_FURBOLG: return uiRavenousFurbolg;
- case DATA_NPC_MASSIVE_JORMUNGAR: return uiMassiveJormungar;
- case DATA_NPC_FEROCIOUS_RHINO: return uiFerociousRhino;
- case DATA_NPC_ORB: return uiPalehoofOrb;
- case DATA_SVALA: return uiSvala;
- case DATA_GORTOK_PALEHOOF_SPHERE: return uiGortokPalehoofSphere;
- case DATA_SACRIFICED_PLAYER: return uiSacrificedPlayer;
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "U P " << GetBossSaveData();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
}
- return 0;
- }
+ void Load(char const* str) OVERRIDE
+ {
+ if (!str)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
- std::string GetSaveData() OVERRIDE
- {
- OUT_SAVE_INST_DATA;
+ OUT_LOAD_INST_DATA(str);
- std::ostringstream saveStream;
- saveStream << "U P " << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' '
- << m_auiEncounter[2] << ' ' << m_auiEncounter[3];
+ char dataHead1, dataHead2;
- str_data = saveStream.str();
+ std::istringstream loadStream(str);
+ loadStream >> dataHead1 >> dataHead2;
- OUT_SAVE_INST_DATA_COMPLETE;
- return str_data;
- }
+ if (dataHead1 == 'U' && dataHead2 == 'P')
+ {
+ for (uint32 i = 0; i < EncounterCount; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+ SetBossState(i, EncounterState(tmpState));
+ }
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
- void Load(const char* in) OVERRIDE
- {
- if (!in)
- {
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ OUT_LOAD_INST_DATA_COMPLETE;
}
- OUT_LOAD_INST_DATA(in);
+ protected:
+ uint64 SvalaSorrowgraveGUID;
+ uint64 GortokPalehoofGUID;
+ uint64 SkadiTheRuthlessGUID;
+ uint64 KingYmironGUID;
- char dataHead1, dataHead2;
- uint16 data0, data1, data2, data3;
+ uint64 UtgardeMirrorGUID;
+ uint64 GortokPalehoofSphereGUID;
- std::istringstream loadStream(in);
- loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+ uint64 FrenziedWorgenGUID;
+ uint64 RavenousFurbolgGUID;
+ uint64 FerociousRhinoGUID;
+ uint64 MassiveJormungarGUID;
- if (dataHead1 == 'U' && dataHead2 == 'P')
- {
- m_auiEncounter[0] = data0;
- m_auiEncounter[1] = data1;
- m_auiEncounter[2] = data2;
- m_auiEncounter[3] = data3;
+ uint64 PalehoofOrbGUID;
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- m_auiEncounter[i] = NOT_STARTED;
+ uint64 SvalaGUID;
+ uint64 SacrificedPlayerGUID;
+ };
- } else OUT_LOAD_INST_DATA_FAIL;
-
- OUT_LOAD_INST_DATA_COMPLETE;
+ InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
+ {
+ return new instance_utgarde_pinnacle_InstanceMapScript(map);
}
- };
};
void AddSC_instance_utgarde_pinnacle()
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
index 6166b7c4891..ddf1d1e512a 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
@@ -15,46 +15,64 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DEF_PINNACLE_H
-#define DEF_PINNACLE_H
+#ifndef UTGARDE_PINNACLE_H_
+#define UTGARDE_PINNACLE_H_
-enum Data
+#define UPScriptName "instance_utgarde_pinnacle"
+
+uint32 const EncounterCount = 4;
+
+enum DataTypes
{
- DATA_SVALA_SORROWGRAVE_EVENT,
- DATA_GORTOK_PALEHOOF_EVENT,
- DATA_SKADI_THE_RUTHLESS_EVENT,
- DATA_KING_YMIRON_EVENT
+ // Encounter States/Boss GUIDs
+ DATA_SVALA_SORROWGRAVE = 0,
+ DATA_GORTOK_PALEHOOF = 1,
+ DATA_SKADI_THE_RUTHLESS = 2,
+ DATA_KING_YMIRON = 3,
+
+ // Additional Data
+ DATA_UTGARDE_MIRROR = 4,
+ DATA_SVALA = 5,
+ DATA_SACRIFICED_PLAYER = 6,
+
+ DATA_FRENZIED_WORGEN = 7,
+ DATA_RAVENOUS_FURBOLG = 8,
+ DATA_MASSIVE_JORMUNGAR = 9,
+ DATA_FEROCIOUS_RHINO = 10,
+ DATA_GORTOK_ORB = 11,
+ DATA_GORTOK_PALEHOOF_SPHERE = 12
};
-enum Data64
+enum CreatureIds
{
- DATA_SVALA,
- DATA_SVALA_SORROWGRAVE,
- DATA_GORTOK_PALEHOOF,
- DATA_SKADI_THE_RUTHLESS,
- DATA_NPC_GRAUF,
- DATA_KING_YMIRON,
- DATA_NPC_FRENZIED_WORGEN,
- DATA_NPC_RAVENOUS_FURBOLG,
- DATA_NPC_MASSIVE_JORMUNGAR,
- DATA_NPC_FEROCIOUS_RHINO,
- DATA_NPC_ORB,
- DATA_GORTOK_PALEHOOF_SPHERE,
- DATA_SACRIFICED_PLAYER
+ NPC_SVALA_SORROWGRAVE = 26668,
+ NPC_GORTOK_PALEHOOF = 26687,
+ NPC_SKADI_THE_RUTHLESS = 26693,
+ NPC_KING_YMIRON = 26861,
+
+ // Svala
+ NPC_SVALA = 29281,
+
+ // Gortok Palehoof
+ NPC_FRENZIED_WORGEN = 26683,
+ NPC_RAVENOUS_FURBOLG = 26684,
+ NPC_MASSIVE_JORMUNGAR = 26685,
+ NPC_FEROCIOUS_RHINO = 26686,
+ NPC_PALEHOOF_ORB = 26688
};
-enum CreatureID
+enum GameObjectIds
{
- BOSS_SVALA_SORROWGRAVE = 26668,
- BOSS_GORTOK_PALEHOOF = 26687,
- BOSS_SKADI_RUTHLESS = 26693,
- BOSS_KING_YMIRON = 26861,
- NPC_FRENZIED_WORGEN = 26683,
- NPC_RAVENOUS_FURBOLG = 26684,
- NPC_MASSIVE_JORMUNGAR = 26685,
- NPC_FEROCIOUS_RHINO = 26686,
- NPC_SVALA = 29281,
- NPC_PALEHOOF_ORB = 26688
+ GO_GORTOK_PALEHOOF_SPHERE = 188593,
+ GO_UTGARDE_MIRROR = 191745,
+ GO_SKADI_THE_RUTHLESS_DOOR = 192173,
+ GO_KING_YMIRON_DOOR = 192174
};
-#endif
+template<class AI>
+AI* GetUtgardePinnacleAI(Creature* creature)
+{
+ return GetInstanceAI<AI>(creature, UPScriptName);
+}
+
+#endif // UTGARDE_PINNACLE_H_
diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp
index 11f353b1cc2..083b4f879ee 100644
--- a/src/server/scripts/Northrend/zone_dalaran.cpp
+++ b/src/server/scripts/Northrend/zone_dalaran.cpp
@@ -64,11 +64,11 @@ public:
creature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
}
- void Reset()OVERRIDE { }
+ void Reset() OVERRIDE { }
- void EnterCombat(Unit* /*who*/)OVERRIDE { }
+ void EnterCombat(Unit* /*who*/) OVERRIDE { }
- void AttackStart(Unit* /*who*/)OVERRIDE { }
+ void AttackStart(Unit* /*who*/) OVERRIDE { }
void MoveInLineOfSight(Unit* who) OVERRIDE
@@ -118,7 +118,7 @@ public:
return;
}
- void UpdateAI(uint32 /*diff*/)OVERRIDE { }
+ void UpdateAI(uint32 /*diff*/) OVERRIDE { }
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp
index 0357ea075f4..2c311e20a79 100644
--- a/src/server/scripts/Northrend/zone_dragonblight.cpp
+++ b/src/server/scripts/Northrend/zone_dragonblight.cpp
@@ -37,6 +37,331 @@ EndContentData */
#include "CombatAI.h"
#include "Player.h"
+/*#####
+# npc_commander_eligor_dawnbringer
+#####*/
+
+enum CommanderEligorDawnbringer
+{
+ MODEL_IMAGE_OF_KELTHUZAD = 24787, // Image of Kel'Thuzad
+ MODEL_IMAGE_OF_SAPPHIRON = 24788, // Image of Sapphiron
+ MODEL_IMAGE_OF_RAZUVIOUS = 24799, // Image of Razuvious
+ MODEL_IMAGE_OF_GOTHIK = 24804, // Image of Gothik
+ MODEL_IMAGE_OF_THANE = 24802, // Image of Thane Korth'azz
+ MODEL_IMAGE_OF_BLAUMEUX = 24794, // Image of Lady Blaumeux
+ MODEL_IMAGE_OF_ZELIEK = 24800, // Image of Sir Zeliek
+ MODEL_IMAGE_OF_PATCHWERK = 24798, // Image of Patchwerk
+ MODEL_IMAGE_OF_GROBBULUS = 24792, // Image of Grobbulus
+ MODEL_IMAGE_OF_THADDIUS = 24801, // Image of Thaddius
+ MODEL_IMAGE_OF_GLUTH = 24803, // Image of Gluth
+ MODEL_IMAGE_OF_ANUBREKHAN = 24789, // Image of Anub'rekhan
+ MODEL_IMAGE_OF_FAERLINA = 24790, // Image of Faerlina
+ MODEL_IMAGE_OF_MAEXXNA = 24796, // Image of Maexxna
+ MODEL_IMAGE_OF_NOTH = 24797, // Image of Noth
+ MODEL_IMAGE_OF_HEIGAN = 24793, // Image of Heigan
+ MODEL_IMAGE_OF_LOATHEB = 24795, // Image of Loatheb
+
+ NPC_IMAGE_OF_KELTHUZAD = 27766, // Image of Kel'Thuzad
+ NPC_IMAGE_OF_SAPPHIRON = 27767, // Image of Sapphiron
+ NPC_IMAGE_OF_RAZUVIOUS = 27768, // Image of Razuvious
+ NPC_IMAGE_OF_GOTHIK = 27769, // Image of Gothik
+ NPC_IMAGE_OF_THANE = 27770, // Image of Thane Korth'azz
+ NPC_IMAGE_OF_BLAUMEUX = 27771, // Image of Lady Blaumeux
+ NPC_IMAGE_OF_ZELIEK = 27772, // Image of Sir Zeliek
+ NPC_IMAGE_OF_PATCHWERK = 27773, // Image of Patchwerk
+ NPC_IMAGE_OF_GROBBULUS = 27774, // Image of Grobbulus
+ NPC_IMAGE_OF_THADDIUS = 27775, // Image of Thaddius
+ NPC_IMAGE_OF_GLUTH = 27782, // Image of Gluth
+ NPC_IMAGE_OF_ANUBREKHAN = 27776, // Image of Anub'rekhan
+ NPC_IMAGE_OF_FAERLINA = 27777, // Image of Faerlina
+ NPC_IMAGE_OF_MAEXXNA = 27778, // Image of Maexxna
+ NPC_IMAGE_OF_NOTH = 27779, // Image of Noth
+ NPC_IMAGE_OF_HEIGAN = 27780, // Image of Heigan
+ NPC_IMAGE_OF_LOATHEB = 27781, // Image of Loatheb
+
+ NPC_INFANTRYMAN = 27160, // Add in case I randomize the spawning
+ NPC_SENTINAL = 27162,
+ NPC_BATTLE_MAGE = 27164,
+
+ // Five platforms to choose from
+ SAY_PINNACLE = 0,
+ SAY_DEATH_KNIGHT_WING = 1,
+ SAY_ABOMINATION_WING = 2,
+ SAY_SPIDER_WING = 3,
+ SAY_PLAGUE_WING = 4,
+ // Used in all talks
+ SAY_TALK_COMPLETE = 5,
+ // Pinnacle of Naxxramas
+ SAY_SAPPHIRON = 6,
+ SAY_KELTHUZAD_1 = 7,
+ SAY_KELTHUZAD_2 = 8,
+ SAY_KELTHUZAD_3 = 9,
+ // Death knight wing of Naxxramas
+ SAY_RAZUVIOUS = 10,
+ SAY_GOTHIK = 11,
+ SAY_DEATH_KNIGHTS_1 = 12,
+ SAY_DEATH_KNIGHTS_2 = 13,
+ SAY_DEATH_KNIGHTS_3 = 14,
+ SAY_DEATH_KNIGHTS_4 = 15,
+ // Blighted abomination wing of Naxxramas
+ SAY_PATCHWERK = 16,
+ SAY_GROBBULUS = 17,
+ SAY_GLUTH = 18,
+ SAY_THADDIUS = 19,
+ // Accursed spider wing of Naxxramas
+ SAY_ANUBREKHAN = 20,
+ SAY_FAERLINA = 21,
+ SAY_MAEXXNA = 22,
+ // Dread plague wing of Naxxramas
+ SAY_NOTH = 23,
+ SAY_HEIGAN_1 = 24,
+ SAY_HEIGAN_2 = 25,
+ SAY_LOATHEB = 26,
+
+ SPELL_HEROIC_IMAGE_CHANNEL = 49519,
+
+ EVENT_START_RANDOM = 1,
+ EVENT_MOVE_TO_POINT = 2,
+ EVENT_TALK_COMPLETE = 3,
+ EVENT_GET_TARGETS = 4,
+ EVENT_KELTHUZAD_2 = 5,
+ EVENT_KELTHUZAD_3 = 6,
+ EVENT_DEATH_KNIGHTS_2 = 7,
+ EVENT_DEATH_KNIGHTS_3 = 8,
+ EVENT_DEATH_KNIGHTS_4 = 9,
+ EVENT_HEIGAN_2 = 10
+};
+
+uint32 const AudienceMobs[3] = { NPC_INFANTRYMAN, NPC_SENTINAL, NPC_BATTLE_MAGE };
+
+Position const PosTalkLocations[6] =
+{
+ { 3805.453f, -682.9075f, 222.2917f, 2.793398f }, // Pinnacle of Naxxramas
+ { 3807.508f, -691.0882f, 221.9688f, 2.094395f }, // Death knight wing of Naxxramas
+ { 3797.228f, -690.3555f, 222.5019f, 1.134464f }, // Blighted abomination wing of Naxxramas
+ { 3804.038f, -672.3098f, 222.5019f, 4.578917f }, // Accursed spider wing of Naxxramas
+ { 3815.097f, -680.2596f, 221.9777f, 2.86234f }, // Dread plague wing of Naxxramas
+ { 3798.05f, -680.611f, 222.9825f, 6.038839f }, // Home
+};
+
+class npc_commander_eligor_dawnbringer : public CreatureScript
+{
+ public: npc_commander_eligor_dawnbringer() : CreatureScript("npc_commander_eligor_dawnbringer") {}
+
+ struct npc_commander_eligor_dawnbringerAI : public ScriptedAI
+ {
+ npc_commander_eligor_dawnbringerAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ talkWing = 0;
+ memset(audienceList, 0, sizeof(audienceList));
+ memset(imageList, 0, sizeof(imageList));
+ _events.ScheduleEvent(EVENT_GET_TARGETS, 5000);
+ _events.ScheduleEvent(EVENT_START_RANDOM, 20000);
+ }
+
+ void MovementInform(uint32 type, uint32 id) OVERRIDE
+ {
+ if (type == POINT_MOTION_TYPE)
+ {
+ if (id == 1)
+ {
+ me->SetFacingTo(PosTalkLocations[talkWing].m_orientation);
+ TurnAudience();
+
+ switch (talkWing)
+ {
+ case 0: // Pinnacle of Naxxramas
+ {
+ switch (urand (0, 1))
+ {
+ case 0: ChangeImage(NPC_IMAGE_OF_KELTHUZAD, MODEL_IMAGE_OF_KELTHUZAD, SAY_KELTHUZAD_1);
+ _events.ScheduleEvent(EVENT_KELTHUZAD_2, 8000); break;
+ case 1: ChangeImage(NPC_IMAGE_OF_SAPPHIRON, MODEL_IMAGE_OF_SAPPHIRON, SAY_SAPPHIRON); break;
+ }
+ }
+ break;
+ case 1: // Death knight wing of Naxxramas
+ {
+ switch (urand (0, 2))
+ {
+ case 0: ChangeImage(NPC_IMAGE_OF_RAZUVIOUS, MODEL_IMAGE_OF_RAZUVIOUS, SAY_RAZUVIOUS); break;
+ case 1: ChangeImage(NPC_IMAGE_OF_GOTHIK, MODEL_IMAGE_OF_GOTHIK, SAY_GOTHIK); break;
+ case 2: ChangeImage(NPC_IMAGE_OF_THANE, MODEL_IMAGE_OF_THANE, SAY_DEATH_KNIGHTS_1);
+ _events.ScheduleEvent(EVENT_DEATH_KNIGHTS_2, 10000); break;
+ }
+ }
+ break;
+ case 2: // Blighted abomination wing of Naxxramas
+ {
+ switch (urand (0, 3))
+ {
+ case 0: ChangeImage(NPC_IMAGE_OF_PATCHWERK, MODEL_IMAGE_OF_PATCHWERK, SAY_PATCHWERK); break;
+ case 1: ChangeImage(NPC_IMAGE_OF_GROBBULUS, MODEL_IMAGE_OF_GROBBULUS, SAY_GROBBULUS); break;
+ case 2: ChangeImage(NPC_IMAGE_OF_THADDIUS, MODEL_IMAGE_OF_THADDIUS, SAY_THADDIUS); break;
+ case 3: ChangeImage(NPC_IMAGE_OF_GLUTH, MODEL_IMAGE_OF_GLUTH, SAY_GLUTH); break;
+ }
+ }
+ break;
+ case 3: // Accursed spider wing of Naxxramas
+ {
+ switch (urand (0, 2))
+ {
+ case 0: ChangeImage(NPC_IMAGE_OF_ANUBREKHAN, MODEL_IMAGE_OF_ANUBREKHAN, SAY_ANUBREKHAN); break;
+ case 1: ChangeImage(NPC_IMAGE_OF_FAERLINA, MODEL_IMAGE_OF_FAERLINA, SAY_FAERLINA); break;
+ case 2: ChangeImage(NPC_IMAGE_OF_MAEXXNA, MODEL_IMAGE_OF_MAEXXNA, SAY_MAEXXNA); break;
+ }
+ }
+ break;
+ case 4: // Dread plague wing of Naxxramas
+ {
+ switch (urand (0, 2))
+ {
+ case 0: ChangeImage(NPC_IMAGE_OF_NOTH, MODEL_IMAGE_OF_NOTH, SAY_NOTH); break;
+ case 1: ChangeImage(NPC_IMAGE_OF_HEIGAN, MODEL_IMAGE_OF_HEIGAN, SAY_HEIGAN_1);
+ _events.ScheduleEvent(EVENT_HEIGAN_2, 8000); break;
+ case 2: ChangeImage(NPC_IMAGE_OF_LOATHEB, MODEL_IMAGE_OF_LOATHEB, SAY_LOATHEB); break;
+ }
+ }
+ break;
+ case 5: // Home
+ _events.ScheduleEvent(EVENT_START_RANDOM, 30000);
+ break;
+ }
+ }
+ }
+ }
+
+ void StoreTargets()
+ {
+ uint8 creaturecount;
+
+ creaturecount = 0;
+
+ for (uint8 ii = 0; ii < 3; ++ii)
+ {
+ std::list<Creature*> creatureList;
+ GetCreatureListWithEntryInGrid(creatureList, me, AudienceMobs[ii], 15.0f);
+ for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
+ {
+ if (Creature* creatureList = *itr)
+ {
+ audienceList[creaturecount] = creatureList->GetGUID();
+ ++creaturecount;
+ }
+ }
+ }
+
+ if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_KELTHUZAD, 20.0f, true))
+ imageList[0] = creature->GetGUID();
+ if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_RAZUVIOUS, 20.0f, true))
+ imageList[1] = creature->GetGUID();
+ if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_PATCHWERK, 20.0f, true))
+ imageList[2] = creature->GetGUID();
+ if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_ANUBREKHAN, 20.0f, true))
+ imageList[3] = creature->GetGUID();
+ if (Creature* creature = me->FindNearestCreature(NPC_IMAGE_OF_NOTH, 20.0f, true))
+ imageList[4] = creature->GetGUID();
+ }
+
+ void ChangeImage(uint32 entry, uint32 model, uint8 text)
+ {
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, imageList[talkWing]))
+ {
+ Talk(text);
+ creature->SetEntry(entry);
+ creature->SetDisplayId(model);
+ creature->CastSpell(creature, SPELL_HEROIC_IMAGE_CHANNEL);
+ _events.ScheduleEvent(EVENT_TALK_COMPLETE, 40000);
+ }
+ }
+
+ void TurnAudience()
+ {
+ for (uint8 i = 0; i < 10; ++i)
+ {
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, audienceList[i]))
+ creature->SetFacingToObject(me);
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_RANDOM:
+ talkWing = urand (0, 4);
+ Talk(talkWing);
+ _events.ScheduleEvent(EVENT_MOVE_TO_POINT, 8000);
+ break;
+ case EVENT_MOVE_TO_POINT:
+ me->SetWalk(true);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(1, PosTalkLocations[talkWing].m_positionX, PosTalkLocations[talkWing].m_positionY, PosTalkLocations[talkWing].m_positionZ);
+ break;
+ case EVENT_TALK_COMPLETE:
+ talkWing = 5;
+ Talk(talkWing);
+ _events.ScheduleEvent(EVENT_MOVE_TO_POINT, 5000);
+ break;
+ case EVENT_GET_TARGETS:
+ StoreTargets();
+ break;
+ case EVENT_KELTHUZAD_2:
+ Talk(SAY_KELTHUZAD_2);
+ _events.ScheduleEvent(EVENT_KELTHUZAD_3, 8000);
+ break;
+ case EVENT_KELTHUZAD_3:
+ Talk(SAY_KELTHUZAD_3);
+ break;
+ case EVENT_DEATH_KNIGHTS_2:
+ Talk(SAY_DEATH_KNIGHTS_2);
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, imageList[talkWing]))
+ {
+ creature->SetEntry(NPC_IMAGE_OF_BLAUMEUX);
+ creature->SetDisplayId(MODEL_IMAGE_OF_BLAUMEUX);
+ }
+ _events.ScheduleEvent(EVENT_DEATH_KNIGHTS_3, 10000);
+ break;
+ case EVENT_DEATH_KNIGHTS_3:
+ Talk(SAY_DEATH_KNIGHTS_3);
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, imageList[talkWing]))
+ {
+ creature->SetEntry(NPC_IMAGE_OF_ZELIEK);
+ creature->SetDisplayId(MODEL_IMAGE_OF_ZELIEK);
+ }
+ _events.ScheduleEvent(EVENT_DEATH_KNIGHTS_4, 10000);
+ break;
+ case EVENT_DEATH_KNIGHTS_4:
+ Talk(SAY_DEATH_KNIGHTS_4);
+ break;
+ case EVENT_HEIGAN_2:
+ Talk(SAY_HEIGAN_2);
+ break;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+ private:
+ EventMap _events;
+ uint64 audienceList[10];
+ uint64 imageList[5];
+ uint8 talkWing;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_commander_eligor_dawnbringerAI(creature);
+ }
+};
+
enum AlexstraszaWrGate
{
// Quest
@@ -303,10 +628,112 @@ class npc_wyrmrest_defender : public CreatureScript
}
};
+/*#####
+# npc_torturer_lecraft
+#####*/
+
+enum TorturerLeCraft
+{
+ SPELL_HEMORRHAGE = 30478,
+ SPELL_KIDNEY_SHOT = 30621,
+ SPELL_HIGH_EXECUTORS_BRANDING_IRON = 48603,
+ NPC_TORTURER_LECRAFT = 27394,
+ EVENT_HEMORRHAGE = 1,
+ EVENT_KIDNEY_SHOT = 2,
+ SAY_AGGRO = 0
+};
+
+class npc_torturer_lecraft : public CreatureScript
+{
+ public: npc_torturer_lecraft() : CreatureScript("npc_torturer_lecraft") {}
+
+ struct npc_torturer_lecraftAI : public ScriptedAI
+ {
+ npc_torturer_lecraftAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ _textCounter = 1;
+ _playerGUID = 0;
+ }
+
+ void EnterCombat(Unit* who) OVERRIDE
+ {
+ _events.ScheduleEvent(EVENT_HEMORRHAGE, urand(5000, 8000));
+ _events.ScheduleEvent(EVENT_KIDNEY_SHOT, urand(12000, 15000));
+
+ if (Player* player = who->ToPlayer())
+ Talk (SAY_AGGRO, player->GetGUID());
+ }
+
+ void SpellHit(Unit* caster, const SpellInfo* spell) OVERRIDE
+ {
+ if (spell->Id != SPELL_HIGH_EXECUTORS_BRANDING_IRON)
+ return;
+
+ if (Player* player = caster->ToPlayer())
+ {
+ if (_textCounter == 1)
+ _playerGUID = player->GetGUID();
+
+ if (_playerGUID != player->GetGUID())
+ return;
+
+ Talk(_textCounter, player->GetGUID());
+
+ if (_textCounter == 5)
+ player->KilledMonsterCredit(NPC_TORTURER_LECRAFT, 0);
+
+ ++_textCounter;
+
+ if (_textCounter == 13)
+ _textCounter = 6;
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_HEMORRHAGE:
+ DoCastVictim(SPELL_HEMORRHAGE);
+ _events.ScheduleEvent(EVENT_HEMORRHAGE, urand(12000, 168000));
+ break;
+ case EVENT_KIDNEY_SHOT:
+ DoCastVictim(SPELL_KIDNEY_SHOT);
+ _events.ScheduleEvent(EVENT_KIDNEY_SHOT, urand(20000, 26000));
+ break;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+ private:
+ EventMap _events;
+ uint8 _textCounter;
+ uint64 _playerGUID;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_torturer_lecraftAI(creature);
+ }
+};
+
void AddSC_dragonblight()
{
- new npc_alexstrasza_wr_gate;
- new spell_q12096_q12092_dummy;
- new spell_q12096_q12092_bark;
- new npc_wyrmrest_defender;
+ new npc_commander_eligor_dawnbringer();
+ new npc_alexstrasza_wr_gate();
+ new spell_q12096_q12092_dummy();
+ new spell_q12096_q12092_bark();
+ new npc_wyrmrest_defender();
+ new npc_torturer_lecraft();
}
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index 6bf791417ab..6587f0536b3 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -20,7 +20,9 @@
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "Player.h"
+#include "Spell.h"
#include "SpellInfo.h"
+#include "SpellScript.h"
#include "CreatureTextMgr.h"
/*######
@@ -508,87 +510,6 @@ public:
}
};
-/*Lightning Sentry - if you kill it when you have your Minion with you, you will get a quest credit*/
-enum Sentry
-{
- //Creature
- NPC_LIGHTNING_SENTRY = 26407,
- NPC_WAR_GOLEM = 27017,
- // Quest
- QUEST_OR_MAYBE_WE_DONT_A = 12138,
- QUEST_OR_MAYBE_WE_DONT_H = 12198,
- // Spell
- SPELL_CHARGED_SENTRY_TOTEM = 52703,
- SPELL_WAR_GOLEM_CHARGE_CREDIT = 47797,
-};
-
-enum SentryEvents
-{
- EVENT_SENTRY = 1
-};
-
-class npc_lightning_sentry : public CreatureScript
-{
-public:
- npc_lightning_sentry() : CreatureScript("npc_lightning_sentry") { }
-
- struct npc_lightning_sentryAI : public ScriptedAI
- {
- npc_lightning_sentryAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE
- {
- _events.ScheduleEvent(EVENT_SENTRY, urand(10000, 12000));
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SENTRY:
- DoCast(SPELL_CHARGED_SENTRY_TOTEM);
- _events.ScheduleEvent(EVENT_SENTRY, urand(10000, 12000));
- break;
- default:
- break;
- }
- }
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* killer) OVERRIDE
- {
- if (killer->ToPlayer() && killer->ToPlayer()->GetTypeId() == TYPEID_PLAYER)
- {
- if (me->FindNearestCreature(NPC_WAR_GOLEM, 10.0f, true))
- {
- if (killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_A) == QUEST_STATUS_INCOMPLETE ||
- killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_H) == QUEST_STATUS_INCOMPLETE)
- DoCast(killer, SPELL_WAR_GOLEM_CHARGE_CREDIT);
- }
- }
- }
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_lightning_sentryAI(creature);
- }
-};
-
/*Venture co. Straggler - when you cast Smoke Bomb, he will yell and run away*/
enum SmokeEmOut
{
@@ -830,6 +751,43 @@ public:
}
};
+enum ShredderDelivery
+{
+ NPC_BROKEN_DOWN_SHREDDER = 27354
+};
+
+class spell_shredder_delivery : public SpellScriptLoader
+{
+ public:
+ spell_shredder_delivery() : SpellScriptLoader("spell_shredder_delivery") { }
+
+ class spell_shredder_delivery_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_shredder_delivery_SpellScript);
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (GetCaster()->ToCreature()->GetEntry() == NPC_BROKEN_DOWN_SHREDDER)
+ GetCaster()->ToCreature()->DespawnOrUnsummon();
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_shredder_delivery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_shredder_delivery_SpellScript();
+ }
+};
+
void AddSC_grizzly_hills()
{
new npc_emily();
@@ -838,7 +796,7 @@ void AddSC_grizzly_hills()
new npc_tallhorn_stag();
new npc_amberpine_woodsman();
new npc_wounded_skirmisher();
- new npc_lightning_sentry();
new npc_venture_co_straggler();
new npc_lake_frog();
+ new spell_shredder_delivery();
}
diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp
index 671628e4cbc..fd5b0a5ca1c 100644
--- a/src/server/scripts/Northrend/zone_howling_fjord.cpp
+++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp
@@ -32,6 +32,8 @@ EndContentData */
#include "ScriptedGossip.h"
#include "ScriptedEscortAI.h"
#include "Player.h"
+#include "SpellInfo.h"
+#include "SpellScript.h"
/*######
## npc_apothecary_hanes
@@ -43,7 +45,8 @@ enum Entries
FACTION_ESCORTEE_H = 775,
NPC_HANES_FIRE_TRIGGER = 23968,
QUEST_TRAIL_OF_FIRE = 11241,
- SPELL_COSMETIC_LOW_POLY_FIRE = 56274
+ SPELL_COSMETIC_LOW_POLY_FIRE = 56274,
+ SPELL_HEALING_POTION = 17534
};
class npc_apothecary_hanes : public CreatureScript
@@ -92,7 +95,7 @@ public:
{
if (PotTimer <= diff)
{
- DoCast(me, 17534, true);
+ DoCast(me, SPELL_HEALING_POTION, true);
PotTimer = 10000;
} else PotTimer -= diff;
}
@@ -380,10 +383,107 @@ public:
}
};
+enum MindlessAbomination
+{
+ EVENT_CHECK_CHARMED = 1
+};
+
+class npc_mindless_abomination : public CreatureScript
+{
+public:
+ npc_mindless_abomination() : CreatureScript("npc_mindless_abomination") { }
+
+ struct npc_mindless_abominationAI : public ScriptedAI
+ {
+ npc_mindless_abominationAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ events.ScheduleEvent(EVENT_CHECK_CHARMED, 1000);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CHECK_CHARMED:
+ if (!me->IsCharmedOwnedByPlayerOrPlayer())
+ me->DespawnOrUnsummon();
+ else
+ events.ScheduleEvent(EVENT_CHECK_CHARMED, 1000);
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_mindless_abominationAI(creature);
+ }
+};
+
+class spell_mindless_abomination_explosion_fx_master : public SpellScriptLoader
+{
+ enum Spells
+ {
+ SPELL_RANDOM_CIRCUMFERENCE_POINT_POISON = 42266,
+ SPELL_COSMETIC_BLOOD_EXPLOSION_GREEN_LARGE = 43401
+ };
+
+ public:
+ spell_mindless_abomination_explosion_fx_master() : SpellScriptLoader("spell_mindless_abomination_explosion_fx_master") { }
+
+ class spell_mindless_abomination_explosion_fx_master_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mindless_abomination_explosion_fx_master_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RANDOM_CIRCUMFERENCE_POINT_POISON) || !sSpellMgr->GetSpellInfo(SPELL_COSMETIC_BLOOD_EXPLOSION_GREEN_LARGE))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*eff*/)
+ {
+ Creature* caster = GetCaster()->ToCreature();
+ if (!caster)
+ return;
+
+ caster->AI()->DoCast(caster, SPELL_COSMETIC_BLOOD_EXPLOSION_GREEN_LARGE);
+
+ for (uint8 i = 0; i < 10; ++i)
+ caster->AI()->DoCast(caster, SPELL_RANDOM_CIRCUMFERENCE_POINT_POISON);
+
+ caster->DespawnOrUnsummon(4000);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mindless_abomination_explosion_fx_master_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mindless_abomination_explosion_fx_master_SpellScript();
+ }
+};
+
void AddSC_howling_fjord()
{
- new npc_apothecary_hanes;
- new npc_plaguehound_tracker;
- new npc_razael_and_lyana;
- new npc_daegarn;
+ new npc_apothecary_hanes();
+ new npc_plaguehound_tracker();
+ new npc_razael_and_lyana();
+ new npc_daegarn();
+ new npc_mindless_abomination();
+ new spell_mindless_abomination_explosion_fx_master();
}
diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp
index d952321c749..5c65be982e0 100644
--- a/src/server/scripts/Northrend/zone_icecrown.cpp
+++ b/src/server/scripts/Northrend/zone_icecrown.cpp
@@ -25,91 +25,6 @@
#include "CombatAI.h"
/*######
-## npc_arete
-######*/
-
-#define GOSSIP_ARETE_ITEM1 "Lord-Commander, I would hear your tale."
-#define GOSSIP_ARETE_ITEM2 "<You nod slightly but do not complete the motion as the Lord-Commander narrows his eyes before he continues.>"
-#define GOSSIP_ARETE_ITEM3 "I thought that they now called themselves the Scarlet Onslaught?"
-#define GOSSIP_ARETE_ITEM4 "Where did the grand admiral go?"
-#define GOSSIP_ARETE_ITEM5 "That's fine. When do I start?"
-#define GOSSIP_ARETE_ITEM6 "Let's finish this!"
-#define GOSSIP_ARETE_ITEM7 "That's quite a tale, Lord-Commander."
-
-enum Arete
-{
- GOSSIP_TEXTID_ARETE1 = 13525,
- GOSSIP_TEXTID_ARETE2 = 13526,
- GOSSIP_TEXTID_ARETE3 = 13527,
- GOSSIP_TEXTID_ARETE4 = 13528,
- GOSSIP_TEXTID_ARETE5 = 13529,
- GOSSIP_TEXTID_ARETE6 = 13530,
- GOSSIP_TEXTID_ARETE7 = 13531,
-
- QUEST_THE_STORY_THUS_FAR = 12807
-};
-
-class npc_arete : public CreatureScript
-{
-public:
- npc_arete() : CreatureScript("npc_arete") { }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_THE_STORY_THUS_FAR) == QUEST_STATUS_INCOMPLETE)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE1, creature->GetGUID());
- return true;
- }
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE2, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE3, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE4, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE5, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE6, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE7, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(QUEST_THE_STORY_THUS_FAR);
- break;
- }
-
- return true;
- }
-};
-
-/*######
## npc_squire_david
######*/
@@ -483,7 +398,7 @@ class npc_tournament_training_dummy : public CreatureScript
me->SetControlled(true, UNIT_STATE_STUNNED);
}
- void MoveInLineOfSight(Unit* /*who*/)OVERRIDE { }
+ void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
};
@@ -1149,7 +1064,6 @@ class npc_morbidus : public CreatureScript
void AddSC_icecrown()
{
- new npc_arete;
new npc_squire_david;
new npc_argent_valiant;
new npc_guardian_pavilion;
diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
index 77b85037a01..a0b6524bd89 100644
--- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
@@ -1082,6 +1082,57 @@ public:
}
};
+/*######
+## Quest Dreadsaber Mastery: Stalking the Prey (12550)
+######*/
+
+enum ShangoTracks
+{
+ SPELL_CORRECT_TRACKS = 52160,
+ SPELL_INCORRECT_TRACKS = 52163,
+ SAY_CORRECT_TRACKS = 28634,
+ SAY_INCORRECT_TRACKS = 28635
+};
+
+class spell_shango_tracks : public SpellScriptLoader
+{
+public:
+ spell_shango_tracks() : SpellScriptLoader("spell_shango_tracks") { }
+
+ class spell_shango_tracks_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_shango_tracks_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* player = GetHitUnit()->ToPlayer())
+ {
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_CORRECT_TRACKS:
+ player->MonsterSay(sObjectMgr->GetTrinityStringForDBCLocale(SAY_CORRECT_TRACKS), LANG_UNIVERSAL, player->GetGUID());
+ break;
+ case SPELL_INCORRECT_TRACKS:
+ player->MonsterSay(sObjectMgr->GetTrinityStringForDBCLocale(SAY_INCORRECT_TRACKS), LANG_UNIVERSAL, player->GetGUID());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_shango_tracks_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_shango_tracks_SpellScript();
+ }
+};
+
void AddSC_sholazar_basin()
{
new npc_injured_rainspeaker_oracle();
@@ -1095,4 +1146,5 @@ void AddSC_sholazar_basin()
new spell_q12589_shoot_rjr();
new npc_haiphoon();
new npc_vics_flying_machine();
+ new spell_shango_tracks();
}
diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp
index 83d49045eff..c09c817a2bf 100644
--- a/src/server/scripts/Northrend/zone_storm_peaks.cpp
+++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp
@@ -163,7 +163,8 @@ public:
## npc_brunnhildar_prisoner
######*/
-enum BrunnhildarPrisoner {
+enum BrunnhildarPrisoner
+{
SPELL_ICE_PRISON = 54894,
SPELL_ICE_LANCE = 55046,
SPELL_FREE_PRISONER = 55048,
@@ -413,6 +414,180 @@ class npc_hyldsmeet_protodrake : public CreatureScript
}
};
+
+/*#####
+# npc_brann_bronzebeard for Quest 13285 "Forging the Keystone"
+#####*/
+
+enum BrannBronzebeard
+{
+ NPC_BRANN_BRONZEBEARD = 31810,
+ NPC_A_DISTANT_VOICE = 31814,
+ OBJECT_TOL_SIGNAL_1 = 193590,
+ OBJECT_TOL_SIGNAL_2 = 193591,
+ OBJECT_TOL_SIGNAL_3 = 193592,
+ OBJECT_TOL_SIGNAL_4 = 193593,
+ OBJECT_TOL_SIGNAL_5 = 193594,
+ SPELL_RESURRECTION = 58854,
+ SAY_BRANN_1 = 0,
+ SAY_BRANN_2 = 1,
+ SAY_BRANN_3 = 2,
+ SAY_VOICE_1 = 0,
+ SAY_VOICE_2 = 1,
+ SAY_VOICE_3 = 2,
+ SAY_VOICE_4 = 3,
+ SAY_VOICE_5 = 4,
+
+ EVENT_SCRIPT_1 = 1,
+ EVENT_SCRIPT_2 = 2,
+ EVENT_SCRIPT_3 = 3,
+ EVENT_SCRIPT_4 = 4,
+ EVENT_SCRIPT_5 = 5,
+ EVENT_SCRIPT_6 = 6,
+ EVENT_SCRIPT_7 = 7,
+ EVENT_SCRIPT_8 = 8,
+ EVENT_SCRIPT_9 = 9,
+ EVENT_SCRIPT_10 = 10,
+ EVENT_SCRIPT_11 = 11,
+ EVENT_SCRIPT_12 = 12,
+ EVENT_SCRIPT_13 = 13
+};
+
+class npc_brann_bronzebeard_keystone : public CreatureScript
+{
+public:
+ npc_brann_bronzebeard_keystone() : CreatureScript("npc_brann_bronzebeard_keystone") { }
+
+ struct npc_brann_bronzebeard_keystoneAI : public ScriptedAI
+ {
+ npc_brann_bronzebeard_keystoneAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ memset(&objectGUID, 0, sizeof(objectGUID));
+ playerGUID = 0;
+ voiceGUID = 0;
+ objectCounter = 0;
+ }
+
+ void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) OVERRIDE
+ {
+ player->CLOSE_GOSSIP_MENU();
+ playerGUID = player->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_1, 100);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SCRIPT_1:
+ Talk(SAY_BRANN_1, playerGUID);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER);
+ if (Creature* voice = me->SummonCreature(NPC_A_DISTANT_VOICE, 7863.43f, -1396.585f, 1538.076f, 2.949606f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 49000))
+ voiceGUID = voice->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_2, 4000);
+ break;
+ case EVENT_SCRIPT_2:
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(0, 7861.488f, -1396.376f, 1534.059f, false);
+ events.ScheduleEvent(EVENT_SCRIPT_3, 6000);
+ break;
+ case EVENT_SCRIPT_3:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_WORK_MINING);
+ events.ScheduleEvent(EVENT_SCRIPT_4, 6000);
+ break;
+ case EVENT_SCRIPT_4:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID))
+ {
+ voice->AI()->DoCast(voice, SPELL_RESURRECTION);
+ voice->AI()->Talk(SAY_VOICE_1, playerGUID);
+ }
+ if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_1, 7860.273f, -1383.622f, 1538.302f, -1.658062f, 0, 0, -0.737277f, 0.6755905f, 0))
+ objectGUID[objectCounter++] = go->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_5, 6000);
+ break;
+ case EVENT_SCRIPT_5:
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID))
+ voice->AI()->Talk(SAY_VOICE_2, playerGUID);
+ if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_2, 7875.67f, -1387.266f, 1538.323f, -2.373644f, 0, 0, -0.9271832f, 0.3746083f, 0))
+ objectGUID[objectCounter++] = go->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_6, 6000);
+ break;
+ case EVENT_SCRIPT_6:
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID))
+ voice->AI()->Talk(SAY_VOICE_3, playerGUID);
+ if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_3, 7879.212f, -1401.175f, 1538.279f, 2.967041f, 0, 0, 0.9961939f, 0.08716504f, 0))
+ objectGUID[objectCounter++] = go->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_7, 6000);
+ break;
+ case EVENT_SCRIPT_7:
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID))
+ voice->AI()->Talk(SAY_VOICE_4, playerGUID);
+ if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_4, 7868.944f, -1411.18f, 1538.213f, 2.111848f, 0, 0, 0.8703556f, 0.4924237f, 0))
+ objectGUID[objectCounter++] = go->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_8, 6000);
+ break;
+ case EVENT_SCRIPT_8:
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID))
+ voice->AI()->Talk(SAY_VOICE_5, playerGUID);
+ if (GameObject* go = me->SummonGameObject(OBJECT_TOL_SIGNAL_5, 7855.11f, -1406.839f, 1538.42f, 1.151916f, 0, 0, 0.5446386f, 0.8386708f, 0))
+ objectGUID[objectCounter] = go->GetGUID();
+ events.ScheduleEvent(EVENT_SCRIPT_9, 6000);
+ break;
+ case EVENT_SCRIPT_9:
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, voiceGUID))
+ voice->AI()->DoCast(voice, SPELL_RESURRECTION);
+ events.ScheduleEvent(EVENT_SCRIPT_10, 6000);
+ break;
+ case EVENT_SCRIPT_10:
+ Talk(SAY_BRANN_2, playerGUID);
+ if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
+ player->KilledMonsterCredit(me->GetEntry());
+ events.ScheduleEvent(EVENT_SCRIPT_11, 6000);
+ break;
+ case EVENT_SCRIPT_11:
+ me->SetFacingTo(2.932153f);
+ Talk(SAY_BRANN_3, playerGUID);
+
+ for (uint8 i = 0; i < 5; ++i)
+ if (GameObject* go = ObjectAccessor::GetGameObject(*me, objectGUID[i]))
+ go->Delete();
+
+ events.ScheduleEvent(EVENT_SCRIPT_12, 6000);
+ break;
+ case EVENT_SCRIPT_12:
+ me->GetMotionMaster()->Clear();
+ me->SetWalk(false);
+ me->GetMotionMaster()->MovePoint(0, 7799.908f, -1413.561f, 1534.829f, false);
+ events.ScheduleEvent(EVENT_SCRIPT_13, 10000);
+ break;
+ case EVENT_SCRIPT_13:
+ me->DisappearAndDie();
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ uint64 playerGUID;
+ uint64 objectGUID[5];
+ uint64 voiceGUID;
+ uint8 objectCounter;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_brann_bronzebeard_keystoneAI(creature);
+ }
+};
+
enum CloseRift
{
SPELL_DESPAWN_RIFT = 61665
@@ -460,6 +635,91 @@ class spell_close_rift : public SpellScriptLoader
}
};
+/*#####
+# Krolmir, Hammer of Storms
+#####*/
+
+enum JokkumScriptcast
+{
+ SPELL_JOKKUM_KILL_CREDIT = 56545,
+ SPELL_JOKKUM_SUMMON = 56541,
+ NPC_KINGJOKKUM = 30331,
+ SAY_HOLD_ON = 0,
+ PATH_JOKKUM = 2072200
+};
+
+class spell_jokkum_scriptcast : public SpellScriptLoader
+{
+ public: spell_jokkum_scriptcast() : SpellScriptLoader("spell_jokkum_scriptcast") { }
+
+ class spell_jokkum_scriptcast_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_jokkum_scriptcast_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_JOKKUM_SUMMON))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ target->CastSpell(target, SPELL_JOKKUM_SUMMON, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_jokkum_scriptcast_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_jokkum_scriptcast_AuraScript();
+ }
+};
+
+class npc_king_jokkum_vehicle : public CreatureScript
+{
+ public:
+ npc_king_jokkum_vehicle() : CreatureScript("npc_king_jokkum_vehicle") { }
+
+ struct npc_king_jokkum_vehicleAI : public VehicleAI
+ {
+ npc_king_jokkum_vehicleAI(Creature* creature) : VehicleAI(creature) { }
+
+ void OnCharmed(bool /*apply*/) OVERRIDE { }
+
+ void PassengerBoarded(Unit* who, int8 /*seat*/, bool apply) OVERRIDE
+ {
+ if (apply)
+ {
+ Talk(SAY_HOLD_ON, who->GetGUID());
+ me->CastSpell(who, SPELL_JOKKUM_KILL_CREDIT, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
+ me->GetMotionMaster()->MovePath(PATH_JOKKUM, false);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id) OVERRIDE
+ {
+ if (type != WAYPOINT_MOTION_TYPE)
+ return;
+
+ // PointId in WaypointMovementGenerator doesn't match with PointId in DB
+ if (id == 19)
+ me->GetVehicleKit()->RemoveAllPassengers();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_king_jokkum_vehicleAI(creature);
+ }
+};
+
void AddSC_storm_peaks()
{
new npc_injured_goblin();
@@ -468,5 +728,8 @@ void AddSC_storm_peaks()
new npc_freed_protodrake();
new npc_icefang();
new npc_hyldsmeet_protodrake();
+ new npc_brann_bronzebeard_keystone();
new spell_close_rift();
+ new spell_jokkum_scriptcast();
+ new npc_king_jokkum_vehicle();
}
diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp
index 66415448d32..1137c86f287 100644
--- a/src/server/scripts/Northrend/zone_zuldrak.cpp
+++ b/src/server/scripts/Northrend/zone_zuldrak.cpp
@@ -57,16 +57,15 @@ public:
float x, y, z;
me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 0.1f);
- if (Unit* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000))
+ if (Creature* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z, 0, TEMPSUMMON_DEAD_DESPAWN, 1000))
{
_rageclawGUID = summon->GetGUID();
- LockRageclaw();
+ LockRageclaw(summon);
}
}
- void LockRageclaw()
+ void LockRageclaw(Creature* rageclaw)
{
- Unit* rageclaw = Unit::GetCreature(*me, _rageclawGUID);
// pointer check not needed
me->SetInFront(rageclaw);
rageclaw->SetInFront(me);
@@ -75,12 +74,11 @@ public:
DoCast(rageclaw, SPELL_RIGHT_CHAIN, true);
}
- void UnlockRageclaw(Unit* who)
+ void UnlockRageclaw(Unit* who, Creature* rageclaw)
{
if (!who)
return;
- Creature* rageclaw = Unit::GetCreature(*me, _rageclawGUID);
// pointer check not needed
DoCast(rageclaw, SPELL_FREE_RAGECLAW, true);
@@ -95,7 +93,7 @@ public:
{
if (Creature* rageclaw = Unit::GetCreature(*me, _rageclawGUID))
{
- UnlockRageclaw(caster);
+ UnlockRageclaw(caster, rageclaw);
caster->ToPlayer()->KilledMonster(rageclaw->GetCreatureTemplate(), _rageclawGUID);
me->DespawnOrUnsummon();
}
@@ -141,8 +139,7 @@ public:
DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P
}
- void MoveInLineOfSight(Unit* /*who*/)OVERRIDE { }
-
+ void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
void SpellHit(Unit* /*caster*/, const SpellInfo* spell) OVERRIDE
{
@@ -166,982 +163,6 @@ public:
}
};
-/*####
-## npc_gurgthock
-####*/
-
-enum Gurgthock
-{
- QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON = 12935,
- QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER = 12936,
- QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2 = 12954,
- QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1 = 12932,
- QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR = 12933,
- QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND = 12934,
-
- NPC_ORINOKO_TUSKBREAKER = 30020,
- NPC_KORRAK_BLOODRAGER = 30023,
- NPC_YGGDRAS = 30014,
- NPC_STINKBEARD = 30017,
- NPC_AZ_BARIN = 30026, // air
- NPC_DUKE_SINGEN = 30019, // fire
- NPC_ERATHIUS = 30025, // earth
- NPC_GARGORAL = 30024, // water
- NPC_FIEND_WATER = 30044,
- NPC_FIEND_AIR = 30045,
- NPC_FIEND_FIRE = 30042,
- NPC_FIEND_EARTH = 30043,
-
- SAY_QUEST_ACCEPT_TUSKARRMAGEDON = 0,
- SAY_QUEST_ACCEPT_KORRAK_1 = 1,
- SAY_QUEST_ACCEPT_KORRAK_2 = 2,
- SAY_QUEST_ACCEPT_MAGNATAUR = 3,
- EMOTE_YGGDRAS_SPAWN = 4,
- SAY_STINKBEARD_SPAWN = 5,
- SAY_GURGTHOCK_ELEMENTAL_SPAWN = 6,
- SAY_GURGTHOCK_7 = 7,
- SAY_QUEST_AMPHITHEATER_ANGUISH_YGGDRAS = 8,
- SAY_GURGTHOCK_9 = 9,
-
- SAY_CALL_FOR_HELP = 0,
- SAY_RECRUIT = 0,
-
- SPELL_CRASHING_WAVE = 55909, // water
- SPELL_SHOCKWAVE = 55918, // earth
- SPELL_BLAST_OF_AIR = 55912, // air
- SPELL_MAGMA_WAVE = 55916, // fire
-
- SPELL_ORB_OF_WATER = 55888, // fiend of water spell
- SPELL_ORB_OF_STORMS = 55882, // fiend of air spell
- SPELL_BOULDER = 55886, // fiend of earth spell
- SPELL_ORB_OF_FLAME = 55872, // fiend of fire spell
-};
-
-struct BossAndAdd
-{
- uint32 uiBoss;
- uint32 uiAdd;
- uint32 uiSpell;
- uint32 uiAddSpell;
-};
-
-static BossAndAdd Boss[]=
-{
- {NPC_GARGORAL, NPC_FIEND_WATER, SPELL_CRASHING_WAVE, SPELL_ORB_OF_WATER},
- {NPC_AZ_BARIN, NPC_FIEND_AIR, SPELL_BLAST_OF_AIR, SPELL_ORB_OF_STORMS},
- {NPC_DUKE_SINGEN, NPC_FIEND_FIRE, SPELL_MAGMA_WAVE, SPELL_ORB_OF_FLAME},
- {NPC_ERATHIUS, NPC_FIEND_EARTH, SPELL_SHOCKWAVE, SPELL_BOULDER},
-};
-
-const Position SpawnPosition[] =
-{
- {5754.692f, -2939.46f, 286.276123f, 5.156380f}, // stinkbeard || orinoko || korrak
- {5762.054199f, -2954.385010f, 273.826955f, 5.108289f}, //yggdras
- {5776.855f, -2989.77979f, 272.96814f, 5.194f} // elementals
-};
-
-const Position AddSpawnPosition[] =
-{
- {5722.487f, -3010.75f, 312.751648f, 0.478f}, // caster location
- {5724.983f, -2969.89551f, 286.359619f, 0.478f},
- {5733.76025f, -3000.34644f, 286.359619f, 0.478f},
- {5739.8125f, -2981.524f, 290.7671f, 0.478f}, // caster location
- {5742.101f, -2950.75586f, 286.2643f, 5.21f},
- {5743.305f, -3011.29736f, 290.7671f, 0.478f}, // caster location
- {5744.417f, -3025.528f, 286.35965f, 0.478f},
- {5763.189f, -3029.67529f, 290.7671f, 0.478f},
- {5769.401f, -2935.121f, 286.335754f, 5.21f},
- {5793.061f, -2934.593f, 286.359619f, 3.53f},
- {5797.32129f, -2955.26855f, 290.7671f, 3.53f}, // caster location
- {5813.94531f, -2956.74683f, 286.359619f, 3.53f},
- {5816.85547f, -2974.476f, 290.7671f, 3.53f}, // caster location
- {5820.30859f, -3002.83716f, 290.7671f, 3.53f}, // caster location
- {5828.50244f, -2981.737f, 286.359619f, 3.53f},
- {5828.899f, -2960.15479f, 312.751648f, 3.53f}, // caster location
-};
-
-class npc_gurgthock : public CreatureScript
-{
-public:
- npc_gurgthock() : CreatureScript("npc_gurgthock") { }
-
- struct npc_gurgthockAI : public ScriptedAI
- {
- npc_gurgthockAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE
- {
- _summonGUID = 0;
- _playerGUID = 0;
-
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
- uiTimer = 0;
- uiPhase = 0;
- uiQuest = 0;
- uiRemoveFlagTimer = 5000;
-
- _bossRandom = 0;
-
- _removeFlag = false;
- }
-
- void SetGUID(uint64 guid, int32 /*id*/) OVERRIDE
- {
- _playerGUID = guid;
- }
-
- void SetData(uint32 type, uint32 data) OVERRIDE
- {
- _removeFlag = true;
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
-
- switch (type)
- {
- case 1:
- switch (data)
- {
- case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON:
- Talk(SAY_QUEST_ACCEPT_TUSKARRMAGEDON);
- uiPhase = 1;
- uiTimer = 4000;
- break;
- case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER:
- Talk(SAY_QUEST_ACCEPT_KORRAK_1);
- uiPhase = 3;
- uiTimer = 3000;
- break;
- case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2:
- case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1:
- uiPhase = 6;
- uiTimer = 3000;
- break;
- case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR:
- uiTimer = 5000;
- uiPhase = 7;
- break;
- case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND:
- uiTimer = 2000;
- uiPhase = 12;
- break;
- }
- break;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- ScriptedAI::UpdateAI(diff);
-
- if (_removeFlag)
- {
- if (uiRemoveFlagTimer <= diff)
- {
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
- _removeFlag = false;
-
- uiRemoveFlagTimer = 10000;
- } else uiRemoveFlagTimer -= diff;
- }
-
- if (uiPhase)
- {
- if (uiTimer <= diff)
- {
- switch (uiPhase)
- {
- case 1:
- if (Creature* summon = me->SummonCreature(NPC_ORINOKO_TUSKBREAKER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000))
- _summonGUID = summon->GetGUID();
- uiPhase = 2;
- uiTimer = 4000;
- break;
- case 2:
- if (Creature* summon = Unit::GetCreature(*me, _summonGUID))
- summon->GetMotionMaster()->MoveJump(5776.319824f, -2981.005371f, 273.100037f, 10.0f, 20.0f);
- uiPhase = 0;
- _summonGUID = 0;
- break;
- case 3:
- Talk(SAY_QUEST_ACCEPT_KORRAK_2);
- uiTimer = 3000;
- uiPhase = 4;
- break;
- case 4:
- if (Creature* summon = me->SummonCreature(NPC_KORRAK_BLOODRAGER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000))
- _summonGUID = summon->GetGUID();
- uiTimer = 3000;
- uiPhase = 0;
- break;
- case 6:
- Talk(SAY_GURGTHOCK_7, _playerGUID);
- uiTimer = 5000;
- uiPhase = 9;
- break;
- case 7:
- Talk(SAY_GURGTHOCK_9, _playerGUID);
- uiTimer = 3000;
- uiPhase = 8;
- break;
- case 8:
- Talk(SAY_QUEST_ACCEPT_MAGNATAUR);
- uiTimer = 5000;
- uiPhase = 11;
- break;
- case 9:
- Talk(SAY_QUEST_AMPHITHEATER_ANGUISH_YGGDRAS, _playerGUID);
- uiTimer = 10000;
- uiPhase = 10;
- break;
- case 10:
- me->SummonCreature(NPC_YGGDRAS, SpawnPosition[1], TEMPSUMMON_CORPSE_DESPAWN, 1000);
- Talk(EMOTE_YGGDRAS_SPAWN);
- uiPhase = 0;
- break;
- case 11:
- if (Creature* creature = me->SummonCreature(NPC_STINKBEARD, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000))
- creature->AI()->Talk(SAY_STINKBEARD_SPAWN);
- uiPhase = 0;
- break;
- case 12:
- Talk(SAY_GURGTHOCK_9, _playerGUID);
- uiTimer = 5000;
- uiPhase = 13;
- break;
- case 13:
- Talk(SAY_GURGTHOCK_ELEMENTAL_SPAWN);
- uiTimer = 3000;
- uiPhase = 14;
- break;
- case 14:
- _bossRandom = urand(0, 3);
- if (Creature* creature = me->SummonCreature(Boss[_bossRandom].uiBoss, SpawnPosition[2], TEMPSUMMON_CORPSE_DESPAWN, 1000))
- creature->AI()->SetData(1, _bossRandom);
- uiPhase = 0;
- break;
- }
- }
- else
- uiTimer -= diff;
- }
- }
-
- private:
- bool _removeFlag;
- uint8 _bossRandom;
- uint64 _summonGUID;
- uint64 _playerGUID;
-
- uint32 uiTimer;
- uint32 uiPhase;
- uint32 uiRemoveFlagTimer;
- uint32 uiQuest;
-
- };
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- switch (quest->GetQuestId())
- {
- case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON:
- creature->AI()->SetData(1, quest->GetQuestId());
- break;
- case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER:
- creature->AI()->SetData(1, quest->GetQuestId());
- break;
- case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2:
- case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1:
- creature->AI()->SetData(1, quest->GetQuestId());
- break;
- case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR:
- creature->AI()->SetData(1, quest->GetQuestId());
- break;
- case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND:
- creature->AI()->SetData(1, quest->GetQuestId());
- break;
- }
-
- creature->AI()->SetGUID(player->GetGUID());
-
- return false;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_gurgthockAI(creature);
- }
-};
-
-/*####
-## npc_orinoko_tuskbreaker
-####*/
-
-enum OrinokoTuskbreaker
-{
- NPC_WHISKER = 30113,
- NPC_HUNGRY_PENGUIN = 30110,
-
- SPELL_BATTLE_SHOUT = 32064,
- SPELL_FISHY_SCENT = 55937,
- SPELL_IMPALE = 55929,
- SPELL_SUMMON_WHISKER = 55946
-};
-
-class npc_orinoko_tuskbreaker : public CreatureScript
-{
-public:
- npc_orinoko_tuskbreaker() : CreatureScript("npc_orinoko_tuskbreaker") { }
-
- struct npc_orinoko_tuskbreakerAI : public ScriptedAI
- {
- npc_orinoko_tuskbreakerAI(Creature* creature) : ScriptedAI(creature)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_PASSIVE);
- }
-
- void Reset() OVERRIDE
- {
- _summoned = false;
- _battleShout = false;
- _fishyScent = false;
- uiBattleShoutTimer = 0;
- uiFishyScentTimer = 20000;
- _whiskerGUID = 0;
- _affectedGUID = 0;
- }
-
- void EnterEvadeMode() OVERRIDE
- {
- if (Creature* whisker = me->GetCreature(*me, _whiskerGUID))
- whisker->RemoveFromWorld();
- }
-
- void MovementInform(uint32 type, uint32 /*pointId*/) OVERRIDE
- {
- if (type != EFFECT_MOTION_TYPE)
- return;
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
- uiBattleShoutTimer = 7000;
- }
-
- void EnterCombat(Unit* who) OVERRIDE
- {
- DoCast(who, SPELL_IMPALE);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (!_battleShout && uiBattleShoutTimer <= diff)
- {
- DoCast(me, SPELL_BATTLE_SHOUT);
- _battleShout = true;
- } else uiBattleShoutTimer -= diff;
-
- if (uiFishyScentTimer <= diff)
- {
- if (Unit* affected = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoCast(affected, SPELL_FISHY_SCENT);
- _affectedGUID = affected->GetGUID();
- }
- uiFishyScentTimer = 20000;
- } else uiFishyScentTimer -= diff;
-
- if (!_summoned && !HealthAbovePct(50))
- {
- Talk(SAY_CALL_FOR_HELP);
- //DoCastVictim(SPELL_SUMMON_WHISKER); petai is not working correctly???
-
- if (Creature* whisker = me->SummonCreature(NPC_WHISKER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0))
- _whiskerGUID = whisker->GetGUID();
- _summoned = true;
- }
-
- DoMeleeAttackIfReady();
- }
-
- void JustSummoned(Creature* summon) OVERRIDE
- {
- switch (summon->GetEntry())
- {
- case NPC_WHISKER:
- summon->AI()->AttackStart(me->GetVictim());
- break;
- case NPC_HUNGRY_PENGUIN:
- if (Unit* affected = Unit::GetUnit(*me, _affectedGUID))
- {
- if (affected->IsAlive())
- summon->AI()->AttackStart(affected);
- }
- break;
- }
- }
-
- void JustDied(Unit* killer) OVERRIDE
- {
- if (_whiskerGUID)
- if (Creature* whisker = me->GetCreature(*me, _whiskerGUID))
- whisker->RemoveFromWorld();
-
- if (killer->GetTypeId() == TYPEID_PLAYER)
- killer->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON, killer);
-
- }
-
- private:
- bool _summoned;
- bool _battleShout;
- bool _fishyScent;
- uint32 uiBattleShoutTimer;
- uint32 uiFishyScentTimer;
- uint64 _affectedGUID;
- uint64 _whiskerGUID;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_orinoko_tuskbreakerAI(creature);
- }
-};
-
-/*####
-## npc_korrak_bloodrager
-####*/
-
-enum KorrakBloodrager
-{
- SPELL_GROW = 55948,
- SPELL_CHARGE = 24193,
- SPELL_UPPERCUT = 30471,
- SPELL_ENRAGE = 42745
-};
-
-class npc_korrak_bloodrager : public CreatureScript
-{
-public:
- npc_korrak_bloodrager() : CreatureScript("npc_korrak_bloodrager") { }
-
- struct npc_korrak_bloodragerAI : public npc_escortAI
- {
- npc_korrak_bloodragerAI(Creature* creature) : npc_escortAI(creature)
- {
- Start(true, true, 0, NULL);
- SetDespawnAtEnd(false);
- }
-
- void Reset() OVERRIDE
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_PASSIVE);
- _enrage = false;
- _chargeTimer = 15000;
- _uppercutTimer = 12000;
-
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 6:
- me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_AGGRESSIVE);
- break;
- }
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- DoCast(me, SPELL_GROW);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- npc_escortAI::UpdateAI(diff);
-
- if (!UpdateVictim())
- return;
-
- if (_uppercutTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0))
- DoCast(target, SPELL_UPPERCUT);
- _uppercutTimer = 12000;
- } else _uppercutTimer -= diff;
-
- if (_chargeTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0))
- DoCast(target, SPELL_CHARGE);
- _chargeTimer = 15000;
- } else _chargeTimer -= diff;
-
- if (!_enrage && !HealthAbovePct(20))
- {
- DoCast(me, SPELL_ENRAGE);
- _enrage = true;
- }
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* killer) OVERRIDE
- {
- if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER, killer);
- }
- private:
- bool _enrage;
- uint32 _chargeTimer;
- uint32 _uppercutTimer;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_korrak_bloodragerAI(creature);
- }
-};
-
-/*####
-## npc_yggdras
-####*/
-
-enum Yggdras
-{
- SPELL_CLEAVE = 40504,
- SPELL_CORRODE_FLESH = 57076,
- SPELL_JORMUNGAR_SPAWN = 55859
-};
-
-class npc_yggdras : public CreatureScript
-{
-public:
- npc_yggdras() : CreatureScript("npc_yggdras") { }
-
- struct npc_yggdrasAI : public ScriptedAI
- {
- npc_yggdrasAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE
- {
- _cleaveTimer = 9000;
- _corrodeFleshTimer = 6000;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (me->GetVictim()->GetPositionZ() >= 286.276f)
- {
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
- {
- if (unit->GetPositionZ() <= 286.276f)
- {
- me->getThreatManager().resetAllAggro();
- me->AddThreat(unit, 5.0f);
- break;
- }
- EnterEvadeMode();
- }
- }
- }
-
- if (_cleaveTimer <= diff)
- {
- DoCastVictim(SPELL_CLEAVE);
- _cleaveTimer = 9000;
- } else _cleaveTimer -= diff;
-
- if (_corrodeFleshTimer <= diff)
- {
- DoCastVictim(SPELL_CORRODE_FLESH);
- _corrodeFleshTimer = 6000;
- } else _corrodeFleshTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* killer) OVERRIDE
- {
- if (Unit* summoner = me->ToTempSummon()->GetSummoner())
- {
- std::string sText = (std::string(killer->GetName()) + " has defeated Yg.. Yggg-really big worm!");
- summoner->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0);
- }
-
- if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- {
- player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1, killer);
- player->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2, killer);
- }
-
- for (uint8 i = 0; i < 3; ++i)
- DoCast(killer, SPELL_JORMUNGAR_SPAWN, true);
- }
- private:
- uint32 _cleaveTimer;
- uint32 _corrodeFleshTimer;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_yggdrasAI(creature);
- }
-};
-
-/*####
-## npc_stinkbeard
-####*/
-
-enum Stinkbeard
-{
- SPELL_ENRAGE_STINKBEARD = 50420,
- SPELL_KNOCK_AWAY = 31389,
- SPELL_STINKY_BEARD = 55867,
- SPELL_THUNDERBLADE = 55866,
- SPELL_THUNDERCLAP = 15588
-};
-
-class npc_stinkbeard : public CreatureScript
-{
-public:
- npc_stinkbeard() : CreatureScript("npc_stinkbeard") { }
-
- struct npc_stinkbeardAI : public npc_escortAI
- {
- npc_stinkbeardAI(Creature* creature) : npc_escortAI(creature)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_PASSIVE);
- Start(true, true, 0, NULL);
- SetDespawnAtEnd(false);
- }
-
- void Reset() OVERRIDE
- {
- me->AddAura(SPELL_THUNDERBLADE, me);
- uiKnockAwayTimer = 10000;
- uiStinkyBeardTimer = 15000;
- _enrage = false;
- _thunderClap = false;
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 7:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
- break;
- }
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- npc_escortAI::UpdateAI(uiDiff);
-
- if (!UpdateVictim())
- return;
-
- if (Unit* victim = me->GetVictim())
- {
- if (victim->GetPositionZ() >= 286.276f)
- {
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
- {
- if (unit->GetPositionZ() <= 286.276f)
- {
- me->getThreatManager().resetAllAggro();
- me->AddThreat(unit, 5.0f);
- break;
- }
- EnterEvadeMode();
- }
- }
- }
- }
-
- if (_thunderClap && !HealthAbovePct(10))
- {
- DoCastAOE(SPELL_THUNDERCLAP);
- _thunderClap = true;
- }
-
- if (uiKnockAwayTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- if (target && target->IsAlive())
- DoCast(target, SPELL_KNOCK_AWAY);
- }
- uiKnockAwayTimer = 10000;
- } else uiKnockAwayTimer -= uiDiff;
-
- if (uiStinkyBeardTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- if (target && target->IsAlive())
- DoCast(target, SPELL_STINKY_BEARD);
- }
- uiStinkyBeardTimer = 15000;
- } else uiStinkyBeardTimer -= uiDiff;
-
- if (!_enrage && !HealthAbovePct(20))
- {
- DoCast(me, SPELL_ENRAGE_STINKBEARD);
- _enrage = true;
- }
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* killer) OVERRIDE
- {
- if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- player->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR, killer);
-
- std::string sText = ("And with AUTHORITY, " + std::string(killer->GetName()) + " dominates the magnataur lord! Stinkbeard's clan is gonna miss him back home in the Dragonblight!");
- me->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0);
- }
- private:
- bool _enrage;
- bool _thunderClap;
- uint32 uiKnockAwayTimer;
- uint32 uiStinkyBeardTimer;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_stinkbeardAI(creature);
- }
-};
-
-/*####
-## npc_elemental_lord
-####*/
-
-class npc_elemental_lord : public CreatureScript
-{
-public:
- npc_elemental_lord() : CreatureScript("npc_elemental_lord") { }
-
- struct npc_elemental_lordAI : public ScriptedAI
- {
- npc_elemental_lordAI(Creature* creature) : ScriptedAI(creature) { }
-
- std::list<uint64> SummonList;
-
- uint32 uiElementalSpellTimer;
-
- uint8 uiBossRandom;
- uint32 uiSpellInfo;
-
- bool bAddAttack;
-
- void Reset() OVERRIDE
- {
- uiBossRandom = 0;
- uiSpellInfo = 0;
- uiElementalSpellTimer = urand(5000, 8000);
-
- bAddAttack = false;
- }
-
- void SetData(uint32 uiData, uint32 uiValue) OVERRIDE
- {
- if (uiData == 1)
- {
- uiBossRandom = uiValue;
- SummonAdds();
- }
- }
-
- void SummonAdds()
- {
- if (!Boss[uiBossRandom].uiAdd)
- return;
-
- SummonList.clear();
-
- for (uint8 uiI = 0; uiI < 16; uiI++)
- {
- if (Creature* summon = me->SummonCreature(Boss[uiBossRandom].uiAdd, AddSpawnPosition[uiI]))
- {
- summon->AI()->SetData(1, uiBossRandom);
- SummonList.push_back(summon->GetGUID());
- }
- }
-
- }
-
- void EnterCombat(Unit* unit) OVERRIDE
- {
- if (!SummonList.empty())
- for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
- {
- if (Creature* temp = Unit::GetCreature(*me, *itr))
- {
- temp->m_CombatDistance = 100.0f; // ugly hack? we are not in a instance sorry. :(
- temp->AI()->AttackStart(unit);
- }
- }
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (me->GetVictim()->GetPositionZ() >= 286.276f)
- {
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- if (Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
- {
- if (unit->GetPositionZ() <= 286.276f)
- {
- me->getThreatManager().resetAllAggro();
- me->AddThreat(unit, 5.0f);
- break;
- }
- EnterEvadeMode();
- }
- }
- }
-
- if (uiElementalSpellTimer <= uiDiff)
- {
- DoCastVictim(Boss[uiBossRandom].uiSpell);
-
- uiElementalSpellTimer = urand(5000, 8000);
- } else uiElementalSpellTimer -= uiDiff;
-
- if (!bAddAttack && !HealthAbovePct(20))
- {
- if (!SummonList.empty())
- for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
- {
- if (Creature* temp = Unit::GetCreature(*me, *itr))
- {
- if (temp->GetPositionZ() >= 287.00f)
- continue;
-
- if (temp->GetVictim())
- temp->GetMotionMaster()->MoveChase(temp->GetVictim());
- }
- }
-
- bAddAttack = true;
- }
-
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* killer) OVERRIDE
- {
- if (!SummonList.empty())
- for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
- if (Creature* temp = Unit::GetCreature(*me, *itr))
- temp->DespawnOrUnsummon();
-
- if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
- player->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND, killer);
-
- std::string sText = (std::string(killer->GetName()) + " is victorious once more!");
-
- if (Unit* summoner = me->ToTempSummon()->GetSummoner())
- summoner->MonsterYell(sText.c_str(), LANG_UNIVERSAL, 0);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_elemental_lordAI(creature);
- }
-};
-
-/*####
-## npc_fiend_elemental
-####*/
-
-class npc_fiend_elemental : public CreatureScript
-{
-public:
- npc_fiend_elemental() : CreatureScript("npc_fiend_elemental") { }
-
- struct npc_fiend_elementalAI : public ScriptedAI
- {
- npc_fiend_elementalAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE
- {
- if (me->GetPositionZ() >= 287.0f)
- me->GetMotionMaster()->MoveIdle();
-
- _spell = 0;
- _missleTimer = urand(2000, 7000);
- }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!who)
- return;
-
- AttackStartNoMove(who);
- }
-
- void SetData(uint32 Data, uint32 Value) OVERRIDE
- {
- if (Data == 1)
- _spell = Boss[Value].uiAddSpell;
-
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (me->GetPositionZ() >= 287.0f)
- {
- if (_missleTimer <= diff)
- {
- if (_spell) // Sometimes it is 0, why?
- DoCast(me, _spell); // this spell (what spell) is not supported ... YET!
- _missleTimer = urand(2000, 7000);
- } else _missleTimer -= diff;
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- uint32 _missleTimer;
- uint32 _spell;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_fiend_elementalAI(creature);
- }
-};
/*####
## npc_released_offspring_harkoa
@@ -1184,7 +205,8 @@ public:
enum CrusadeRecruit
{
SPELL_QUEST_CREDIT = 50633,
- QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE = 12509
+ QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE = 12509,
+ SAY_RECRUIT = 0
};
enum CrusadeRecruitEvents
@@ -1435,6 +457,8 @@ public:
void Reset() OVERRIDE
{
+ _playerGUID = 0;
+ _getingredienttry = 0;
_events.ScheduleEvent(EVENT_TURN_TO_POT, urand(15000, 26000));
}
@@ -1867,15 +891,8 @@ void AddSC_zuldrak()
{
new npc_drakuru_shackles();
new npc_captured_rageclaw();
- new npc_gurgthock();
- new npc_orinoko_tuskbreaker();
- new npc_korrak_bloodrager();
- new npc_yggdras();
- new npc_stinkbeard();
new npc_released_offspring_harkoa();
new npc_crusade_recruit();
- new npc_elemental_lord();
- new npc_fiend_elemental();
new go_scourge_enclosure();
new npc_alchemist_finklestein();
new go_finklesteins_cauldron();