aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortibbi <tibbi@centrum.sk>2012-11-19 00:42:25 +0000
committerNay <dnpd.dd@gmail.com>2012-11-19 00:42:25 +0000
commit1f9db80b69379f3abc4b2f8bb5dbc26ec971cc92 (patch)
treed1eba882ba9c99ea2ecceb250f1984427c4af00f
parentaea5fec30dd2b2f5d1709e11949913764dcdae35 (diff)
Scripts/ToC: Trial of the Crusader rewrite
Closes #8272 Closes #7013 Closes #7552 Closes #5561 Closes #4221 Closes #2701 Closes #2079 Closes #5082 Closes #6503 Closes #6784 Signed-off-by: Nay <dnpd.dd@gmail.com>
-rw-r--r--sql/updates/world/2012_11_18_02_world_toc.sql151
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp3
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp1011
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp3412
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp771
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp1529
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp624
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp340
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp677
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h48
10 files changed, 4707 insertions, 3859 deletions
diff --git a/sql/updates/world/2012_11_18_02_world_toc.sql b/sql/updates/world/2012_11_18_02_world_toc.sql
new file mode 100644
index 00000000000..b28a2f5cc64
--- /dev/null
+++ b/sql/updates/world/2012_11_18_02_world_toc.sql
@@ -0,0 +1,151 @@
+-- Trial of the Crusader Death knight Death grip scriptname
+DELETE FROM `spell_script_names` WHERE `spell_id` IN (66017, 68753, 68754, 68755);
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(66017, 'spell_faction_champion_death_grip'),
+(68753, 'spell_faction_champion_death_grip'),
+(68754, 'spell_faction_champion_death_grip'),
+(68755, 'spell_faction_champion_death_grip');
+
+-- Trial of the Crusader shaman heroism/bloodlust
+DELETE FROM `spell_script_names` WHERE `spell_id` IN (65983, 65980);
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(65983, 'spell_toc_heroism'),
+(65980, 'spell_toc_bloodlust');
+
+-- impale scriptname
+DELETE FROM `spell_script_names` WHERE `spell_id`=65919;
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(65919, 'spell_impale');
+
+-- firebomb scriptname and modelid (ToC Gormok encounter)
+UPDATE `creature_template` SET `ScriptName`="npc_firebomb" WHERE `entry`=34854;
+
+-- frost sphere corrections
+UPDATE `creature_template` SET `minlevel`=80, `InhabitType`=4, `RegenHealth`=0 WHERE `entry` IN (34606, 34649);
+
+-- Dark / Light essence removing
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (-67222, -67223, -67224, -65686, -67176, -67177, -67178, -65684);
+INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(-67222, -67511, 0, 'Light Essence 25M'),
+(-67223, -67512, 0, 'Light Essence 10M H'),
+(-67224, -67513, 0, 'Light Essence 25M H'),
+(-65686, -65811, 0, 'Light Essence 10M'),
+(-67176, -67179, 0, 'Dark Essence 25M'),
+(-67177, -67180, 0, 'Dark Essence 10M H'),
+(-67178, -67181, 0, 'Dark Essence 25M H'),
+(-65684, -65827, 0, 'Dark Essence 10M');
+
+-- Gormoks Fire Bomb scriptname
+DELETE FROM `spell_script_names` WHERE `spell_id`=66313;
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(66313, 'spell_gormok_fire_bomb');
+
+-- correcting hitbox of Anub'Arak
+UPDATE `creature_model_info` SET `bounding_radius`=1.085, `combat_reach`=10.5 WHERE `modelid`=29268;
+
+-- correcting hitbox of Acidmaw
+UPDATE `creature_model_info` SET `bounding_radius`=1.24, `combat_reach`=12 WHERE `modelid`=29815;
+
+-- spawn the Anub'arak gate in all versions of the instance
+UPDATE `gameobject` SET `spawnMask`=15 WHERE `guid`=151192;
+
+-- adding ToC boss immunities
+UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask` | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 65536 | 131072 | 524288 | 4194304 | 8388608 | 67108864 | 536870912
+ WHERE `entry` IN (34796, 35438, 35439, 35440, 34799, 35514, 35515, 35516, 35144, 35511, 35512, 35513, 34797, 35447, 35448, 35449, 34780, 35216, 35268, 35269, 36066, 35347, 35348, 35349, 34497, 35350, 35351, 35352, 34564, 34566, 35615, 35616);
+
+-- adding Teleport locations to Trial of the Crusader/champion for GMs
+DELETE FROM `game_tele` WHERE `name` LIKE '%TrialOfTheCrusader%' OR `name` LIKE '%TrialOfTheChampion%';
+INSERT INTO `game_tele` (`position_x`, `position_y`, `position_z`, `orientation`, `map`, `name`) VALUES
+(8515.63, 714.174, 558.248, 1.57298, 571, 'TrialOfTheCrusader'),
+(8588.42, 791.888, 558.236, 3.23819, 571, 'TrialOfTheChampion');
+
+-- misc fixes for higher boss brackets
+UPDATE `creature_template` SET `dmg_multiplier`=70 WHERE `entry` IN (35440, 35513, 35516, 35449, 35269, 35352, 35349, 35616, 35664, 35670, 35673, 35676, 35682, 35685, 35688, 35691, 35694, 35697, 35701, 35704, 35707, 35710, 35713, 35716, 35720, 35723, 35726, 35730, 35733, 35736, 35739, 35742, 35745, 35748, 35749);
+UPDATE `creature_template` SET `flags_extra`=`flags_extra` | 1 WHERE `entry` IN (35438, 35439, 35440, 35511, 35512, 35513, 35514, 35515, 35516, 35662, 35663, 35664, 35665, 35666, 35667, 35668, 35669, 35670, 35671, 35672, 35673, 35674, 35675, 35676, 35680, 35681, 35682, 35683, 35684, 35685, 35686, 35687, 35688, 35689, 35690, 35691, 35692, 35693, 35694, 35695, 35696, 35697, 35699, 35700, 35701, 35702, 35703, 35704, 35705, 35706, 35707, 35708, 35709, 35710, 35711, 35712, 35713, 35714, 35715, 35716, 35718, 35719, 35720, 35721, 35722, 35723, 35724, 35725, 35726, 35728, 35729, 35730, 35731, 35732, 35733, 35734, 35735, 35736, 35737, 35738, 35739, 35740, 35741, 35742, 35743, 35744, 35745, 35746, 35747, 35748, 34442, 34443, 35749);
+UPDATE `creature_template` SET `speed_walk`=2.8, `speed_run`=1.71429 WHERE `entry` IN (35350, 35351, 35352, 35347, 35348, 35349);
+UPDATE `creature_template` SET `speed_walk`=2, `speed_run`=1.14286 WHERE `entry` IN (34566, 35615, 35616);
+UPDATE `creature_template` SET `skinloot`=34797 WHERE `entry` IN (35447, 35448, 35449);
+UPDATE `creature_template` SET `skinloot`=70214 WHERE `entry` IN (34566, 35615, 35616);
+UPDATE `creature_template` SET `mindmg`=388, `maxdmg`=583, `attackpower`=146 WHERE `entry` IN (35711, 35712, 35713);
+UPDATE `creature_template` SET `mindmg`=468, `maxdmg`=702, `attackpower`=175 WHERE `entry` IN (35699, 35700, 35701);
+UPDATE `creature_template` SET `dmg_multiplier`=35 WHERE `entry` IN (34472, 34454);
+UPDATE `creature_template` SET `unit_class`=1 WHERE `entry` IN (34461, 35743, 35744, 35745);
+
+-- adding Jaraxxus add immunities
+UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask` | 1024 | 2048 WHERE `entry` IN (34815, 35262, 35263, 35264, 34826, 35270, 35271, 35272);
+UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask` | 262144 WHERE `entry` IN (35263, 35264);
+-- adding Nether portal and Infernal volcano immunities to knockout/grip
+UPDATE `creature_template` SET `mechanic_immune_mask`=`mechanic_immune_mask` | 32 | 8192 WHERE `entry` IN (34825, 35278, 35279, 35280, 34813, 35265, 35266, 35267);
+
+-- cast Forbearance together with Divine shield (ToC Faction Champions paladin)
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=66010;
+INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(66010, 25771, 0, 'Divine Shield - Forbearance');
+
+-- make all Diminishing returns rules apply in faction champions
+UPDATE `creature_template` SET `flags_extra`=`flags_extra` | 1048576 WHERE `entry` IN
+(34445,35705,35706,35707,
+34459,35686,35687,35688,
+34447,35683,35684,35685,
+34455,35680,35681,35682,
+34453,35718,35719,35720,
+34458,35692,35693,35694,
+34454,35711,35712,35713,
+34448,35724,35725,35726,
+34441,34442,34443,35749,
+34450,35695,35696,35697,
+35610,35774,35775,35776,
+35465,36301,36302,36303,
+34451,35671,35672,35673,
+34449,35689,35690,35691,
+34444,35740,35741,35742,
+34456,35708,35709,35710,
+34460,35702,35703,35704,
+34461,35743,35744,35745,
+34463,35734,35735,35736,
+34465,35746,35747,35748,
+34466,35665,35666,35667,
+34467,35662,35663,35664,
+34468,35721,35722,35723,
+34469,35714,35715,35716,
+34470,35728,35729,35730,
+34473,35674,35675,35676,
+34474,35731,35732,35733,
+34475,35737,35738,35739,
+34471,35668,35669,35670,
+34472,35699,35700,35701);
+
+-- correcting faction champions dmg multipliers
+UPDATE `creature_template` SET `dmg_multiplier`=10.8 WHERE `entry` IN (34445,34459,34447,34455,34453,34458,34454,34448,34441,34450,35610,35465,34451,34449,34444,34456,34460,34461,34463,34465,34466,34467,34468,34469,34470,34473,34474,34475,34472, 34471);
+UPDATE `creature_template` SET `dmg_multiplier`=16.1 WHERE `entry` IN (35705,35706,35686,35687,35683,35684,35680,35681,35718,35719,35692,35693,35711,35712,35724,35725,34442,34443,35695,35696,35774,35775,36301,36302,35671,35672,35689,35690,35740,35741,35708,35709,35702,35703,35743,35744,35734,35735,35746,35747,35665,35666,35662,35663,35721,35722,35714,35715,35728,35729,35674,35675,35731,35732,35737,35738,35699,35700, 35668, 35669);
+UPDATE `creature_template` SET `dmg_multiplier`=21.5 WHERE `entry` IN (35707,35688,35685,35682,35720,35694,35713,35726,35749,35697,35776,36303,35673,35691,35742,35710,35704,35745,35736,35748,35667,35664,35723,35716,35730,35676,35733,35739,35701, 35670);
+
+-- ToC warlock pet db corrections
+UPDATE `creature_template` SET `minlevel`=80, `maxlevel`=80, `exp`=2, `faction_A`=16, `faction_H`=16, `mindmg`=417, `maxdmg`=582, `attackpower`=608, `unit_class`=2, `dynamicflags`=8, `minrangedmg`=341, `maxrangedmg`=506, `rangedattackpower`=80 WHERE `entry` IN (36301, 36302, 36303);
+UPDATE `creature_template` SET `faction_A`=16, `faction_H`=16, `difficulty_entry_1`=36301, `difficulty_entry_2`=36302, `difficulty_entry_3`=36303 WHERE `entry`=35465;
+UPDATE `creature_template` SET `name`="Zhaagrym (1)" WHERE `entry`=36301;
+
+-- Jaraxxus Mistress Kiss
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_mistress_kiss_area';
+INSERT INTO `spell_script_names` (spell_id, `ScriptName`) VALUES
+(66336, 'spell_mistress_kiss_area'),
+(67076, 'spell_mistress_kiss_area'),
+(67077, 'spell_mistress_kiss_area'),
+(67078, 'spell_mistress_kiss_area');
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_mistress_kiss';
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(66334, 'spell_mistress_kiss'),
+(67905, 'spell_mistress_kiss'),
+(67906, 'spell_mistress_kiss'),
+(67907, 'spell_mistress_kiss');
+
+-- Gormoks Rising anger targeting
+DELETE FROM `conditions` WHERE `SourceEntry`=66636;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `Comment`) VALUES
+(13, 1, 66636, 31, 3, 34796, 'Rising Anger');
+
+-- Twins loot correction
+UPDATE `creature_loot_template` SET `maxcount`=1 WHERE `entry`=34497 AND `mincountOrRef` IN (-34296, -34302);
+-- Anubarak loot correction
+UPDATE `creature_loot_template` SET `maxcount`=2 WHERE `entry`=34564 AND `mincountOrRef` IN (-34298, -34304);
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index f3317f3a424..1edb8eab103 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -81,6 +81,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto,
// Gnaw
else if (spellproto->Id == 47481)
return DIMINISHING_CONTROLLED_STUN;
+ // ToC Icehowl Arctic Breath
+ else if (spellproto->SpellVisual[0] == 14153)
+ return DIMINISHING_NONE;
break;
}
// Event spells
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index 0f33c3866dd..1108c6ffc85 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -16,25 +16,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: boss_anubarak_trial
-SD%Complete: ??%
-SDComment: based on /dev/rsa
-SDCategory:
-EndScriptData */
-
// Known bugs:
// Anubarak - underground phase partially not worked
// - tele after impale hit a permafrost doesn't work (the entire tele spell should be better)
-// Burrow - visual is vanishing
-// Burrower - Spider Frenzy not working as it should (frenzy not stacking)
// Scarab - Kill credit isn't crediting?
-// FrostSph - often they are casting Permafrost a little above the ground
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "trial_of_the_crusader.h"
-#include "Player.h"
+#include <limits>
enum Yells
{
@@ -48,7 +38,7 @@ enum Yells
SAY_KILL_PLAYER = 7,
SAY_DEATH = 8,
- EMOTE_SPIKE = 0,
+ EMOTE_SPIKE = 0
};
enum Summons
@@ -57,7 +47,7 @@ enum Summons
NPC_BURROW = 34862,
NPC_BURROWER = 34607,
NPC_SCARAB = 34605,
- NPC_SPIKE = 34660,
+ NPC_SPIKE = 34660
};
enum BossSpells
@@ -87,8 +77,9 @@ enum BossSpells
SPELL_EXPOSE_WEAKNESS = 67720, //Passive - Triggered
SPELL_SHADOW_STRIKE = 66134,
SPELL_SUBMERGE_EFFECT = 68394,
- SPELL_EMERGE_EFFECT = 65982,
SPELL_AWAKENED = 66311,
+ SPELL_EMERGE_EFFECT = 65982,
+
SPELL_PERSISTENT_DIRT = 68048,
SUMMON_SCARAB = NPC_SCARAB,
@@ -108,15 +99,15 @@ enum BossSpells
SPELL_SPIKE_SPEED2 = 65922,
SPELL_SPIKE_SPEED3 = 65923,
SPELL_SPIKE_FAIL = 66181,
- SPELL_SPIKE_TELE = 66170,
+ SPELL_SPIKE_TELE = 66170
};
#define SPELL_PERMAFROST_HELPER RAID_MODE<uint32>(66193, 67855, 67856, 67857)
enum SummonActions
{
- ACTION_SHADOW_STRIKE,
- ACTION_SCARAB_SUBMERGE,
+ ACTION_SHADOW_STRIKE = 0,
+ ACTION_SCARAB_SUBMERGE = 1
};
const Position SphereSpawn[6] =
@@ -134,446 +125,468 @@ enum MovementPoints
POINT_FALL_GROUND = 1
};
-class boss_anubarak_trial : public CreatureScript
+enum PursuingSpikesPhases
{
-public:
- boss_anubarak_trial() : CreatureScript("boss_anubarak_trial") { }
+ PHASE_NO_MOVEMENT = 0,
+ PHASE_IMPALE_NORMAL = 1,
+ PHASE_IMPALE_MIDDLE = 2,
+ PHASE_IMPALE_FAST = 3
+};
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_anubarak_trialAI(creature);
- };
+enum Events
+{
+ // Anub'arak
+ EVENT_FREEZE_SLASH = 1,
+ EVENT_PENETRATING_COLD = 2,
+ EVENT_SUMMON_NERUBIAN = 3,
+ EVENT_NERUBIAN_SHADOW_STRIKE = 4,
+ EVENT_SUBMERGE = 5,
+ EVENT_EMERGE = 6,
+ EVENT_PURSUING_SPIKE = 7,
+ EVENT_SUMMON_SCARAB = 8,
+ EVENT_SUMMON_FROST_SPHERE = 9,
+ EVENT_BERSERK = 10
+};
- struct boss_anubarak_trialAI : public ScriptedAI
- {
- boss_anubarak_trialAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- instance = creature->GetInstanceScript();
- }
+enum Phases
+{
+ // Anub'arak
+ PHASE_MELEE = 1,
+ PHASE_SUBMERGED = 2,
- InstanceScript* instance;
-
- SummonList Summons;
- std::list<uint64> m_vBurrowGUID;
- uint64 m_aSphereGUID[6];
-
- uint32 m_uiFreezeSlashTimer;
- uint32 m_uiPenetratingColdTimer;
- uint32 m_uiSummonNerubianTimer;
- uint32 m_uiNerubianShadowStrikeTimer;
- uint32 m_uiSubmergeTimer;
- uint32 m_uiPursuingSpikeTimer;
- uint32 m_uiSummonScarabTimer;
- uint32 m_uiSummonFrostSphereTimer;
- uint32 m_uiBerserkTimer;
-
- uint8 m_uiStage;
- bool m_bIntro;
- bool m_bReachedPhase3;
- uint64 m_uiTargetGUID;
- uint8 m_uiScarabSummoned;
-
- void Reset()
- {
- m_uiFreezeSlashTimer = 15*IN_MILLISECONDS;
- m_uiPenetratingColdTimer = 20*IN_MILLISECONDS;
- m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
- m_uiSummonNerubianTimer = 10*IN_MILLISECONDS;
- m_uiSubmergeTimer = 80*IN_MILLISECONDS;
-
- m_uiPursuingSpikeTimer = 2*IN_MILLISECONDS;
- m_uiSummonScarabTimer = 2*IN_MILLISECONDS;
-
- m_uiSummonFrostSphereTimer = 20*IN_MILLISECONDS;
-
- m_uiBerserkTimer = 10*MINUTE*IN_MILLISECONDS;
- m_uiStage = 0;
- m_uiScarabSummoned = 0;
- m_bIntro = true;
- m_bReachedPhase3 = false;
- m_uiTargetGUID = 0;
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- Summons.DespawnAll();
- m_vBurrowGUID.clear();
- }
+ PHASE_MASK_MELEE = 1 << PHASE_MELEE
+};
- void KilledUnit(Unit* who)
+class boss_anubarak_trial : public CreatureScript
+{
+ public:
+ boss_anubarak_trial() : CreatureScript("boss_anubarak_trial") { }
+
+ struct boss_anubarak_trialAI : public BossAI
{
- if (who->GetTypeId() == TYPEID_PLAYER)
+ boss_anubarak_trialAI(Creature* creature) : BossAI(creature, BOSS_ANUBARAK)
{
- Talk(SAY_KILL_PLAYER);
- if (instance)
- instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
- }
- void MoveInLineOfSight(Unit* /*who*/)
- {
- if (!m_bIntro)
+ void Reset()
{
- Talk(SAY_INTRO);
- m_bIntro = false;
+ _Reset();
+ events.SetPhase(PHASE_MELEE);
+ events.ScheduleEvent(EVENT_FREEZE_SLASH, 15*IN_MILLISECONDS, 0, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_PENETRATING_COLD, 20*IN_MILLISECONDS, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_SUMMON_NERUBIAN, 10*IN_MILLISECONDS, 0, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_SUBMERGE, 80*IN_MILLISECONDS, 0, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_BERSERK, 10*MINUTE*IN_MILLISECONDS);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_NERUBIAN_SHADOW_STRIKE, 30*IN_MILLISECONDS, 0, PHASE_MELEE);
+
+ if (!IsHeroic())
+ events.ScheduleEvent(EVENT_SUMMON_FROST_SPHERE, 20*IN_MILLISECONDS);
+
+ _intro = true;
+ _reachedPhase3 = false;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ // clean up spawned Frost Spheres
+ std::list<Creature*> FrostSphereList;
+ me->GetCreatureListWithEntryInGrid(FrostSphereList, NPC_FROST_SPHERE, 150.0f);
+ if (!FrostSphereList.empty())
+ for (std::list<Creature*>::iterator itr = FrostSphereList.begin(); itr != FrostSphereList.end(); itr++)
+ (*itr)->DespawnOrUnsummon();
+
+ _burrowGUID.clear();
}
- }
- void JustReachedHome()
- {
- if (instance)
- instance->SetData(TYPE_ANUBARAK, FAIL);
- //Summon Scarab Swarms neutral at random places
- for (int i=0; i < 10; i++)
- if (Creature* temp = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ()))
+ void KilledUnit(Unit* who)
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER)
{
- temp->setFaction(31);
- temp->GetMotionMaster()->MoveRandom(10);
+ Talk(SAY_KILL_PLAYER);
+ if (instance)
+ instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
- }
-
- void JustDied(Unit* /*killer*/)
- {
- Summons.DespawnAll();
- Talk(SAY_DEATH);
- if (instance)
- instance->SetData(TYPE_ANUBARAK, DONE);
- }
-
- void JustSummoned(Creature* summoned)
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true);
- switch (summoned->GetEntry())
- {
- case NPC_BURROW:
- m_vBurrowGUID.push_back(summoned->GetGUID());
- summoned->SetReactState(REACT_PASSIVE);
- summoned->CastSpell(summoned, SPELL_CHURNING_GROUND, false);
- break;
- case NPC_SPIKE:
- summoned->CombatStart(target);
- Talk(EMOTE_SPIKE, target->GetGUID());
- break;
- }
- Summons.Summon(summoned);
- }
+ }
- void SummonedCreatureDespawn(Creature* summoned)
- {
- switch (summoned->GetEntry())
+ void MoveInLineOfSight(Unit* /*who*/)
{
- case NPC_SPIKE:
- m_uiPursuingSpikeTimer = 2*IN_MILLISECONDS;
- break;
+ if (!_intro)
+ {
+ Talk(SAY_INTRO);
+ _intro = false;
+ }
}
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- Talk(SAY_AGGRO);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetInCombatWithZone();
- if (instance)
- instance->SetData(TYPE_ANUBARAK, IN_PROGRESS);
- //Despawn Scarab Swarms neutral
- EntryCheckPredicate pred(NPC_SCARAB);
- Summons.DoAction(ACTION_SCARAB_SUBMERGE, pred);
- //Spawn Burrow
- for (int i=0; i < 4; i++)
- me->SummonCreature(NPC_BURROW, AnubarakLoc[i+2]);
- //Spawn Frost Spheres
- for (int i=0; i < 6; i++)
- if (Unit* summoned = me->SummonCreature(NPC_FROST_SPHERE, SphereSpawn[i]))
- m_aSphereGUID[i] = summoned->GetGUID();
- }
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
+ void JustReachedHome()
+ {
+ if (instance)
+ instance->SetBossState(BOSS_ANUBARAK, FAIL);
+ //Summon Scarab Swarms neutral at random places
+ for (int i = 0; i < 10; i++)
+ if (Creature* temp = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ()))
+ {
+ temp->setFaction(31);
+ temp->GetMotionMaster()->MoveRandom(10);
+ }
+ }
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ void JustDied(Unit* /*killer*/)
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+
+ // despawn frostspheres and Burrowers on death
+ std::list<Creature*> AddList;
+ me->GetCreatureListWithEntryInGrid(AddList, NPC_FROST_SPHERE, 150.0f);
+ me->GetCreatureListWithEntryInGrid(AddList, NPC_BURROWER, 150.0f);
+ if (!AddList.empty())
+ for (std::list<Creature*>::iterator itr = AddList.begin(); itr != AddList.end(); itr++)
+ (*itr)->DespawnOrUnsummon();
+ }
- switch (m_uiStage)
+ void JustSummoned(Creature* summoned)
{
- case 0:
- if (m_uiFreezeSlashTimer <= uiDiff)
- {
- DoCastVictim(SPELL_FREEZE_SLASH);
- m_uiFreezeSlashTimer = 15*IN_MILLISECONDS;
- } else m_uiFreezeSlashTimer -= uiDiff;
+ Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
+ switch (summoned->GetEntry())
+ {
+ case NPC_BURROW:
+ _burrowGUID.push_back(summoned->GetGUID());
+ summoned->SetReactState(REACT_PASSIVE);
+ summoned->CastSpell(summoned, SPELL_CHURNING_GROUND, false);
+ summoned->SetDisplayId(summoned->GetCreatureTemplate()->Modelid2);
+ break;
+ case NPC_SPIKE:
+ summoned->CombatStart(target);
+ summoned->SetDisplayId(summoned->GetCreatureTemplate()->Modelid1);
+ Talk(EMOTE_SPIKE, target->GetGUID());
+ break;
+ default:
+ break;
+ }
+ summons.Summon(summoned);
+ }
- if (m_uiPenetratingColdTimer <= uiDiff)
- {
- me->CastCustomSpell(SPELL_PENETRATING_COLD, SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5, 2, 5));
- m_uiPenetratingColdTimer = 20*IN_MILLISECONDS;
- } else m_uiPenetratingColdTimer -= uiDiff;
+ void EnterCombat(Unit* /*who*/)
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+
+ // Despawn Scarab Swarms neutral
+ EntryCheckPredicate pred(NPC_SCARAB);
+ summons.DoAction(ACTION_SCARAB_SUBMERGE, pred);
+
+ // Spawn Burrow
+ for (int i = 0; i < 4; i++)
+ me->SummonCreature(NPC_BURROW, AnubarakLoc[i + 2]);
+
+ // Spawn 6 Frost Spheres at start
+ for (int i = 0; i < 6; i++)
+ if (Unit* summoned = me->SummonCreature(NPC_FROST_SPHERE, SphereSpawn[i]))
+ _sphereGUID[i] = summoned->GetGUID();
+ }
- if (m_uiSummonNerubianTimer <= uiDiff && (IsHeroic() || !m_bReachedPhase3))
- {
- me->CastCustomSpell(SPELL_SUMMON_BURROWER, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 2, 2, 4));
- m_uiSummonNerubianTimer = 45*IN_MILLISECONDS;
- } else m_uiSummonNerubianTimer -= uiDiff;
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- if (IsHeroic() && m_uiNerubianShadowStrikeTimer <= uiDiff)
- {
- EntryCheckPredicate pred(NPC_BURROWER);
- Summons.DoAction(ACTION_SHADOW_STRIKE, pred);
- m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
- } else m_uiNerubianShadowStrikeTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiSubmergeTimer <= uiDiff && !m_bReachedPhase3 && !me->HasAura(SPELL_BERSERK))
- {
- m_uiStage = 1;
- m_uiSubmergeTimer = 60*IN_MILLISECONDS;
- } else m_uiSubmergeTimer -= uiDiff;
- break;
- case 1:
- DoCast(me, SPELL_SUBMERGE_ANUBARAK);
- DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- Talk(EMOTE_BURROWER);
- m_uiScarabSummoned = 0;
- m_uiSummonScarabTimer = 4*IN_MILLISECONDS;
- m_uiStage = 2;
- break;
- case 2:
- if (m_uiPursuingSpikeTimer <= uiDiff)
- {
- DoCast(SPELL_SPIKE_CALL);
- // Just to make sure it won't happen again in this phase
- m_uiPursuingSpikeTimer = 90*IN_MILLISECONDS;
- } else m_uiPursuingSpikeTimer -= uiDiff;
+ events.Update(diff);
- if (m_uiSummonScarabTimer <= uiDiff)
- {
- /* WORKAROUND
- * - The correct implementation is more likely the comment below but it needs spell knowledge
- */
- std::list<uint64>::iterator i = m_vBurrowGUID.begin();
- uint32 at = urand(0, m_vBurrowGUID.size()-1);
- for (uint32 k = 0; k < at; k++)
- ++i;
- if (Creature* pBurrow = Unit::GetCreature(*me, *i))
- pBurrow->CastSpell(pBurrow, 66340, false);
- m_uiScarabSummoned++;
- m_uiSummonScarabTimer = 4*IN_MILLISECONDS;
- if (m_uiScarabSummoned == 4) m_uiSummonScarabTimer = RAID_MODE(4, 20)*IN_MILLISECONDS;
-
- /*It seems that this spell have something more that needs to be taken into account
- //Need more sniff info
- DoCast(SPELL_SUMMON_BEATLES);
- // Just to make sure it won't happen again in this phase
- m_uiSummonScarabTimer = 90*IN_MILLISECONDS;*/
- } else m_uiSummonScarabTimer -= uiDiff;
-
- if (m_uiSubmergeTimer <= uiDiff)
- {
- m_uiStage = 3;
- m_uiSubmergeTimer = 80*IN_MILLISECONDS;
- } else m_uiSubmergeTimer -= uiDiff;
- break;
- case 3:
- m_uiStage = 0;
- DoCast(SPELL_SPIKE_TELE);
- Summons.DespawnEntry(NPC_SPIKE);
- me->RemoveAurasDueToSpell(SPELL_SUBMERGE_ANUBARAK);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- DoCast(me, SPELL_EMERGE_ANUBARAK);
- me->GetMotionMaster()->MoveChase(me->getVictim());
- m_uiSummonNerubianTimer = 10*IN_MILLISECONDS;
- m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
- m_uiSummonScarabTimer = 2*IN_MILLISECONDS;
- break;
- }
-
- if (!IsHeroic())
- {
- if (m_uiSummonFrostSphereTimer <= uiDiff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- uint8 startAt = urand(0, 5);
- uint8 i = startAt;
- do
+ switch (eventId)
{
- if (Unit* pSphere = Unit::GetCreature(*me, m_aSphereGUID[i]))
+ case EVENT_FREEZE_SLASH:
+ DoCastVictim(SPELL_FREEZE_SLASH);
+ events.ScheduleEvent(EVENT_FREEZE_SLASH, 15*IN_MILLISECONDS, 0, PHASE_MELEE);
+ return;
+ case EVENT_PENETRATING_COLD:
+ me->CastCustomSpell(SPELL_PENETRATING_COLD, SPELLVALUE_MAX_TARGETS, RAID_MODE(2, 5, 2, 5));
+ events.ScheduleEvent(EVENT_PENETRATING_COLD, 20*IN_MILLISECONDS, 0, PHASE_MELEE);
+ return;
+ case EVENT_SUMMON_NERUBIAN:
+ if (IsHeroic() || !_reachedPhase3)
+ me->CastCustomSpell(SPELL_SUMMON_BURROWER, SPELLVALUE_MAX_TARGETS, RAID_MODE(1, 2, 2, 4));
+ events.ScheduleEvent(EVENT_SUMMON_NERUBIAN, 45*IN_MILLISECONDS, 0, PHASE_MELEE);
+ return;
+ case EVENT_NERUBIAN_SHADOW_STRIKE:
{
- if (!pSphere->HasAura(SPELL_FROST_SPHERE))
+ EntryCheckPredicate pred(NPC_BURROWER);
+ summons.DoAction(ACTION_SHADOW_STRIKE, pred);
+ events.ScheduleEvent(EVENT_NERUBIAN_SHADOW_STRIKE, 30*IN_MILLISECONDS, 0, PHASE_MELEE);
+ break;
+ }
+ case EVENT_SUBMERGE:
+ if (!_reachedPhase3 && !me->HasAura(SPELL_BERSERK))
{
- if (Creature* summon = me->SummonCreature(NPC_FROST_SPHERE, SphereSpawn[i]))
- m_aSphereGUID[i] = summon->GetGUID();
- break;
+ DoCast(me, SPELL_SUBMERGE_ANUBARAK);
+ DoCast(me, SPELL_CLEAR_ALL_DEBUFFS);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ Talk(EMOTE_BURROWER);
+ events.SetPhase(PHASE_SUBMERGED);
+ events.ScheduleEvent(EVENT_PURSUING_SPIKE, 2*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
+ events.ScheduleEvent(EVENT_SUMMON_SCARAB, 4*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
+ events.ScheduleEvent(EVENT_EMERGE, 1*MINUTE*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
}
+ break;
+ case EVENT_PURSUING_SPIKE:
+ DoCast(SPELL_SPIKE_CALL);
+ break;
+ case EVENT_SUMMON_SCARAB:
+ {
+ /* WORKAROUND
+ * - The correct implementation is more likely the comment below but it needs spell knowledge
+ */
+ std::list<uint64>::iterator i = _burrowGUID.begin();
+ uint32 at = urand(0, _burrowGUID.size()-1);
+ for (uint32 k = 0; k < at; k++)
+ ++i;
+ if (Creature* pBurrow = Unit::GetCreature(*me, *i))
+ pBurrow->CastSpell(pBurrow, 66340, false);
+
+ events.ScheduleEvent(EVENT_SUMMON_SCARAB, 4*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
+
+ /*It seems that this spell have something more that needs to be taken into account
+ //Need more sniff info
+ DoCast(SPELL_SUMMON_BEATLES);
+ // Just to make sure it won't happen again in this phase
+ m_uiSummonScarabTimer = 90*IN_MILLISECONDS;*/
+ break;
}
- i = (i+1)%6;
- } while (i != startAt);
- m_uiSummonFrostSphereTimer = urand(20, 30)*IN_MILLISECONDS;
- } else m_uiSummonFrostSphereTimer -= uiDiff;
- }
+ case EVENT_EMERGE:
+ events.ScheduleEvent(EVENT_SUBMERGE, 80*IN_MILLISECONDS, 0, PHASE_MELEE);
+ DoCast(SPELL_SPIKE_TELE);
+ summons.DespawnEntry(NPC_SPIKE);
+ me->RemoveAurasDueToSpell(SPELL_SUBMERGE_ANUBARAK);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_EMERGE_ANUBARAK);
+ events.SetPhase(PHASE_MELEE);
+ events.ScheduleEvent(EVENT_FREEZE_SLASH, 15*IN_MILLISECONDS, 0, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_PENETRATING_COLD, 20*IN_MILLISECONDS, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_SUMMON_NERUBIAN, 10*IN_MILLISECONDS, 0, PHASE_MELEE);
+ events.ScheduleEvent(EVENT_SUBMERGE, 80*IN_MILLISECONDS, 0, PHASE_MELEE);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_NERUBIAN_SHADOW_STRIKE, 30*IN_MILLISECONDS, 0, PHASE_MELEE);
+ return;
+ case EVENT_SUMMON_FROST_SPHERE:
+ {
+ uint8 startAt = urand(0, 5);
+ uint8 i = startAt;
+ do
+ {
+ if (Unit* pSphere = Unit::GetCreature(*me, _sphereGUID[i]))
+ {
+ if (!pSphere->HasAura(SPELL_FROST_SPHERE))
+ {
+ if (Creature* summon = me->SummonCreature(NPC_FROST_SPHERE, SphereSpawn[i]))
+ _sphereGUID[i] = summon->GetGUID();
+ break;
+ }
+ }
+ i = (i + 1) % 6;
+ }
+ while
+ (i != startAt);
+ events.ScheduleEvent(EVENT_SUMMON_FROST_SPHERE, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ break;
+ }
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK);
+ break;
+ default:
+ break;
+ }
- if (HealthBelowPct(30) && m_uiStage == 0 && !m_bReachedPhase3)
- {
- m_bReachedPhase3 = true;
- DoCastAOE(SPELL_LEECHING_SWARM);
- Talk(EMOTE_LEECHING_SWARM);
- Talk(SAY_LEECHING_SWARM);
- }
+ }
- if (m_uiBerserkTimer <= uiDiff && !me->HasAura(SPELL_BERSERK))
- {
- DoCast(me, SPELL_BERSERK);
- } else m_uiBerserkTimer -= uiDiff;
+ if (HealthBelowPct(30) && events.GetPhaseMask() & PHASE_MASK_MELEE && !_reachedPhase3)
+ {
+ _reachedPhase3 = true;
+ DoCastAOE(SPELL_LEECHING_SWARM);
+ Talk(EMOTE_LEECHING_SWARM);
+ Talk(SAY_LEECHING_SWARM);
+ }
- DoMeleeAttackIfReady();
- }
- };
+ if (events.GetPhaseMask() & PHASE_MASK_MELEE)
+ DoMeleeAttackIfReady();
+ }
+ private:
+ std::list<uint64> _burrowGUID;
+ uint64 _sphereGUID[6];
+ bool _intro;
+ bool _reachedPhase3;
+ uint32 _frostSphereTimer;
+ uint32 _berserkTimer;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_anubarak_trialAI(creature);
+ };
};
class mob_swarm_scarab : public CreatureScript
{
-public:
- mob_swarm_scarab() : CreatureScript("mob_swarm_scarab") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_swarm_scarabAI(creature);
- };
-
- struct mob_swarm_scarabAI : public ScriptedAI
- {
- mob_swarm_scarabAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 m_uiDeterminationTimer;
+ public:
+ mob_swarm_scarab() : CreatureScript("mob_swarm_scarab") { }
- void Reset()
+ struct mob_swarm_scarabAI : public ScriptedAI
{
- me->SetCorpseDelay(0);
- m_uiDeterminationTimer = urand(5*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- DoCast(me, SPELL_ACID_MANDIBLE);
- me->SetInCombatWithZone();
- if (me->isInCombat())
- if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ANUBARAK)))
- Anubarak->AI()->JustSummoned(me);
- }
+ mob_swarm_scarabAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- void DoAction(const int32 actionId)
- {
- switch (actionId)
+ void Reset()
{
- case ACTION_SCARAB_SUBMERGE:
- DoCast(SPELL_SUBMERGE_EFFECT);
- me->DespawnOrUnsummon(1000);
- break;
+ me->SetCorpseDelay(0);
+ _determinationTimer = urand(5*IN_MILLISECONDS, 60*IN_MILLISECONDS);
+ DoCast(me, SPELL_ACID_MANDIBLE);
+ me->SetInCombatWithZone();
+ if (me->isInCombat())
+ if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_ANUBARAK)))
+ Anubarak->AI()->JustSummoned(me);
}
- }
- void JustDied(Unit* killer)
- {
- DoCast(killer, RAID_MODE(SPELL_TRAITOR_KING_10, SPELL_TRAITOR_KING_25));
- }
+ void DoAction(const int32 actionId)
+ {
+ switch (actionId)
+ {
+ case ACTION_SCARAB_SUBMERGE:
+ DoCast(SPELL_SUBMERGE_EFFECT);
+ me->DespawnOrUnsummon(1*IN_MILLISECONDS);
+ break;
+ default:
+ break;
+ }
+ }
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
+ void JustDied(Unit* killer)
+ {
+ DoCast(killer, RAID_MODE(SPELL_TRAITOR_KING_10, SPELL_TRAITOR_KING_25));
+ }
- /* Bosskillers don't recognize */
- if (m_uiDeterminationTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- DoCast(me, SPELL_DETERMINATION);
- m_uiDeterminationTimer = urand(10*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- } else m_uiDeterminationTimer -= uiDiff;
+ if (_instance && _instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS)
+ me->DisappearAndDie();
- DoMeleeAttackIfReady();
- }
- };
+ if (!UpdateVictim())
+ return;
-};
+ /* Bosskillers don't recognize */
+ if (_determinationTimer <= diff)
+ {
+ DoCast(me, SPELL_DETERMINATION);
+ _determinationTimer = urand(10*IN_MILLISECONDS, 60*IN_MILLISECONDS);
+ }
+ else
+ _determinationTimer -= diff;
-class mob_nerubian_burrower : public CreatureScript
-{
-public:
- mob_nerubian_burrower() : CreatureScript("mob_nerubian_burrower") { }
+ DoMeleeAttackIfReady();
+ }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_nerubian_burrowerAI(creature);
- };
+ private:
+ InstanceScript* _instance;
+ uint32 _determinationTimer;
+ };
- struct mob_nerubian_burrowerAI : public ScriptedAI
- {
- mob_nerubian_burrowerAI(Creature* creature) : ScriptedAI(creature)
+ CreatureAI* GetAI(Creature* creature) const
{
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 m_uiSpiderFrenzyTimer;
- uint32 m_uiSubmergeTimer;
+ return new mob_swarm_scarabAI(creature);
+ };
+};
- void Reset()
- {
- me->SetCorpseDelay(10);
- m_uiSpiderFrenzyTimer = urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS);
- m_uiSubmergeTimer = 30*IN_MILLISECONDS;
- DoCast(me, SPELL_EXPOSE_WEAKNESS);
- DoCast(me, SPELL_SPIDER_FRENZY);
- DoCast(me, SPELL_AWAKENED);
- me->SetInCombatWithZone();
- if (me->isInCombat())
- if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ANUBARAK)))
- Anubarak->AI()->JustSummoned(me);
- }
+class mob_nerubian_burrower : public CreatureScript
+{
+ public:
+ mob_nerubian_burrower() : CreatureScript("mob_nerubian_burrower") { }
- void DoAction(const int32 actionId)
+ struct mob_nerubian_burrowerAI : public ScriptedAI
{
- switch (actionId)
+ mob_nerubian_burrowerAI(Creature* creature) : ScriptedAI(creature)
{
- case ACTION_SHADOW_STRIKE:
- if (!me->HasAura(SPELL_AWAKENED))
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_SHADOW_STRIKE);
- break;
+ _instance = creature->GetInstanceScript();
}
- }
-
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ void Reset()
+ {
+ me->SetCorpseDelay(10);
+ _submergeTimer = 30*IN_MILLISECONDS;
+ DoCast(me, SPELL_EXPOSE_WEAKNESS);
+ DoCast(me, SPELL_SPIDER_FRENZY);
+ DoCast(me, SPELL_AWAKENED);
+ me->SetInCombatWithZone();
+ if (me->isInCombat())
+ if (Creature* Anubarak = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_ANUBARAK)))
+ Anubarak->AI()->JustSummoned(me);
+ }
- if ((m_uiSubmergeTimer <= uiDiff) && HealthBelowPct(80))
+ void DoAction(const int32 actionId)
{
- if (me->HasAura(SPELL_SUBMERGE_EFFECT))
+ switch (actionId)
{
- me->RemoveAurasDueToSpell(SPELL_SUBMERGE_EFFECT);
- DoCast(me, SPELL_EMERGE_EFFECT);
- DoCast(me, SPELL_AWAKENED);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ case ACTION_SHADOW_STRIKE:
+ if (!me->HasAura(SPELL_AWAKENED))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_SHADOW_STRIKE);
+ break;
+ default:
+ break;
}
- else
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (_instance && _instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS)
+ me->DisappearAndDie();
+
+ if (!UpdateVictim() && !me->HasAura(SPELL_SUBMERGE_EFFECT))
+ return;
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ if ((_submergeTimer <= diff) && HealthBelowPct(80))
{
- if (!me->HasAura(SPELL_PERMAFROST_HELPER))
+ if (me->HasAura(SPELL_SUBMERGE_EFFECT))
{
- DoCast(me, SPELL_SUBMERGE_EFFECT);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- DoCast(me, SPELL_PERSISTENT_DIRT, true);
+ me->RemoveAurasDueToSpell(SPELL_SUBMERGE_EFFECT);
+ DoCast(me, SPELL_EMERGE_EFFECT);
+ DoCast(me, SPELL_AWAKENED);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ else
+ {
+ if (!me->HasAura(SPELL_PERMAFROST_HELPER))
+ {
+ DoCast(me, SPELL_SUBMERGE_EFFECT);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_PERSISTENT_DIRT, true);
+ }
}
+ _submergeTimer = 20*IN_MILLISECONDS;
}
- m_uiSubmergeTimer = 20*IN_MILLISECONDS;
- } else m_uiSubmergeTimer -= uiDiff;
+ else
+ _submergeTimer -= diff;
- DoMeleeAttackIfReady();
- }
- };
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ uint32 _submergeTimer;
+ Phases _phase;
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_nerubian_burrowerAI(creature);
+ };
};
class mob_frost_sphere : public CreatureScript
@@ -637,6 +650,8 @@ class mob_frost_sphere : public CreatureScript
DoCast(SPELL_PERMAFROST);
me->SetObjectScale(2.0f);
break;
+ default:
+ break;
}
}
};
@@ -649,92 +664,180 @@ class mob_frost_sphere : public CreatureScript
class mob_anubarak_spike : public CreatureScript
{
-public:
- mob_anubarak_spike() : CreatureScript("mob_anubarak_spike") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_anubarak_spikeAI(creature);
- };
+ public:
+ mob_anubarak_spike() : CreatureScript("mob_anubarak_spike") { }
- struct mob_anubarak_spikeAI : public ScriptedAI
- {
- mob_anubarak_spikeAI(Creature* creature) : ScriptedAI(creature)
+ struct mob_anubarak_spikeAI : public ScriptedAI
{
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
- uint32 m_uiIncreaseSpeedTimer;
- uint8 m_uiSpeed;
- uint64 m_uiTargetGUID;
+ mob_anubarak_spikeAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
- void Reset()
- {
- // For an unknown reason this npc isn't recognize the Aura of Permafrost with this flags =/
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
- m_uiTargetGUID = 0;
- }
+ void Reset()
+ {
+ _phase = PHASE_NO_MOVEMENT;
+ _phaseSwitchTimer = 1;
+ // make sure the spike has everyone on threat list
+ me->SetInCombatWithZone();
+ }
- bool CanAIAttack(Unit const* victim) const
- {
- return victim->GetTypeId() == TYPEID_PLAYER;
- }
+ bool CanAIAttack(Unit const* victim) const
+ {
+ return victim->GetTypeId() == TYPEID_PLAYER;
+ }
- void EnterCombat(Unit* who)
- {
- m_uiTargetGUID = who->GetGUID();
- DoCast(who, SPELL_MARK);
- Talk(EMOTE_SPIKE, who->GetGUID());
- me->SetSpeed(MOVE_RUN, 0.5f);
- m_uiSpeed = 0;
- m_uiIncreaseSpeedTimer = 1*IN_MILLISECONDS;
- me->TauntApply(who);
- }
+ void EnterCombat(Unit* who)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ {
+ StartChase(target);
+ Talk(EMOTE_SPIKE, who->GetGUID());
+ }
+ }
- void DamageTaken(Unit* /*who*/, uint32& uiDamage)
- {
- uiDamage = 0;
- }
+ void DamageTaken(Unit* /*who*/, uint32& uiDamage)
+ {
+ uiDamage = 0;
+ }
- void UpdateAI(const uint32 uiDiff)
- {
- Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID);
- if (!target || !target->isAlive() || !target->HasAura(SPELL_MARK))
+ void UpdateAI(const uint32 diff)
{
- if (Creature* pAnubarak = Unit::GetCreature((*me), instance->GetData64(NPC_ANUBARAK)))
- pAnubarak->CastSpell(pAnubarak, SPELL_SPIKE_TELE, false);
- me->DisappearAndDie();
- return;
+ if (!UpdateVictim())
+ {
+ me->DisappearAndDie();
+ return;
+ }
+
+ if (_phaseSwitchTimer)
+ {
+ if (_phaseSwitchTimer <= diff)
+ {
+ switch (_phase)
+ {
+ case PHASE_NO_MOVEMENT:
+ DoCast(me, SPELL_SPIKE_SPEED1);
+ DoCast(me, SPELL_SPIKE_TRAIL);
+ _phase = PHASE_IMPALE_NORMAL;
+ if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ {
+ StartChase(target2);
+ Talk(EMOTE_SPIKE, target2->GetGUID());
+ }
+ _phaseSwitchTimer = 7*IN_MILLISECONDS;
+ return;
+ case PHASE_IMPALE_NORMAL:
+ DoCast(me, SPELL_SPIKE_SPEED2);
+ _phase = PHASE_IMPALE_MIDDLE;
+ _phaseSwitchTimer = 7*IN_MILLISECONDS;
+ return;
+ case PHASE_IMPALE_MIDDLE:
+ DoCast(me, SPELL_SPIKE_SPEED3);
+ _phase = PHASE_IMPALE_FAST;
+ _phaseSwitchTimer = 0;
+ return;
+ default:
+ return;
+ }
+ }
+ else
+ _phaseSwitchTimer -= diff;
+ }
}
- if (m_uiIncreaseSpeedTimer)
+ void MoveInLineOfSight(Unit* pWho)
{
- if (m_uiIncreaseSpeedTimer <= uiDiff)
+ if (!pWho)
+ return;
+
+ if (pWho->GetEntry() != NPC_FROST_SPHERE)
+ return;
+
+ if (_phase == PHASE_NO_MOVEMENT)
+ return;
+
+ if (me->IsWithinDist(pWho, 7.0f))
{
- switch (m_uiSpeed)
+ switch (_phase)
{
- case 0:
- DoCast(me, SPELL_SPIKE_SPEED1);
- DoCast(me, SPELL_SPIKE_TRAIL);
- m_uiSpeed = 1;
- m_uiIncreaseSpeedTimer = 7*IN_MILLISECONDS;
+ case PHASE_IMPALE_NORMAL:
+ me->RemoveAurasDueToSpell(SPELL_SPIKE_SPEED1);
+ break;
+ case PHASE_IMPALE_MIDDLE:
+ me->RemoveAurasDueToSpell(SPELL_SPIKE_SPEED2);
break;
- case 1:
- DoCast(me, SPELL_SPIKE_SPEED2);
- m_uiSpeed = 2;
- m_uiIncreaseSpeedTimer = 7*IN_MILLISECONDS;
+ case PHASE_IMPALE_FAST:
+ me->RemoveAurasDueToSpell(SPELL_SPIKE_SPEED3);
break;
- case 2:
- DoCast(me, SPELL_SPIKE_SPEED3);
- m_uiIncreaseSpeedTimer = 0;
+ default:
break;
}
- } else m_uiIncreaseSpeedTimer -= uiDiff;
+
+ me->CastSpell(me, SPELL_SPIKE_FAIL, true);
+
+ pWho->ToCreature()->DespawnOrUnsummon(3*IN_MILLISECONDS);
+
+ // After the spikes hit the icy surface they can't move for about ~5 seconds
+ _phase = PHASE_NO_MOVEMENT;
+ _phaseSwitchTimer = 5*IN_MILLISECONDS;
+ SetCombatMovement(false);
+ me->GetMotionMaster()->MoveIdle();
+ me->GetMotionMaster()->Clear();
+ }
+ }
+
+ void StartChase(Unit* who)
+ {
+ DoCast(who, SPELL_MARK);
+ me->SetSpeed(MOVE_RUN, 0.5f);
+ // make sure the Spine will really follow the one he should
+ me->getThreatManager().clearReferences();
+ me->SetInCombatWithZone();
+ me->getThreatManager().addThreat(who, std::numeric_limits<float>::max());
+ me->GetMotionMaster()->Clear(true);
+ me->GetMotionMaster()->MoveChase(who);
+ me->TauntApply(who);
+ }
+
+ private:
+ uint32 _phaseSwitchTimer;
+ PursuingSpikesPhases _phase;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_anubarak_spikeAI(creature);
+ };
+};
+
+class spell_impale : public SpellScriptLoader
+{
+ public:
+ spell_impale() : SpellScriptLoader("spell_impale") { }
+
+ class spell_impale_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_impale_SpellScript);
+
+ void HandleDamageCalc(SpellEffIndex /*effIndex*/)
+ {
+ Unit* target = GetHitUnit();
+ uint32 permafrost = sSpellMgr->GetSpellIdForDifficulty(SPELL_PERMAFROST, target);
+
+ // make sure Impale doesnt do damage if we are standing on permafrost
+ if (target && target->HasAura(permafrost))
+ SetHitDamage(0);
}
- }
- };
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_impale_SpellScript::HandleDamageCalc, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_impale_SpellScript();
+ }
};
void AddSC_boss_anubarak_trial()
@@ -744,4 +847,6 @@ void AddSC_boss_anubarak_trial()
new mob_nerubian_burrower();
new mob_anubarak_spike();
new mob_frost_sphere();
+
+ new spell_impale();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
index e376a97dd36..63966e5f204 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
@@ -16,17 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: faction_champions
-SD%Complete: ??%
-SDComment: Scripts by Selector, modified by /dev/rsa
-SDCategory: Crusader Coliseum
-EndScriptData */
-
-// Known bugs:
-// All - untested
-// Pets aren't being summoned by their masters
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
@@ -36,7 +25,7 @@ EndScriptData */
enum Yells
{
- SAY_KILL_PLAYER = 6,
+ SAY_KILL_PLAYER = 6
};
enum eAIs
@@ -44,234 +33,527 @@ enum eAIs
AI_MELEE = 0,
AI_RANGED = 1,
AI_HEALER = 2,
- AI_PET = 3,
+ AI_PET = 3
};
enum eSpells
{
- SPELL_ANTI_AOE = 68595,
- SPELL_PVP_TRINKET = 65547,
+ // generic
+ SPELL_ANTI_AOE = 68595,
+ SPELL_PVP_TRINKET = 65547,
+
+ // druid healer
+ SPELL_LIFEBLOOM = 66093,
+ SPELL_NOURISH = 66066,
+ SPELL_REGROWTH = 66067,
+ SPELL_REJUVENATION = 66065,
+ SPELL_TRANQUILITY = 66086,
+ SPELL_BARKSKIN = 65860,
+ SPELL_THORNS = 66068,
+ SPELL_NATURE_GRASP = 66071,
+
+ // shaman healer
+ SPELL_HEALING_WAVE = 66055,
+ SPELL_RIPTIDE = 66053,
+ SPELL_SPIRIT_CLEANSE = 66056, //friendly only
+ SPELL_HEROISM = 65983,
+ SPELL_BLOODLUST = 65980,
+ SPELL_HEX = 66054,
+ SPELL_EARTH_SHIELD = 66063,
+ SPELL_EARTH_SHOCK = 65973,
+ AURA_EXHAUSTION = 57723,
+ AURA_SATED = 57724,
+
+ // paladin healer
+ SPELL_HAND_OF_FREEDOM = 68757,
+ SPELL_DIVINE_SHIELD = 66010,
+ SPELL_CLEANSE = 66116,
+ SPELL_FLASH_OF_LIGHT = 66113,
+ SPELL_HOLY_LIGHT = 66112,
+ SPELL_HOLY_SHOCK = 66114,
+ SPELL_HAND_OF_PROTECTION = 66009,
+ SPELL_HAMMER_OF_JUSTICE = 66613,
+ SPELL_FORBEARANCE = 25771,
+
+ // priest healer
+ SPELL_RENEW = 66177,
+ SPELL_SHIELD = 66099,
+ SPELL_FLASH_HEAL = 66104,
+ SPELL_DISPEL = 65546,
+ SPELL_PSYCHIC_SCREAM = 65543,
+ SPELL_MANA_BURN = 66100,
+ SPELL_PENANCE = 66097,
+
+ // priest dps
+ SPELL_SILENCE = 65542,
+ SPELL_VAMPIRIC_TOUCH = 65490,
+ SPELL_SW_PAIN = 65541,
+ SPELL_MIND_FLAY = 65488,
+ SPELL_MIND_BLAST = 65492,
+ SPELL_HORROR = 65545,
+ SPELL_DISPERSION = 65544,
+ SPELL_SHADOWFORM = 16592,
+
+ // warlock
+ SPELL_HELLFIRE = 65816,
+ SPELL_CORRUPTION = 65810,
+ SPELL_CURSE_OF_AGONY = 65814,
+ SPELL_CURSE_OF_EXHAUSTION = 65815,
+ SPELL_FEAR = 65809,
+ SPELL_SEARING_PAIN = 65819,
+ SPELL_SHADOW_BOLT = 65821,
+ SPELL_UNSTABLE_AFFLICTION = 65812,
+ SPELL_UNSTABLE_AFFLICTION_DISPEL = 65813,
+ SPELL_SUMMON_FELHUNTER = 67514,
+
+ // mage
+ SPELL_ARCANE_BARRAGE = 65799,
+ SPELL_ARCANE_BLAST = 65791,
+ SPELL_ARCANE_EXPLOSION = 65800,
+ SPELL_BLINK = 65793,
+ SPELL_COUNTERSPELL = 65790,
+ SPELL_FROST_NOVA = 65792,
+ SPELL_FROSTBOLT = 65807,
+ SPELL_ICE_BLOCK = 65802,
+ SPELL_POLYMORPH = 65801,
+
+ // hunter
+ SPELL_AIMED_SHOT = 65883,
+ SPELL_DETERRENCE = 65871,
+ SPELL_DISENGAGE = 65869,
+ SPELL_EXPLOSIVE_SHOT = 65866,
+ SPELL_FROST_TRAP = 65880,
+ SPELL_SHOOT = 65868,
+ SPELL_STEADY_SHOT = 65867,
+ SPELL_WING_CLIP = 66207,
+ SPELL_WYVERN_STING = 65877,
+ SPELL_CALL_PET = 67777,
+
+ // druid dps
+ SPELL_CYCLONE = 65859,
+ SPELL_ENTANGLING_ROOTS = 65857,
+ SPELL_FAERIE_FIRE = 65863,
+ SPELL_FORCE_OF_NATURE = 65861,
+ SPELL_INSECT_SWARM = 65855,
+ SPELL_MOONFIRE = 65856,
+ SPELL_STARFIRE = 65854,
+ SPELL_WRATH = 65862,
+
+ // warrior
+ SPELL_BLADESTORM = 65947,
+ SPELL_INTIMIDATING_SHOUT = 65930,
+ SPELL_MORTAL_STRIKE = 65926,
+ SPELL_CHARGE = 68764,
+ SPELL_DISARM = 65935,
+ SPELL_OVERPOWER = 65924,
+ SPELL_SUNDER_ARMOR = 65936,
+ SPELL_SHATTERING_THROW = 65940,
+ SPELL_RETALIATION = 65932,
+
+ // death knight
+ SPELL_CHAINS_OF_ICE = 66020,
+ SPELL_DEATH_COIL = 66019,
+ SPELL_DEATH_GRIP = 66017,
+ SPELL_FROST_STRIKE = 66047,
+ SPELL_ICEBOUND_FORTITUDE = 66023,
+ SPELL_ICY_TOUCH = 66021,
+ SPELL_STRANGULATE = 66018,
+ SPELL_DEATH_GRIP_PULL = 64431, // used at spellscript
+
+ // rogue
+ SPELL_FAN_OF_KNIVES = 65955,
+ SPELL_BLIND = 65960,
+ SPELL_CLOAK = 65961,
+ SPELL_BLADE_FLURRY = 65956,
+ SPELL_SHADOWSTEP = 66178,
+ SPELL_HEMORRHAGE = 65954,
+ SPELL_EVISCERATE = 65957,
+ SPELL_WOUND_POISON = 65962,
+
+ // shaman dps (some spells taken from shaman healer)
+ SPELL_LAVA_LASH = 65974,
+ SPELL_STORMSTRIKE = 65970,
+ SPELL_WINDFURY = 65976,
+
+ // paladin dps
+ SPELL_AVENGING_WRATH = 66011,
+ SPELL_CRUSADER_STRIKE = 66003,
+ SPELL_DIVINE_STORM = 66006,
+ SPELL_HAMMER_OF_JUSTICE_RET = 66007,
+ SPELL_JUDGEMENT_OF_COMMAND = 66005,
+ SPELL_REPENTANCE = 66008,
+ SPELL_SEAL_OF_COMMAND = 66004,
+
+ // warlock pet
+ SPELL_DEVOUR_MAGIC = 67518,
+ SPELL_SPELL_LOCK = 67519,
+
+ // hunter pet
+ SPELL_CLAW = 67793
};
-class boss_toc_champion_controller : public CreatureScript
+enum Events
{
-public:
- boss_toc_champion_controller() : CreatureScript("boss_toc_champion_controller") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_toc_champion_controllerAI (creature);
- }
-
- struct boss_toc_champion_controllerAI : public ScriptedAI
- {
- boss_toc_champion_controllerAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- instance = creature->GetInstanceScript();
- }
+ // generic
+ EVENT_THREAT = 1,
+ EVENT_REMOVE_CC = 2,
+
+ // druid healer
+ EVENT_LIFEBLOOM = 1,
+ EVENT_NOURISH = 2,
+ EVENT_REGROWTH = 3,
+ EVENT_REJUVENATION = 4,
+ EVENT_TRANQUILITY = 5,
+ EVENT_HEAL_BARKSKIN = 6,
+ EVENT_THORNS = 7,
+ EVENT_NATURE_GRASP = 8,
+
+ // shaman healer
+ EVENT_HEALING_WAVE = 1,
+ EVENT_RIPTIDE = 2,
+ EVENT_SPIRIT_CLEANSE = 3,
+ EVENT_HEAL_BLOODLUST_HEROISM = 4,
+ EVENT_HEX = 5,
+ EVENT_EARTH_SHIELD = 6,
+ EVENT_HEAL_EARTH_SHOCK = 7,
+
+ // paladin healer
+ EVENT_HAND_OF_FREEDOM = 1,
+ EVENT_HEAL_DIVINE_SHIELD = 2,
+ EVENT_CLEANSE = 3,
+ EVENT_FLASH_OF_LIGHT = 4,
+ EVENT_HOLY_LIGHT = 5,
+ EVENT_HOLY_SHOCK = 6,
+ EVENT_HEAL_HAND_OF_PROTECTION = 7,
+ EVENT_HAMMER_OF_JUSTICE = 8,
+
+ // priest healer
+ EVENT_RENEW = 1,
+ EVENT_SHIELD = 2,
+ EVENT_FLASH_HEAL = 3,
+ EVENT_HEAL_DISPEL = 4,
+ EVENT_HEAL_PSYCHIC_SCREAM = 5,
+ EVENT_MANA_BURN = 6,
+ EVENT_PENANCE = 7,
+
+ // priest dps
+ EVENT_SILENCE = 1,
+ EVENT_VAMPIRIC_TOUCH = 2,
+ EVENT_SW_PAIN = 3,
+ EVENT_MIND_BLAST = 4,
+ EVENT_HORROR = 5,
+ EVENT_DISPERSION = 6,
+ EVENT_DPS_DISPEL = 7,
+ EVENT_DPS_PSYCHIC_SCREAM = 8,
+
+ // warlock
+ EVENT_HELLFIRE = 1,
+ EVENT_CORRUPTION = 2,
+ EVENT_CURSE_OF_AGONY = 3,
+ EVENT_CURSE_OF_EXHAUSTION = 4,
+ EVENT_FEAR = 5,
+ EVENT_SEARING_PAIN = 6,
+ EVENT_UNSTABLE_AFFLICTION = 7,
+
+ // mage
+ EVENT_ARCANE_BARRAGE = 1,
+ EVENT_ARCANE_BLAST = 2,
+ EVENT_ARCANE_EXPLOSION = 3,
+ EVENT_BLINK = 4,
+ EVENT_COUNTERSPELL = 5,
+ EVENT_FROST_NOVA = 6,
+ EVENT_ICE_BLOCK = 7,
+ EVENT_POLYMORPH = 8,
+
+ // hunter
+ EVENT_AIMED_SHOT = 1,
+ EVENT_DETERRENCE = 2,
+ EVENT_DISENGAGE = 3,
+ EVENT_EXPLOSIVE_SHOT = 4,
+ EVENT_FROST_TRAP = 5,
+ EVENT_STEADY_SHOT = 6,
+ EVENT_WING_CLIP = 7,
+ EVENT_WYVERN_STING = 8,
+
+ // druid dps
+ EVENT_CYCLONE = 1,
+ EVENT_ENTANGLING_ROOTS = 2,
+ EVENT_FAERIE_FIRE = 3,
+ EVENT_FORCE_OF_NATURE = 4,
+ EVENT_INSECT_SWARM = 5,
+ EVENT_MOONFIRE = 6,
+ EVENT_STARFIRE = 7,
+ EVENT_DPS_BARKSKIN = 8,
+
+ // warrior
+ EVENT_BLADESTORM = 1,
+ EVENT_INTIMIDATING_SHOUT = 2,
+ EVENT_MORTAL_STRIKE = 3,
+ EVENT_WARR_CHARGE = 4,
+ EVENT_DISARM = 5,
+ EVENT_OVERPOWER = 6,
+ EVENT_SUNDER_ARMOR = 7,
+ EVENT_SHATTERING_THROW = 8,
+ EVENT_RETALIATION = 9,
+
+ // death knight
+ EVENT_CHAINS_OF_ICE = 1,
+ EVENT_DEATH_COIL = 2,
+ EVENT_DEATH_GRIP = 3,
+ EVENT_FROST_STRIKE = 4,
+ EVENT_ICEBOUND_FORTITUDE = 5,
+ EVENT_ICY_TOUCH = 6,
+ EVENT_STRANGULATE = 7,
+
+ // rogue
+ EVENT_FAN_OF_KNIVES = 1,
+ EVENT_BLIND = 2,
+ EVENT_CLOAK = 3,
+ EVENT_BLADE_FLURRY = 4,
+ EVENT_SHADOWSTEP = 5,
+ EVENT_HEMORRHAGE = 6,
+ EVENT_EVISCERATE = 7,
+ EVENT_WOUND_POISON = 8,
+
+ // shaman dps
+ EVENT_DPS_EARTH_SHOCK = 1,
+ EVENT_LAVA_LASH = 2,
+ EVENT_STORMSTRIKE = 3,
+ EVENT_DPS_BLOODLUST_HEROISM = 4,
+ EVENT_DEPLOY_TOTEM = 5,
+ EVENT_WINDFURY = 6,
+
+ // paladin dps
+ EVENT_AVENGING_WRATH = 1,
+ EVENT_CRUSADER_STRIKE = 2,
+ EVENT_DIVINE_STORM = 3,
+ EVENT_HAMMER_OF_JUSTICE_RET = 4,
+ EVENT_JUDGEMENT_OF_COMMAND = 5,
+ EVENT_REPENTANCE = 6,
+ EVENT_DPS_HAND_OF_PROTECTION = 7,
+ EVENT_DPS_DIVINE_SHIELD = 8,
+
+ // warlock pet
+ EVENT_DEVOUR_MAGIC = 1,
+ EVENT_SPELL_LOCK = 2
+};
- InstanceScript* instance;
- SummonList Summons;
- uint32 m_uiChampionsNotStarted;
- uint32 m_uiChampionsFailed;
- uint32 m_uiChampionsKilled;
- bool m_bInProgress;
+class boss_toc_champion_controller : public CreatureScript
+{
+ public:
+ boss_toc_champion_controller() : CreatureScript("boss_toc_champion_controller") { }
- void Reset()
+ struct boss_toc_champion_controllerAI : public ScriptedAI
{
- m_uiChampionsNotStarted = 0;
- m_uiChampionsFailed = 0;
- m_uiChampionsKilled = 0;
- m_bInProgress = false;
- }
+ boss_toc_champion_controllerAI(Creature* creature) : ScriptedAI(creature), _summons(me)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- std::vector<uint32> SelectChampions(Team playerTeam)
- {
- std::vector<uint32> vHealersEntries;
- vHealersEntries.clear();
- vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DRUID_RESTORATION : NPC_ALLIANCE_DRUID_RESTORATION);
- vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PALADIN_HOLY : NPC_ALLIANCE_PALADIN_HOLY);
- vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PRIEST_DISCIPLINE : NPC_ALLIANCE_PRIEST_DISCIPLINE);
- vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_SHAMAN_RESTORATION : NPC_ALLIANCE_SHAMAN_RESTORATION);
-
- std::vector<uint32> vOtherEntries;
- vOtherEntries.clear();
- vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DEATH_KNIGHT : NPC_ALLIANCE_DEATH_KNIGHT);
- vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_HUNTER : NPC_ALLIANCE_HUNTER);
- vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_MAGE : NPC_ALLIANCE_MAGE);
- vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_ROGUE : NPC_ALLIANCE_ROGUE);
- vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARLOCK : NPC_ALLIANCE_WARLOCK);
- vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR);
-
- uint8 healersSubtracted = 2;
- if (instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
- healersSubtracted = 1;
- for (uint8 i = 0; i < healersSubtracted; ++i)
+ void Reset()
{
- uint8 pos = urand(0, vHealersEntries.size()-1);
- switch (vHealersEntries[pos])
+ _championsNotStarted = 0;
+ _championsFailed = 0;
+ _championsKilled = 0;
+ _inProgress = false;
+ }
+
+ std::vector<uint32> SelectChampions(Team playerTeam)
+ {
+ std::vector<uint32> vHealersEntries;
+ vHealersEntries.clear();
+ vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DRUID_RESTORATION : NPC_ALLIANCE_DRUID_RESTORATION);
+ vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PALADIN_HOLY : NPC_ALLIANCE_PALADIN_HOLY);
+ vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_PRIEST_DISCIPLINE : NPC_ALLIANCE_PRIEST_DISCIPLINE);
+ vHealersEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_SHAMAN_RESTORATION : NPC_ALLIANCE_SHAMAN_RESTORATION);
+
+ std::vector<uint32> vOtherEntries;
+ vOtherEntries.clear();
+ vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_DEATH_KNIGHT : NPC_ALLIANCE_DEATH_KNIGHT);
+ vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_HUNTER : NPC_ALLIANCE_HUNTER);
+ vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_MAGE : NPC_ALLIANCE_MAGE);
+ vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_ROGUE : NPC_ALLIANCE_ROGUE);
+ vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARLOCK : NPC_ALLIANCE_WARLOCK);
+ vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR);
+
+ uint8 healersSubtracted = 2;
+ if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
+ healersSubtracted = 1;
+ for (uint8 i = 0; i < healersSubtracted; ++i)
{
- case NPC_ALLIANCE_DRUID_RESTORATION:
- vOtherEntries.push_back(NPC_ALLIANCE_DRUID_BALANCE);
- break;
- case NPC_HORDE_DRUID_RESTORATION:
- vOtherEntries.push_back(NPC_HORDE_DRUID_BALANCE);
- break;
- case NPC_ALLIANCE_PALADIN_HOLY:
- vOtherEntries.push_back(NPC_ALLIANCE_PALADIN_RETRIBUTION);
- break;
- case NPC_HORDE_PALADIN_HOLY:
- vOtherEntries.push_back(NPC_HORDE_PALADIN_RETRIBUTION);
- break;
- case NPC_ALLIANCE_PRIEST_DISCIPLINE:
- vOtherEntries.push_back(NPC_ALLIANCE_PRIEST_SHADOW);
- break;
- case NPC_HORDE_PRIEST_DISCIPLINE:
- vOtherEntries.push_back(NPC_HORDE_PRIEST_SHADOW);
- break;
- case NPC_ALLIANCE_SHAMAN_RESTORATION:
- vOtherEntries.push_back(NPC_ALLIANCE_SHAMAN_ENHANCEMENT);
- break;
- case NPC_HORDE_SHAMAN_RESTORATION:
- vOtherEntries.push_back(NPC_HORDE_SHAMAN_ENHANCEMENT);
- break;
+ uint8 pos = urand(0, vHealersEntries.size() - 1);
+ switch (vHealersEntries[pos])
+ {
+ case NPC_ALLIANCE_DRUID_RESTORATION:
+ vOtherEntries.push_back(NPC_ALLIANCE_DRUID_BALANCE);
+ break;
+ case NPC_HORDE_DRUID_RESTORATION:
+ vOtherEntries.push_back(NPC_HORDE_DRUID_BALANCE);
+ break;
+ case NPC_ALLIANCE_PALADIN_HOLY:
+ vOtherEntries.push_back(NPC_ALLIANCE_PALADIN_RETRIBUTION);
+ break;
+ case NPC_HORDE_PALADIN_HOLY:
+ vOtherEntries.push_back(NPC_HORDE_PALADIN_RETRIBUTION);
+ break;
+ case NPC_ALLIANCE_PRIEST_DISCIPLINE:
+ vOtherEntries.push_back(NPC_ALLIANCE_PRIEST_SHADOW);
+ break;
+ case NPC_HORDE_PRIEST_DISCIPLINE:
+ vOtherEntries.push_back(NPC_HORDE_PRIEST_SHADOW);
+ break;
+ case NPC_ALLIANCE_SHAMAN_RESTORATION:
+ vOtherEntries.push_back(NPC_ALLIANCE_SHAMAN_ENHANCEMENT);
+ break;
+ case NPC_HORDE_SHAMAN_RESTORATION:
+ vOtherEntries.push_back(NPC_HORDE_SHAMAN_ENHANCEMENT);
+ break;
+ default:
+ break;
+ }
+ vHealersEntries.erase(vHealersEntries.begin() + pos);
}
- vHealersEntries.erase(vHealersEntries.begin()+pos);
- }
- if (instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
- for (uint8 i = 0; i < 4; ++i)
- vOtherEntries.erase(vOtherEntries.begin()+urand(0, vOtherEntries.size()-1));
+ if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
+ for (uint8 i = 0; i < 4; ++i)
+ vOtherEntries.erase(vOtherEntries.begin() + urand(0, vOtherEntries.size() - 1));
- std::vector<uint32> vChampionEntries;
- vChampionEntries.clear();
- for (uint8 i = 0; i < vHealersEntries.size(); ++i)
- vChampionEntries.push_back(vHealersEntries[i]);
- for (uint8 i = 0; i < vOtherEntries.size(); ++i)
- vChampionEntries.push_back(vOtherEntries[i]);
+ std::vector<uint32> vChampionEntries;
+ vChampionEntries.clear();
+ for (uint8 i = 0; i < vHealersEntries.size(); ++i)
+ vChampionEntries.push_back(vHealersEntries[i]);
+ for (uint8 i = 0; i < vOtherEntries.size(); ++i)
+ vChampionEntries.push_back(vOtherEntries[i]);
- return vChampionEntries;
- }
+ return vChampionEntries;
+ }
- void SummonChampions(Team playerTeam)
- {
- std::vector<Position> vChampionJumpOrigin;
- if (playerTeam == ALLIANCE)
- for (uint8 i = 0; i < 5; i++)
- vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
- else
- for (uint8 i = 5; i < 10; i++)
- vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
+ void SummonChampions(Team playerTeam)
+ {
+ std::vector<Position> vChampionJumpOrigin;
+ if (playerTeam == ALLIANCE)
+ for (uint8 i = 0; i < 5; i++)
+ vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
+ else
+ for (uint8 i = 5; i < 10; i++)
+ vChampionJumpOrigin.push_back(FactionChampionLoc[i]);
- std::vector<Position> vChampionJumpTarget;
- for (uint8 i = 10; i < 20; i++)
- vChampionJumpTarget.push_back(FactionChampionLoc[i]);
- std::vector<uint32> vChampionEntries = SelectChampions(playerTeam);
+ std::vector<Position> vChampionJumpTarget;
+ for (uint8 i = 10; i < 20; i++)
+ vChampionJumpTarget.push_back(FactionChampionLoc[i]);
+ std::vector<uint32> vChampionEntries = SelectChampions(playerTeam);
- for (uint8 i = 0; i < vChampionEntries.size(); ++i)
- {
- uint8 pos = urand(0, vChampionJumpTarget.size()-1);
- if (Creature* temp = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN))
+ for (uint8 i = 0; i < vChampionEntries.size(); ++i)
{
- Summons.Summon(temp);
- temp->SetReactState(REACT_PASSIVE);
- temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
- if (playerTeam == ALLIANCE)
+ uint8 pos = urand(0, vChampionJumpTarget.size()-1);
+ if (Creature* temp = me->SummonCreature(vChampionEntries[i], vChampionJumpOrigin[urand(0, vChampionJumpOrigin.size()-1)], TEMPSUMMON_MANUAL_DESPAWN))
{
- temp->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0);
- temp->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f);
- temp->SetOrientation(0);
- }
- else
- {
- temp->SetHomePosition((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3);
- temp->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f);
- temp->SetOrientation(3);
+ _summons.Summon(temp);
+ temp->SetReactState(REACT_PASSIVE);
+ temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ if (playerTeam == ALLIANCE)
+ {
+ temp->SetHomePosition(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 0);
+ temp->GetMotionMaster()->MoveJump(vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f);
+ temp->SetOrientation(0);
+ }
+ else
+ {
+ temp->SetHomePosition((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 3);
+ temp->GetMotionMaster()->MoveJump((ToCCommonLoc[1].GetPositionX()*2)-vChampionJumpTarget[pos].GetPositionX(), vChampionJumpTarget[pos].GetPositionY(), vChampionJumpTarget[pos].GetPositionZ(), 20.0f, 20.0f);
+ temp->SetOrientation(3);
+ }
}
+ vChampionJumpTarget.erase(vChampionJumpTarget.begin()+pos);
}
- vChampionJumpTarget.erase(vChampionJumpTarget.begin()+pos);
}
- }
- void SetData(uint32 uiType, uint32 uiData)
- {
- switch (uiType)
+ void SetData(uint32 uiType, uint32 uiData)
{
- case 0:
- SummonChampions((Team)uiData);
- break;
- case 1:
- for (std::list<uint64>::iterator i = Summons.begin(); i != Summons.end(); ++i)
- {
- if (Creature* temp = Unit::GetCreature(*me, *i))
+ switch (uiType)
+ {
+ case 0:
+ SummonChampions((Team)uiData);
+ break;
+ case 1:
+ for (std::list<uint64>::iterator i = _summons.begin(); i != _summons.end(); ++i)
{
- temp->SetReactState(REACT_AGGRESSIVE);
- temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
- }
- }
- break;
- case 2:
- switch (uiData)
- {
- case FAIL:
- m_uiChampionsFailed++;
- if (m_uiChampionsFailed + m_uiChampionsKilled >= Summons.size())
- {
- instance->SetData(TYPE_CRUSADERS, FAIL);
- Summons.DespawnAll();
- me->DespawnOrUnsummon();
- }
- break;
- case IN_PROGRESS:
- if (!m_bInProgress)
- {
- m_uiChampionsNotStarted = 0;
- m_uiChampionsFailed = 0;
- m_uiChampionsKilled = 0;
- m_bInProgress = true;
- Summons.DoZoneInCombat();
- instance->SetData(TYPE_CRUSADERS, IN_PROGRESS);
- }
- break;
- case DONE:
- m_uiChampionsKilled++;
- if (m_uiChampionsKilled == 1)
- instance->SetData(TYPE_CRUSADERS, SPECIAL);
- else if (m_uiChampionsKilled >= Summons.size())
+ if (Creature* temp = Unit::GetCreature(*me, *i))
{
- instance->SetData(TYPE_CRUSADERS, DONE);
- Summons.DespawnAll();
- me->DespawnOrUnsummon();
+ temp->SetReactState(REACT_AGGRESSIVE);
+ temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
}
- break;
- }
- break;
+ }
+ break;
+ case 2:
+ switch (uiData)
+ {
+ case FAIL:
+ _championsFailed++;
+ if (_championsFailed + _championsKilled >= _summons.size())
+ {
+ _instance->SetBossState(BOSS_CRUSADERS, FAIL);
+ _summons.DespawnAll();
+ me->DespawnOrUnsummon();
+ }
+ break;
+ case IN_PROGRESS:
+ if (!_inProgress)
+ {
+ _championsNotStarted = 0;
+ _championsFailed = 0;
+ _championsKilled = 0;
+ _inProgress = true;
+ _summons.DoZoneInCombat();
+ _instance->SetBossState(BOSS_CRUSADERS, IN_PROGRESS);
+ }
+ break;
+ case DONE:
+ _championsKilled++;
+ if (_championsKilled == 1)
+ _instance->SetBossState(BOSS_CRUSADERS, SPECIAL);
+ else if (_championsKilled >= _summons.size())
+ {
+ _instance->SetBossState(BOSS_CRUSADERS, DONE);
+ _summons.DespawnAll();
+ me->DespawnOrUnsummon();
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
}
- }
- };
+ private:
+ InstanceScript* _instance;
+ SummonList _summons;
+ uint32 _championsNotStarted;
+ uint32 _championsFailed;
+ uint32 _championsKilled;
+ bool _inProgress;
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_toc_champion_controllerAI (creature);
+ }
};
-struct boss_faction_championsAI : public ScriptedAI
+struct boss_faction_championsAI : public BossAI
{
- boss_faction_championsAI(Creature* creature, uint32 aitype) : ScriptedAI(creature)
+ boss_faction_championsAI(Creature* creature, uint32 aitype) : BossAI(creature, BOSS_CRUSADERS)
{
- instance = creature->GetInstanceScript();
- mAIType = aitype;
+ _aiType = aitype;
}
- InstanceScript* instance;
-
- uint64 championControllerGUID;
- uint32 mAIType;
- uint32 ThreatTimer;
- uint32 CCTimer;
-
void Reset()
{
- championControllerGUID = 0;
- CCTimer = rand()%10000;
- ThreatTimer = 5000;
+ _events.ScheduleEvent(EVENT_THREAT, 5*IN_MILLISECONDS);
+ if (IsHeroic() && (_aiType != AI_PET))
+ _events.ScheduleEvent(EVENT_REMOVE_CC, 5*IN_MILLISECONDS);
}
void JustReachedHome()
@@ -284,9 +566,9 @@ struct boss_faction_championsAI : public ScriptedAI
float CalculateThreat(float distance, float armor, uint32 health)
{
- float dist_mod = (mAIType == AI_MELEE || mAIType == AI_PET) ? 15.0f/(15.0f + distance) : 1.0f;
- float armor_mod = (mAIType == AI_MELEE || mAIType == AI_PET) ? armor / 16635.0f : 0.0f;
- float eh = (health+1) * (1.0f + armor_mod);
+ float dist_mod = (_aiType == AI_MELEE || _aiType == AI_PET) ? 15.0f / (15.0f + distance) : 1.0f;
+ float armor_mod = (_aiType == AI_MELEE || _aiType == AI_PET) ? armor / 16635.0f : 0.0f;
+ float eh = (health + 1) * (1.0f + armor_mod);
return dist_mod * 30000.0f / eh;
}
@@ -298,7 +580,7 @@ struct boss_faction_championsAI : public ScriptedAI
Unit* unit = Unit::GetUnit(*me, (*itr)->getUnitGuid());
if (unit && me->getThreatManager().getThreat(unit))
{
- if (unit->GetTypeId()==TYPEID_PLAYER)
+ if (unit->GetTypeId() == TYPEID_PLAYER)
{
float threat = CalculateThreat(me->GetDistance2d(unit), (float)unit->GetArmor(), unit->GetHealth());
me->getThreatManager().modifyThreatPercent(unit, -100);
@@ -312,8 +594,6 @@ struct boss_faction_championsAI : public ScriptedAI
{
if (me->getPowerType() == POWER_MANA)
me->ModifyPower(POWER_MANA, me->GetMaxPower(POWER_MANA) / 3);
- //else if (me->getPowerType() == POWER_ENERGY)
- // me->ModifyPower(POWER_ENERGY, 100);
}
void RemoveCC()
@@ -328,7 +608,7 @@ struct boss_faction_championsAI : public ScriptedAI
void JustDied(Unit* /*killer*/)
{
- if (mAIType != AI_PET)
+ if (_aiType != AI_PET)
if (instance)
if (Creature* pChampionController = Unit::GetCreature((*me), instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
pChampionController->AI()->SetData(2, DONE);
@@ -337,7 +617,7 @@ struct boss_faction_championsAI : public ScriptedAI
void EnterCombat(Unit* /*who*/)
{
DoCast(me, SPELL_ANTI_AOE, true);
- me->SetInCombatWithZone();
+ _EnterCombat();
if (instance)
if (Creature* pChampionController = Unit::GetCreature((*me), instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
pChampionController->AI()->SetData(2, IN_PROGRESS);
@@ -377,7 +657,7 @@ struct boss_faction_championsAI : public ScriptedAI
std::list<Creature*>::const_iterator itr = lst.begin();
if (lst.empty())
return NULL;
- advance(itr, rand()%lst.size());
+ advance(itr, rand() % lst.size());
return (*itr);
}
@@ -401,7 +681,7 @@ struct boss_faction_championsAI : public ScriptedAI
std::list<HostileReference*>::const_iterator iter;
uint32 count = 0;
Unit* target;
- for (iter = tList.begin(); iter!=tList.end(); ++iter)
+ for (iter = tList.begin(); iter != tList.end(); ++iter)
{
target = Unit::GetUnit(*me, (*iter)->getUnitGuid());
if (target && me->GetDistance2d(target) < distance)
@@ -421,7 +701,7 @@ struct boss_faction_championsAI : public ScriptedAI
me->SetInCombatWith(who);
who->SetInCombatWith(me);
- if (mAIType == AI_MELEE || mAIType == AI_PET)
+ if (_aiType == AI_MELEE || _aiType == AI_PET)
DoStartMovement(who);
else
DoStartMovement(who, 20.0f);
@@ -429,1642 +709,1666 @@ struct boss_faction_championsAI : public ScriptedAI
}
}
- void UpdateAI(const uint32 uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (ThreatTimer < uiDiff)
- {
- UpdatePower();
- UpdateThreat();
- ThreatTimer = 4000;
- }
- else ThreatTimer -= uiDiff;
+ _events.Update(diff);
- if (mAIType != AI_PET)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (CCTimer < uiDiff)
- {
- RemoveCC();
- CCTimer = 8000+rand()%2000;
+ switch (eventId)
+ {
+ case EVENT_THREAT:
+ UpdatePower();
+ UpdateThreat();
+ _events.ScheduleEvent(EVENT_THREAT, 4*IN_MILLISECONDS);
+ return;
+ case EVENT_REMOVE_CC:
+ if (me->HasBreakableByDamageCrowdControlAura())
+ {
+ RemoveCC();
+ _events.RescheduleEvent(EVENT_REMOVE_CC, 2*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ _events.RescheduleEvent(EVENT_REMOVE_CC, 3*IN_MILLISECONDS);
+ return;
+ default:
+ return;
}
- else CCTimer -= uiDiff;
}
- if (mAIType == AI_MELEE || mAIType == AI_PET) DoMeleeAttackIfReady();
+ if (_aiType == AI_MELEE || _aiType == AI_PET)
+ DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 _aiType;
+ // make sure that every bosses separate events dont mix with these _events
+ EventMap _events;
};
/********************************************************************
HEALERS
********************************************************************/
-enum eDruidSpells
-{
- SPELL_LIFEBLOOM = 66093,
- SPELL_NOURISH = 66066,
- SPELL_REGROWTH = 66067,
- SPELL_REJUVENATION = 66065,
- SPELL_TRANQUILITY = 66086,
- SPELL_BARKSKIN = 65860, //1 min cd
- SPELL_THORNS = 66068,
- SPELL_NATURE_GRASP = 66071, //1 min cd, self buff
-};
-
class mob_toc_druid : public CreatureScript
{
-public:
- mob_toc_druid() : CreatureScript("mob_toc_druid") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_druidAI (creature);
- }
-
- struct mob_toc_druidAI : public boss_faction_championsAI
- {
- mob_toc_druidAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
-
- uint32 m_uiNatureGraspTimer;
- uint32 m_uiTranquilityTimer;
- uint32 m_uiBarkskinTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiNatureGraspTimer = IN_MILLISECONDS;
- m_uiTranquilityTimer = IN_MILLISECONDS;
- m_uiBarkskinTimer = IN_MILLISECONDS;
- m_uiCommonTimer = IN_MILLISECONDS;
- SetEquipmentSlots(false, 51799, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_druid() : CreatureScript("mob_toc_druid") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_druidAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_druidAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_LIFEBLOOM, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_NOURISH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_REGROWTH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_REJUVENATION, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_TRANQUILITY, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEAL_BARKSKIN, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_THORNS, 2*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_NATURE_GRASP, urand(3*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 51799, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- if (m_uiNatureGraspTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- DoCast(me, SPELL_NATURE_GRASP);
- m_uiNatureGraspTimer = urand(40*IN_MILLISECONDS, 80*IN_MILLISECONDS);
- } else m_uiNatureGraspTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiTranquilityTimer <= uiDiff)
- {
- DoCastAOE(SPELL_TRANQUILITY);
- m_uiTranquilityTimer = urand(40*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- } else m_uiTranquilityTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiBarkskinTimer <= uiDiff)
- {
- if (HealthBelowPct(50))
- DoCast(me, SPELL_BARKSKIN);
- m_uiBarkskinTimer = urand(45*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- } else m_uiBarkskinTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 4))
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0:
- DoCast(me, SPELL_LIFEBLOOM);
- break;
- case 1:
- DoCast(me, SPELL_NOURISH);
- break;
- case 2:
- DoCast(me, SPELL_REGROWTH);
- break;
- case 3:
- DoCast(me, SPELL_REJUVENATION);
- break;
- case 4:
- if (Creature* target = SelectRandomFriendlyMissingBuff(SPELL_THORNS))
- DoCast(target, SPELL_THORNS);
- break;
+ switch (eventId)
+ {
+ case EVENT_LIFEBLOOM:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_LIFEBLOOM);
+ events.ScheduleEvent(EVENT_LIFEBLOOM, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_NOURISH:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_NOURISH);
+ events.ScheduleEvent(EVENT_NOURISH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_REGROWTH:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_REGROWTH);
+ events.ScheduleEvent(EVENT_REGROWTH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_REJUVENATION:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_REJUVENATION);
+ events.ScheduleEvent(EVENT_REJUVENATION, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_TRANQUILITY:
+ DoCastAOE(SPELL_TRANQUILITY);
+ events.ScheduleEvent(EVENT_TRANQUILITY, urand(15*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_BARKSKIN:
+ if (HealthBelowPct(30))
+ {
+ DoCast(me, SPELL_BARKSKIN);
+ events.RescheduleEvent(EVENT_HEAL_BARKSKIN, 60*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_HEAL_BARKSKIN, 3*IN_MILLISECONDS);
+ return;
+ case EVENT_THORNS:
+ if (Creature* target = SelectRandomFriendlyMissingBuff(SPELL_THORNS))
+ DoCast(target, SPELL_THORNS);
+ events.ScheduleEvent(EVENT_THORNS, urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ return;
+ case EVENT_NATURE_GRASP:
+ DoCast(me, SPELL_NATURE_GRASP);
+ events.ScheduleEvent(EVENT_NATURE_GRASP, 60*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_druidAI (creature);
}
- };
-
-};
-
-enum eShamanSpells
-{
- SPELL_HEALING_WAVE = 66055,
- SPELL_RIPTIDE = 66053,
- SPELL_SPIRIT_CLEANSE = 66056, //friendly only
- SPELL_HEROISM = 65983,
- SPELL_BLOODLUST = 65980,
- SPELL_HEX = 66054,
- SPELL_EARTH_SHIELD = 66063,
- SPELL_EARTH_SHOCK = 65973,
- AURA_EXHAUSTION = 57723,
- AURA_SATED = 57724,
};
class mob_toc_shaman : public CreatureScript
{
-public:
- mob_toc_shaman() : CreatureScript("mob_toc_shaman") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_shamanAI (creature);
- }
-
- struct mob_toc_shamanAI : public boss_faction_championsAI
- {
- mob_toc_shamanAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
-
- uint32 m_uiHeroismOrBloodlustTimer;
- uint32 m_uiHexTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiHeroismOrBloodlustTimer = IN_MILLISECONDS;
- m_uiHexTimer = IN_MILLISECONDS;
- m_uiCommonTimer = IN_MILLISECONDS;
- SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_shaman() : CreatureScript("mob_toc_shaman") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_shamanAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_shamanAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_HEALING_WAVE, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_RIPTIDE, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SPIRIT_CLEANSE, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEAL_BLOODLUST_HEROISM, 20*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_HEX, urand(5*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_EARTH_SHIELD, 1*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_HEAL_EARTH_SHOCK, urand(5*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- if (m_uiHeroismOrBloodlustTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (me->getFaction()) //Am i alliance?
- {
- if (!me->HasAura(AURA_EXHAUSTION))
- DoCastAOE(SPELL_HEROISM);
- }
- else
- if (!me->HasAura(AURA_SATED))
- DoCastAOE(SPELL_BLOODLUST);
- m_uiHeroismOrBloodlustTimer = 300*IN_MILLISECONDS;
- } else m_uiHeroismOrBloodlustTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiHexTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_HEX);
- m_uiHexTimer = urand(10*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiHexTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 5))
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0: case 1:
- DoCast(me, SPELL_HEALING_WAVE);
- break;
- case 2:
- DoCast(me, SPELL_RIPTIDE);
- break;
- case 3:
- DoCast(me, SPELL_EARTH_SHOCK);
- break;
- case 4:
- DoCast(me, SPELL_SPIRIT_CLEANSE);
- break;
- case 5:
- if (Unit* target = SelectRandomFriendlyMissingBuff(SPELL_EARTH_SHIELD))
- DoCast(target, SPELL_EARTH_SHIELD);
- break;
+ switch (eventId)
+ {
+ case EVENT_HEALING_WAVE:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_HEALING_WAVE);
+ events.ScheduleEvent(EVENT_HEALING_WAVE, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ return;
+ case EVENT_RIPTIDE:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_RIPTIDE);
+ events.ScheduleEvent(EVENT_RIPTIDE, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_SPIRIT_CLEANSE:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_SPIRIT_CLEANSE);
+ events.ScheduleEvent(EVENT_SPIRIT_CLEANSE, urand(15*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_BLOODLUST_HEROISM:
+ if (me->getFaction()) // alliance = 1
+ {
+ if (!me->HasAura(AURA_EXHAUSTION))
+ DoCastAOE(SPELL_HEROISM);
+ }
+ else
+ {
+ if (!me->HasAura(AURA_SATED))
+ DoCastAOE(SPELL_BLOODLUST);
+ }
+ events.ScheduleEvent(EVENT_HEAL_BLOODLUST_HEROISM, 5*MINUTE*IN_MILLISECONDS);
+ return;
+ case EVENT_HEX:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ DoCast(target, SPELL_HEX);
+ events.ScheduleEvent(EVENT_HEX, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_EARTH_SHIELD:
+ if (Creature* target = SelectRandomFriendlyMissingBuff(SPELL_EARTH_SHIELD))
+ DoCast(target, SPELL_EARTH_SHIELD);
+ events.ScheduleEvent(EVENT_EARTH_SHIELD, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_EARTH_SHOCK:
+ if (Unit* target = SelectEnemyCaster(true))
+ DoCast(target, SPELL_EARTH_SHOCK);
+ events.ScheduleEvent(EVENT_HEAL_EARTH_SHOCK, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_shamanAI (creature);
}
- };
-
-};
-
-enum ePaladinSpells
-{
- SPELL_HAND_OF_FREEDOM = 68757, //25 sec cd
- SPELL_BUBBLE = 66010, //5 min cd
- SPELL_CLEANSE = 66116,
- SPELL_FLASH_OF_LIGHT = 66113,
- SPELL_HOLY_LIGHT = 66112,
- SPELL_HOLY_SHOCK = 66114,
- SPELL_HAND_OF_PROTECTION = 66009,
- SPELL_HAMMER_OF_JUSTICE = 66613,
};
class mob_toc_paladin : public CreatureScript
{
-public:
- mob_toc_paladin() : CreatureScript("mob_toc_paladin") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_paladinAI (creature);
- }
-
- struct mob_toc_paladinAI : public boss_faction_championsAI
- {
- mob_toc_paladinAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
-
- uint32 m_uiBubbleTimer;
- uint32 m_uiHandOfProtectionTimer;
- uint32 m_uiHolyShockTimer;
- uint32 m_uiHandOfFreedomTimer;
- uint32 m_uiHammerOfJusticeTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiBubbleTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- m_uiHandOfProtectionTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- m_uiHolyShockTimer = urand(6*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiHandOfFreedomTimer = urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- m_uiHammerOfJusticeTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 50771, 47079, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_paladin() : CreatureScript("mob_toc_paladin") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_paladinAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
-
- if (m_uiBubbleTimer <= uiDiff)
- {
- //cast bubble at 20% hp
- if (HealthBelowPct(20))
- DoCast(me, SPELL_BUBBLE);
- m_uiBubbleTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- } else m_uiBubbleTimer -= uiDiff;
+ mob_toc_paladinAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_HAND_OF_FREEDOM, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEAL_DIVINE_SHIELD, 20*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_CLEANSE, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FLASH_OF_LIGHT, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HOLY_LIGHT, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HOLY_SHOCK, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEAL_HAND_OF_PROTECTION, urand(30*IN_MILLISECONDS, 60*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 50771, 47079, EQUIP_NO_CHANGE);
+ }
- if (m_uiHandOfProtectionTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (Unit* target = DoSelectLowestHpFriendly(40.0f))
- if (target->HealthBelowPct(15))
- DoCast(target, SPELL_HAND_OF_PROTECTION);
- m_uiHandOfProtectionTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- } else m_uiHandOfProtectionTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiHolyShockTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_HOLY_SHOCK);
- m_uiHolyShockTimer = urand(6*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiHolyShockTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiHandOfFreedomTimer <= uiDiff)
- {
- if (Unit* target = SelectRandomFriendlyMissingBuff(SPELL_HAND_OF_FREEDOM))
- DoCast(target, SPELL_HAND_OF_FREEDOM);
- m_uiHandOfFreedomTimer = urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiHandOfFreedomTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiHammerOfJusticeTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_HAMMER_OF_JUSTICE);
- m_uiHammerOfJusticeTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiHammerOfJusticeTimer -= uiDiff;
-
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 4))
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0: case 1:
- DoCast(me, SPELL_FLASH_OF_LIGHT);
- break;
- case 2: case 3:
- DoCast(me, SPELL_HOLY_LIGHT);
- break;
- case 4:
- DoCast(me, SPELL_CLEANSE);
- break;
+ switch (eventId)
+ {
+ case EVENT_HAND_OF_FREEDOM:
+ if (Unit* target = SelectRandomFriendlyMissingBuff(SPELL_HAND_OF_FREEDOM))
+ DoCast(target, SPELL_HAND_OF_FREEDOM);
+ events.ScheduleEvent(EVENT_HAND_OF_FREEDOM, urand(15*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_DIVINE_SHIELD:
+ if (HealthBelowPct(30) && !me->HasAura(SPELL_FORBEARANCE))
+ {
+ DoCast(me, SPELL_DIVINE_SHIELD);
+ events.RescheduleEvent(EVENT_HEAL_DIVINE_SHIELD, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_HEAL_DIVINE_SHIELD, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_CLEANSE:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_CLEANSE);
+ events.ScheduleEvent(EVENT_CLEANSE, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_FLASH_OF_LIGHT:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_FLASH_OF_LIGHT);
+ events.ScheduleEvent(EVENT_FLASH_OF_LIGHT, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ return;
+ case EVENT_HOLY_LIGHT:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_HOLY_LIGHT);
+ events.ScheduleEvent(EVENT_HOLY_LIGHT, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_HOLY_SHOCK:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_HOLY_SHOCK);
+ events.ScheduleEvent(EVENT_HOLY_SHOCK, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_HAND_OF_PROTECTION:
+ if (Unit* target = DoSelectLowestHpFriendly(30.0f))
+ {
+ if (!target->HasAura(SPELL_FORBEARANCE))
+ {
+ DoCast(target, SPELL_HAND_OF_PROTECTION);
+ events.RescheduleEvent(EVENT_HEAL_HAND_OF_PROTECTION, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_HEAL_HAND_OF_PROTECTION, 3*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_HEAL_HAND_OF_PROTECTION, 10*IN_MILLISECONDS);
+ return;
+ case EVENT_HAMMER_OF_JUSTICE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 15.0f, true))
+ DoCast(target, SPELL_HAMMER_OF_JUSTICE);
+ events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, 40*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_paladinAI (creature);
}
- };
-
-};
-
-enum ePriestSpells
-{
- SPELL_RENEW = 66177,
- SPELL_SHIELD = 66099,
- SPELL_FLASH_HEAL = 66104,
- SPELL_DISPEL = 65546,
- SPELL_PSYCHIC_SCREAM = 65543,
- SPELL_MANA_BURN = 66100,
};
class mob_toc_priest : public CreatureScript
{
-public:
- mob_toc_priest() : CreatureScript("mob_toc_priest") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_priestAI (creature);
- }
-
- struct mob_toc_priestAI : public boss_faction_championsAI
- {
- mob_toc_priestAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
-
- uint32 m_uiPsychicScreamTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiPsychicScreamTimer = IN_MILLISECONDS;
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_priest() : CreatureScript("mob_toc_priest") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_priestAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_priestAI(Creature* creature) : boss_faction_championsAI(creature, AI_HEALER) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_RENEW, urand(3*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SHIELD, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FLASH_HEAL, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEAL_DISPEL, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEAL_PSYCHIC_SCREAM, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_MANA_BURN, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_PENANCE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- if (m_uiPsychicScreamTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (EnemiesInRange(10.0f) > 2)
- DoCastAOE(SPELL_PSYCHIC_SCREAM);
- m_uiPsychicScreamTimer = urand(5*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiPsychicScreamTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 5))
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0:
- DoCast(me, SPELL_RENEW);
- break;
- case 1:
- DoCast(me, SPELL_SHIELD);
- break;
- case 2: case 3:
- DoCast(me, SPELL_FLASH_HEAL);
- break;
- case 4:
- if (Unit* target = urand(0, 1) ? SelectTarget(SELECT_TARGET_RANDOM, 0) : DoSelectLowestHpFriendly(40.0f))
- DoCast(target, SPELL_DISPEL);
- break;
- case 5:
- DoCast(me, SPELL_MANA_BURN);
- break;
+ switch (eventId)
+ {
+ case EVENT_RENEW:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_RENEW);
+ events.ScheduleEvent(EVENT_RENEW, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ return;
+ case EVENT_SHIELD:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_SHIELD);
+ events.ScheduleEvent(EVENT_SHIELD, urand(15*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_FLASH_HEAL:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_FLASH_HEAL);
+ events.ScheduleEvent(EVENT_FLASH_HEAL, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_DISPEL:
+ if (Unit* target = urand(0, 1) ? SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) : DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_DISPEL);
+ events.ScheduleEvent(EVENT_HEAL_DISPEL, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_HEAL_PSYCHIC_SCREAM:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_PSYCHIC_SCREAM);
+ events.ScheduleEvent(EVENT_HEAL_PSYCHIC_SCREAM, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_MANA_BURN:
+ if (Unit* target = SelectEnemyCaster(false))
+ DoCast(target, SPELL_MANA_BURN);
+ events.ScheduleEvent(EVENT_MANA_BURN, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_PENANCE:
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_PENANCE);
+ events.ScheduleEvent(EVENT_PENANCE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_priestAI (creature);
}
- };
-
};
/********************************************************************
RANGED
********************************************************************/
-enum eShadowPriestSpells
-{
- SPELL_SILENCE = 65542,
- SPELL_VAMPIRIC_TOUCH = 65490,
- SPELL_SW_PAIN = 65541,
- SPELL_MIND_FLAY = 65488,
- SPELL_MIND_BLAST = 65492,
- SPELL_HORROR = 65545,
- SPELL_DISPERSION = 65544,
- SPELL_SHADOWFORM = 16592,
-};
-
class mob_toc_shadow_priest : public CreatureScript
{
-public:
- mob_toc_shadow_priest() : CreatureScript("mob_toc_shadow_priest") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_shadow_priestAI (creature);
- }
-
- struct mob_toc_shadow_priestAI : public boss_faction_championsAI
- {
- mob_toc_shadow_priestAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
-
- uint32 m_uiPsychicScreamTimer;
- uint32 m_uiDispersionTimer;
- uint32 m_uiSilenceTimer;
- uint32 m_uiMindBlastTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiPsychicScreamTimer = urand(5*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiDispersionTimer = urand(1*IN_MILLISECONDS, 180*IN_MILLISECONDS);
- m_uiSilenceTimer = urand(8*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiMindBlastTimer = urand(3*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 50040, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- DoCast(me, SPELL_SHADOWFORM);
- }
-
- void EnterCombat(Unit* who)
- {
- boss_faction_championsAI::EnterCombat(who);
- }
+ public:
+ mob_toc_shadow_priest() : CreatureScript("mob_toc_shadow_priest") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_shadow_priestAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
-
- if (m_uiPsychicScreamTimer <= uiDiff)
- {
- if (EnemiesInRange(10.0f) > 2)
- DoCastAOE(SPELL_PSYCHIC_SCREAM);
- m_uiPsychicScreamTimer = urand(5*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiPsychicScreamTimer -= uiDiff;
+ mob_toc_shadow_priestAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_SILENCE, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_VAMPIRIC_TOUCH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SW_PAIN, urand(3*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_MIND_BLAST, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HORROR, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DISPERSION, urand(20*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DPS_DISPEL, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DPS_PSYCHIC_SCREAM, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 50040, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ DoCast(me, SPELL_SHADOWFORM);
+ }
- if (m_uiDispersionTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (HealthBelowPct(20))
- DoCast(me, SPELL_DISPERSION);
- m_uiDispersionTimer = urand(1*IN_MILLISECONDS, 180*IN_MILLISECONDS);
- } else m_uiDispersionTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiSilenceTimer <= uiDiff)
- {
- if (Unit* target = SelectEnemyCaster(false))
- DoCast(target, SPELL_SILENCE);
- m_uiSilenceTimer = urand(8*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiSilenceTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiMindBlastTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_MIND_BLAST);
- m_uiMindBlastTimer = urand(3*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- } else m_uiMindBlastTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 4))
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0: case 1:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_MIND_FLAY);
- break;
- case 2:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_VAMPIRIC_TOUCH);
- break;
- case 3:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_SW_PAIN);
- break;
- case 4:
- if (Unit* target = urand(0, 1) ? SelectTarget(SELECT_TARGET_RANDOM, 0) : DoSelectLowestHpFriendly(40.0f))
- DoCast(target, SPELL_DISPEL);
- break;
+ switch (eventId)
+ {
+ case EVENT_SILENCE:
+ if (Unit* target = SelectEnemyCaster(true))
+ DoCast(target, SPELL_SILENCE);
+ events.ScheduleEvent(EVENT_SILENCE, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_VAMPIRIC_TOUCH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true))
+ DoCast(target, SPELL_VAMPIRIC_TOUCH);
+ events.ScheduleEvent(EVENT_VAMPIRIC_TOUCH, urand(10*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_SW_PAIN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
+ DoCast(target, SPELL_SW_PAIN);
+ events.ScheduleEvent(EVENT_SW_PAIN, urand(10*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_MIND_BLAST:
+ DoCastVictim(SPELL_MIND_BLAST);
+ events.ScheduleEvent(EVENT_MIND_BLAST, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_HORROR:
+ DoCastVictim(SPELL_HORROR);
+ events.ScheduleEvent(EVENT_HORROR, urand(15*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_DISPERSION:
+ if (HealthBelowPct(40))
+ {
+ DoCast(me, SPELL_DISPERSION);
+ events.RescheduleEvent(EVENT_DISPERSION, 180*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DISPERSION, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_DPS_DISPEL:
+ if (Unit* target = urand(0, 1) ? SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true) : DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_DISPEL);
+ events.ScheduleEvent(EVENT_DPS_DISPEL, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_DPS_PSYCHIC_SCREAM:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_PSYCHIC_SCREAM);
+ events.ScheduleEvent(EVENT_DPS_PSYCHIC_SCREAM, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ DoSpellAttackIfReady(SPELL_MIND_FLAY);
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_shadow_priestAI (creature);
}
- };
-
-};
-
-enum WarlockSpells
-{
- SPELL_HELLFIRE = 65816,
- SPELL_CORRUPTION = 65810,
- SPELL_CURSE_OF_AGONY = 65814,
- SPELL_CURSE_OF_EXHAUSTION = 65815,
- SPELL_FEAR = 65809, // 8s
- SPELL_SEARING_PAIN = 65819,
- SPELL_SHADOW_BOLT = 65821,
- SPELL_UNSTABLE_AFFLICTION = 65812, // 15s
- SPELL_UNSTABLE_AFFLICTION_DISPEL = 65813,
- SPELL_SUMMON_FELHUNTER = 67514,
};
class mob_toc_warlock : public CreatureScript
{
-public:
- mob_toc_warlock() : CreatureScript("mob_toc_warlock") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_warlockAI (creature);
- }
-
- struct mob_toc_warlockAI : public boss_faction_championsAI
- {
- mob_toc_warlockAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED), Summons(me) {}
-
- SummonList Summons;
-
- uint32 m_uiFearTimer;
- uint32 m_uiHellfireTimer;
- uint32 m_uiUnstableAfflictionTimer;
- uint32 m_uiCommonTimer;
- uint32 m_uiSummonPetTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiFearTimer = urand(4*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiHellfireTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- m_uiUnstableAfflictionTimer = urand(2*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
-
- m_uiSummonPetTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- DoCast(SPELL_SUMMON_FELHUNTER);
- }
+ public:
+ mob_toc_warlock() : CreatureScript("mob_toc_warlock") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_warlockAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_warlockAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_HELLFIRE, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_CORRUPTION, urand(2*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_CURSE_OF_AGONY, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_CURSE_OF_EXHAUSTION, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FEAR, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SEARING_PAIN, urand(5*IN_MILLISECONDS, 12*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_UNSTABLE_AFFLICTION, urand(7*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 49992, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- if (m_uiFearTimer <= uiDiff)
+ void EnterCombat(Unit* who)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_FEAR);
- m_uiFearTimer = urand(4*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiFearTimer -= uiDiff;
+ boss_faction_championsAI::EnterCombat(who);
+ DoCast(SPELL_SUMMON_FELHUNTER);
+ }
- if (m_uiHellfireTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (EnemiesInRange(10.0f) > 2)
- DoCastAOE(SPELL_HELLFIRE);
- m_uiHellfireTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiHellfireTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiUnstableAfflictionTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_UNSTABLE_AFFLICTION);
- m_uiUnstableAfflictionTimer = urand(2*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- } else m_uiUnstableAfflictionTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiSummonPetTimer <= uiDiff)
- {
- m_uiSummonPetTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiSummonPetTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 5))
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0: case 1:
- DoCastVictim(SPELL_SHADOW_BOLT);
- break;
- case 2:
- DoCastVictim(SPELL_SEARING_PAIN);
- break;
- case 3:
- DoCastVictim(SPELL_CORRUPTION);
- break;
- case 4:
- DoCastVictim(SPELL_CURSE_OF_AGONY);
- break;
- case 5:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CURSE_OF_EXHAUSTION);
- break;
+ switch (eventId)
+ {
+ case EVENT_HELLFIRE:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_HELLFIRE);
+ events.ScheduleEvent(EVENT_HELLFIRE, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_CORRUPTION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_CORRUPTION);
+ events.ScheduleEvent(EVENT_CORRUPTION, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_CURSE_OF_AGONY:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_CURSE_OF_AGONY);
+ events.ScheduleEvent(EVENT_CURSE_OF_AGONY, urand(20*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_CURSE_OF_EXHAUSTION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_CURSE_OF_EXHAUSTION);
+ events.ScheduleEvent(EVENT_CURSE_OF_EXHAUSTION, urand(20*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_FEAR:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, true))
+ DoCast(target, SPELL_FEAR);
+ events.ScheduleEvent(EVENT_FEAR, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_SEARING_PAIN:
+ DoCastVictim(SPELL_SEARING_PAIN);
+ events.ScheduleEvent(EVENT_SEARING_PAIN, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_UNSTABLE_AFFLICTION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true))
+ DoCast(target, SPELL_UNSTABLE_AFFLICTION);
+ events.ScheduleEvent(EVENT_UNSTABLE_AFFLICTION, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
- boss_faction_championsAI::UpdateAI(uiDiff);
- }
- };
-
-};
+ DoSpellAttackIfReady(SPELL_SHADOW_BOLT);
+ }
+ };
-enum eMageSpells
-{
- SPELL_ARCANE_BARRAGE = 65799, //3s
- SPELL_ARCANE_BLAST = 65791,
- SPELL_ARCANE_EXPLOSION = 65800,
- SPELL_BLINK = 65793, //15s
- SPELL_COUNTERSPELL = 65790, //24s
- SPELL_FROST_NOVA = 65792, //25s
- SPELL_FROSTBOLT = 65807,
- SPELL_ICE_BLOCK = 65802, //5min
- SPELL_POLYMORPH = 65801, //15s
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_warlockAI (creature);
+ }
};
class mob_toc_mage : public CreatureScript
{
-public:
- mob_toc_mage() : CreatureScript("mob_toc_mage") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_mageAI (creature);
- }
-
- struct mob_toc_mageAI : public boss_faction_championsAI
- {
- mob_toc_mageAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
-
- uint32 m_uiCounterspellTimer;
- uint32 m_uiBlinkTimer;
- uint32 m_uiIceBlockTimer;
- uint32 m_uiPolymorphTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiCounterspellTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiBlinkTimer = urand(7*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiIceBlockTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- m_uiPolymorphTimer = urand(15*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 47524, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_mage() : CreatureScript("mob_toc_mage") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_mageAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_mageAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(1*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_BLINK, urand(15*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_COUNTERSPELL, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FROST_NOVA, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ICE_BLOCK, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_POLYMORPH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 47524, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- if (m_uiCounterspellTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (Unit* target = SelectEnemyCaster(false))
- DoCast(target, SPELL_COUNTERSPELL);
- m_uiCounterspellTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiCounterspellTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiBlinkTimer <= uiDiff)
- {
- if (HealthBelowPct(50) && EnemiesInRange(10.0f) > 3)
- {
- DoCastAOE(SPELL_FROST_NOVA);
- DoCast(SPELL_BLINK);
- }
- m_uiBlinkTimer = urand(7*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiBlinkTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiIceBlockTimer <= uiDiff)
- {
- if (HealthBelowPct(20))
- DoCast(me, SPELL_ICE_BLOCK);
- m_uiIceBlockTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- } else m_uiIceBlockTimer -= uiDiff;
-
- if (m_uiPolymorphTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_POLYMORPH);
- m_uiPolymorphTimer = urand(15*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiPolymorphTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 2))
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0:
- DoCast(me, SPELL_ARCANE_BARRAGE);
- break;
- case 1:
- DoCastVictim(SPELL_ARCANE_BLAST);
- break;
- case 2:
- DoCastVictim(SPELL_FROSTBOLT);
- break;
+ switch (eventId)
+ {
+ case EVENT_ARCANE_BARRAGE:
+ DoCastVictim(SPELL_ARCANE_BARRAGE);
+ events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(5*IN_MILLISECONDS, 7*IN_MILLISECONDS));
+ return;
+ case EVENT_ARCANE_BLAST:
+ DoCastVictim(SPELL_ARCANE_BLAST);
+ events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_ARCANE_EXPLOSION:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_ARCANE_EXPLOSION);
+ events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_BLINK:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCast(SPELL_BLINK);
+ events.ScheduleEvent(EVENT_BLINK, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_COUNTERSPELL:
+ if (Unit* target = SelectEnemyCaster(true))
+ DoCast(target, SPELL_COUNTERSPELL);
+ events.ScheduleEvent(EVENT_COUNTERSPELL, 24*IN_MILLISECONDS);
+ return;
+ case EVENT_FROST_NOVA:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_FROST_NOVA);
+ events.ScheduleEvent(EVENT_FROST_NOVA, 25*IN_MILLISECONDS);
+ return;
+ case EVENT_ICE_BLOCK:
+ if (HealthBelowPct(30))
+ {
+ DoCast(SPELL_ICE_BLOCK);
+ events.RescheduleEvent(EVENT_ICE_BLOCK, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_ICE_BLOCK, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_POLYMORPH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ DoCast(target, SPELL_POLYMORPH);
+ events.ScheduleEvent(EVENT_POLYMORPH, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ DoSpellAttackIfReady(SPELL_FROSTBOLT);
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_mageAI (creature);
}
- };
-
-};
-
-enum eHunterSpells
-{
- SPELL_AIMED_SHOT = 65883,
- SPELL_DETERRENCE = 65871, //90s
- SPELL_DISENGAGE = 65869, //30s
- SPELL_EXPLOSIVE_SHOT = 65866,
- SPELL_FROST_TRAP = 65880, //30s
- SPELL_SHOOT = 65868, //1.7s
- SPELL_STEADY_SHOT = 65867, //3s
- SPELL_WING_CLIP = 66207, //6s
- SPELL_WYVERN_STING = 65877, //60s
- SPELL_CALL_PET = 67777,
};
class mob_toc_hunter : public CreatureScript
{
-public:
- mob_toc_hunter() : CreatureScript("mob_toc_hunter") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_hunterAI (creature);
- }
-
- struct mob_toc_hunterAI : public boss_faction_championsAI
- {
- mob_toc_hunterAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED), Summons(me) {}
-
- SummonList Summons;
-
- uint32 m_uiDisengageTimer;
- uint32 m_uiDeterrenceTimer;
- uint32 m_uiWyvernStingTimer;
- uint32 m_uiFrostTrapTimer;
- uint32 m_uiWingClipTimer;
- uint32 m_uiCommonTimer;
- uint32 m_uiSummonPetTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiDisengageTimer = urand(12*IN_MILLISECONDS, 20*IN_MILLISECONDS);
- m_uiDeterrenceTimer = urand(20*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- m_uiWyvernStingTimer = urand(7*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- m_uiFrostTrapTimer = urand(12*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- m_uiWingClipTimer = urand(4*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 47156, EQUIP_NO_CHANGE, 48711);
-
- m_uiSummonPetTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- DoCast(SPELL_CALL_PET);
- }
+ public:
+ mob_toc_hunter() : CreatureScript("mob_toc_hunter") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_hunterAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
-
- if (m_uiDisengageTimer <= uiDiff)
- {
- if (EnemiesInRange(10.0f) > 3)
- DoCast(SPELL_DISENGAGE);
- m_uiDisengageTimer = urand(12*IN_MILLISECONDS, 20*IN_MILLISECONDS);
- } else m_uiDisengageTimer -= uiDiff;
+ mob_toc_hunterAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_AIMED_SHOT, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DETERRENCE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DISENGAGE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_EXPLOSIVE_SHOT, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FROST_TRAP, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_STEADY_SHOT, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_WING_CLIP, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_WYVERN_STING, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 47156, EQUIP_NO_CHANGE, 48711);
+ }
- if (m_uiDeterrenceTimer <= uiDiff)
+ void EnterCombat(Unit* who)
{
- if (HealthBelowPct(20))
- DoCast(SPELL_DETERRENCE);
- m_uiDeterrenceTimer = urand(20*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- } else m_uiDeterrenceTimer -= uiDiff;
+ boss_faction_championsAI::EnterCombat(who);
+ DoCast(SPELL_CALL_PET);
+ }
- if (m_uiWyvernStingTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- DoCastVictim(SPELL_WYVERN_STING);
- m_uiWyvernStingTimer = urand(7*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- } else m_uiWyvernStingTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiFrostTrapTimer <= uiDiff)
- {
- DoCast(SPELL_FROST_TRAP);
- m_uiFrostTrapTimer = urand(12*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiFrostTrapTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiWingClipTimer <= uiDiff)
- {
- if (me->GetDistance2d(me->getVictim()) < 5.0f)
- DoCastVictim(SPELL_WING_CLIP);
- m_uiWingClipTimer = urand(4*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- } else m_uiWingClipTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiSummonPetTimer <= uiDiff)
- {
- m_uiSummonPetTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiSummonPetTimer -= uiDiff;
-
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 3))
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0: case 1:
- DoCastVictim(SPELL_SHOOT);
- break;
- case 2:
- DoCastVictim(SPELL_EXPLOSIVE_SHOT);
- break;
- case 3:
- DoCastVictim(SPELL_AIMED_SHOT);
- break;
+ switch (eventId)
+ {
+ case EVENT_AIMED_SHOT:
+ DoCastVictim(SPELL_AIMED_SHOT);
+ events.ScheduleEvent(EVENT_AIMED_SHOT, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_DETERRENCE:
+ if (HealthBelowPct(30))
+ {
+ DoCast(SPELL_DETERRENCE);
+ events.RescheduleEvent(EVENT_DETERRENCE, 150*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DETERRENCE, 10*IN_MILLISECONDS);
+ return;
+ case EVENT_DISENGAGE:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCast(SPELL_DISENGAGE);
+ events.ScheduleEvent(EVENT_DISENGAGE, 30*IN_MILLISECONDS);
+ return;
+ case EVENT_EXPLOSIVE_SHOT:
+ DoCastVictim(SPELL_EXPLOSIVE_SHOT);
+ events.ScheduleEvent(EVENT_EXPLOSIVE_SHOT, urand(6*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_FROST_TRAP:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_FROST_TRAP);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 30*IN_MILLISECONDS);
+ return;
+ case EVENT_STEADY_SHOT:
+ DoCastVictim(SPELL_STEADY_SHOT);
+ events.ScheduleEvent(EVENT_STEADY_SHOT, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_WING_CLIP:
+ if (me->GetDistance2d(me->getVictim()) < 6.0f)
+ DoCastVictim(SPELL_WING_CLIP);
+ events.ScheduleEvent(EVENT_WING_CLIP, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_WYVERN_STING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ DoCast(target, SPELL_WYVERN_STING);
+ events.ScheduleEvent(EVENT_WYVERN_STING, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ DoSpellAttackIfReady(SPELL_SHOOT);
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_hunterAI (creature);
}
- };
-
-};
-
-enum eBoomkinSpells
-{
- SPELL_CYCLONE = 65859, //6s
- SPELL_ENTANGLING_ROOTS = 65857, //10s
- SPELL_FAERIE_FIRE = 65863,
- SPELL_FORCE_OF_NATURE = 65861, //180s
- SPELL_INSECT_SWARM = 65855,
- SPELL_MOONFIRE = 65856, //5s
- SPELL_STARFIRE = 65854,
- SPELL_WRATH = 65862,
};
class mob_toc_boomkin : public CreatureScript
{
-public:
- mob_toc_boomkin() : CreatureScript("mob_toc_boomkin") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_boomkinAI (creature);
- }
-
- struct mob_toc_boomkinAI : public boss_faction_championsAI
- {
- mob_toc_boomkinAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
-
- uint32 m_uiBarkskinTimer;
- uint32 m_uiCycloneTimer;
- uint32 m_uiEntanglingRootsTimer;
- uint32 m_uiFaerieFireTimer;
- uint32 m_uiCommonTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiBarkskinTimer = urand(5*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- m_uiCycloneTimer = urand(5*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- m_uiEntanglingRootsTimer = urand(5*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- m_uiFaerieFireTimer = urand(10*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- SetEquipmentSlots(false, 50966, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_boomkin() : CreatureScript("mob_toc_boomkin") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_boomkinAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_boomkinAI(Creature* creature) : boss_faction_championsAI(creature, AI_RANGED) {}
- if (m_uiBarkskinTimer <= uiDiff)
+ void Reset()
{
- if (HealthBelowPct(50))
- DoCast(me, SPELL_BARKSKIN);
- m_uiBarkskinTimer = urand(5*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- } else m_uiBarkskinTimer -= uiDiff;
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_CYCLONE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ENTANGLING_ROOTS, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FAERIE_FIRE, urand(2*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FORCE_OF_NATURE, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_INSECT_SWARM, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_MOONFIRE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_STARFIRE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DPS_BARKSKIN, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
- if (m_uiCycloneTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CYCLONE);
- m_uiCycloneTimer = urand(5*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiCycloneTimer -= uiDiff;
+ SetEquipmentSlots(false, 50966, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- if (m_uiEntanglingRootsTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ENTANGLING_ROOTS);
- m_uiEntanglingRootsTimer = urand(5*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiEntanglingRootsTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiFaerieFireTimer <= uiDiff)
- {
- DoCastVictim(SPELL_FAERIE_FIRE);
- m_uiFaerieFireTimer = urand(10*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiFaerieFireTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiCommonTimer <= uiDiff)
- {
- switch (urand(0, 6))
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- case 0: case 1:
- DoCastVictim(SPELL_MOONFIRE);
- break;
- case 2:
- DoCastVictim(SPELL_INSECT_SWARM);
- break;
- case 3:
- DoCastVictim(SPELL_STARFIRE);
- break;
- case 4: case 5: case 6:
- DoCastVictim(SPELL_WRATH);
- break;
+ switch (eventId)
+ {
+ case EVENT_CYCLONE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ DoCast(target, SPELL_CYCLONE);
+ events.ScheduleEvent(EVENT_CYCLONE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_ENTANGLING_ROOTS:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true))
+ DoCast(target, SPELL_ENTANGLING_ROOTS);
+ events.ScheduleEvent(EVENT_ENTANGLING_ROOTS, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_FAERIE_FIRE:
+ DoCastVictim(SPELL_FAERIE_FIRE);
+ events.ScheduleEvent(EVENT_FAERIE_FIRE, urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ return;
+ case EVENT_FORCE_OF_NATURE:
+ DoCastVictim(SPELL_FORCE_OF_NATURE);
+ events.ScheduleEvent(EVENT_FORCE_OF_NATURE, 180*IN_MILLISECONDS);
+ return;
+ case EVENT_INSECT_SWARM:
+ DoCastVictim(SPELL_INSECT_SWARM);
+ events.ScheduleEvent(EVENT_INSECT_SWARM, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_MOONFIRE:
+ DoCastVictim(SPELL_MOONFIRE);
+ events.ScheduleEvent(EVENT_MOONFIRE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_STARFIRE:
+ DoCastVictim(SPELL_STARFIRE);
+ events.ScheduleEvent(EVENT_STARFIRE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_DPS_BARKSKIN:
+ if (HealthBelowPct(30))
+ {
+ DoCast(me, SPELL_BARKSKIN);
+ events.RescheduleEvent(EVENT_DPS_BARKSKIN, 60*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DPS_BARKSKIN, 5*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
}
- m_uiCommonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiCommonTimer -= uiDiff;
+ DoSpellAttackIfReady(SPELL_WRATH);
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_boomkinAI (creature);
}
- };
-
};
/********************************************************************
MELEE
********************************************************************/
-enum eWarriorSpells
-{
- SPELL_BLADESTORM = 65947,
- SPELL_INTIMIDATING_SHOUT = 65930,
- SPELL_MORTAL_STRIKE = 65926,
- SPELL_CHARGE = 68764,
- SPELL_DISARM = 65935,
- SPELL_OVERPOWER = 65924,
- SPELL_SUNDER_ARMOR = 65936,
- SPELL_SHATTERING_THROW = 65940,
- SPELL_RETALIATION = 65932,
-};
-
class mob_toc_warrior : public CreatureScript
{
-public:
- mob_toc_warrior() : CreatureScript("mob_toc_warrior") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_warriorAI (creature);
- }
-
- struct mob_toc_warriorAI : public boss_faction_championsAI
- {
- mob_toc_warriorAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
-
- uint32 m_uiBladestormTimer;
- uint32 m_uiIntimidatingShoutTimer;
- uint32 m_uiMortalStrikeTimer;
- uint32 m_uiSunderArmorTimer;
- uint32 m_uiChargeTimer;
- uint32 m_uiRetaliationTimer;
- uint32 m_uiOverpowerTimer;
- uint32 m_uiShatteringThrowTimer;
- uint32 m_uiDisarmTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiBladestormTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- m_uiIntimidatingShoutTimer = urand(10*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- m_uiMortalStrikeTimer = urand(6*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiSunderArmorTimer = urand(5*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiChargeTimer = urand(3*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiRetaliationTimer = urand(30*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- m_uiOverpowerTimer = urand(30*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- m_uiShatteringThrowTimer = urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiDisarmTimer = urand(20*IN_MILLISECONDS, 80*IN_MILLISECONDS);
- SetEquipmentSlots(false, 47427, 46964, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_warrior() : CreatureScript("mob_toc_warrior") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_warriorAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
-
- if (m_uiBladestormTimer <= uiDiff)
- {
- DoCastVictim(SPELL_BLADESTORM);
- m_uiBladestormTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiBladestormTimer -= uiDiff;
-
- if (m_uiIntimidatingShoutTimer <= uiDiff)
- {
- DoCast(me, SPELL_INTIMIDATING_SHOUT);
- m_uiIntimidatingShoutTimer = urand(10*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- } else m_uiIntimidatingShoutTimer -= uiDiff;
-
- if (m_uiMortalStrikeTimer <= uiDiff)
- {
- DoCastVictim(SPELL_MORTAL_STRIKE);
- m_uiMortalStrikeTimer = urand(6*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiMortalStrikeTimer -= uiDiff;
-
- if (m_uiSunderArmorTimer <= uiDiff)
- {
- DoCastVictim(SPELL_SUNDER_ARMOR);
- m_uiSunderArmorTimer = urand(5*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiSunderArmorTimer -= uiDiff;
-
- if (m_uiChargeTimer <= uiDiff)
- {
- DoCastVictim(SPELL_CHARGE);
- m_uiChargeTimer = urand(3*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiChargeTimer -= uiDiff;
+ mob_toc_warriorAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_BLADESTORM, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_INTIMIDATING_SHOUT, urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_WARR_CHARGE, 1*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_DISARM, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_OVERPOWER, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SUNDER_ARMOR, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SHATTERING_THROW, urand(20*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_RETALIATION, urand(5*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 47427, 46964, EQUIP_NO_CHANGE);
+ }
- if (m_uiRetaliationTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- DoCastVictim(SPELL_RETALIATION);
- m_uiRetaliationTimer = urand(30*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- } else m_uiRetaliationTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiOverpowerTimer <= uiDiff)
- {
- DoCastVictim(SPELL_OVERPOWER);
- m_uiOverpowerTimer = urand(30*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- } else m_uiOverpowerTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiShatteringThrowTimer <= uiDiff)
- {
- DoCastVictim(SPELL_SHATTERING_THROW);
- m_uiShatteringThrowTimer = urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiShatteringThrowTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiDisarmTimer <= uiDiff)
- {
- DoCastVictim(SPELL_DISARM);
- m_uiDisarmTimer = urand(20*IN_MILLISECONDS, 80*IN_MILLISECONDS);
- } else m_uiDisarmTimer -= uiDiff;
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BLADESTORM:
+ DoCastVictim(SPELL_BLADESTORM);
+ events.ScheduleEvent(EVENT_BLADESTORM, 150*IN_MILLISECONDS);
+ return;
+ case EVENT_INTIMIDATING_SHOUT:
+ DoCastAOE(SPELL_INTIMIDATING_SHOUT);
+ events.ScheduleEvent(EVENT_INTIMIDATING_SHOUT, 120*IN_MILLISECONDS);
+ return;
+ case EVENT_MORTAL_STRIKE:
+ DoCastVictim(SPELL_MORTAL_STRIKE);
+ events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(10*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_WARR_CHARGE:
+ DoCastVictim(SPELL_CHARGE);
+ events.ScheduleEvent(EVENT_WARR_CHARGE, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_DISARM:
+ DoCastVictim(SPELL_DISARM);
+ events.ScheduleEvent(EVENT_DISARM, urand(15*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ return;
+ case EVENT_OVERPOWER:
+ DoCastVictim(SPELL_OVERPOWER);
+ events.ScheduleEvent(EVENT_OVERPOWER, urand(20*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ return;
+ case EVENT_SUNDER_ARMOR:
+ DoCastVictim(SPELL_SUNDER_ARMOR);
+ events.ScheduleEvent(EVENT_SUNDER_ARMOR, urand(2*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ return;
+ case EVENT_SHATTERING_THROW:
+ if (me->getVictim()->HasAuraWithMechanic(1<<MECHANIC_IMMUNE_SHIELD))
+ {
+ DoCastVictim(SPELL_SHATTERING_THROW);
+ events.RescheduleEvent(EVENT_SHATTERING_THROW, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_SHATTERING_THROW, 3*IN_MILLISECONDS);
+ return;
+ case EVENT_RETALIATION:
+ if (HealthBelowPct(50))
+ {
+ DoCast(SPELL_RETALIATION);
+ events.RescheduleEvent(EVENT_RETALIATION, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_RETALIATION, 5*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_warriorAI (creature);
}
- };
-
-};
-
-enum eDeathKnightSpells
-{
- SPELL_CHAINS_OF_ICE = 66020, //8sec
- SPELL_DEATH_COIL = 66019, //5sec
- SPELL_DEATH_GRIP = 66017, //35sec
- SPELL_FROST_STRIKE = 66047, //6sec
- SPELL_ICEBOUND_FORTITUDE = 66023, //1min
- SPELL_ICY_TOUCH = 66021, //8sec
- SPELL_STRANGULATE = 66018, //2min
};
class mob_toc_dk : public CreatureScript
{
-public:
- mob_toc_dk() : CreatureScript("mob_toc_dk") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_dkAI (creature);
- }
-
- struct mob_toc_dkAI : public boss_faction_championsAI
- {
- mob_toc_dkAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
-
- uint32 m_uiIceboundFortitudeTimer;
- uint32 m_uiChainsOfIceTimer;
- uint32 m_uiDeathCoilTimer;
- uint32 m_uiStrangulateTimer;
- uint32 m_uiFrostStrikeTimer;
- uint32 m_uiIcyTouchTimer;
- uint32 m_uiDeathGripTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiIceboundFortitudeTimer = urand(5*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- m_uiChainsOfIceTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiDeathCoilTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiStrangulateTimer = urand(10*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- m_uiFrostStrikeTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiIcyTouchTimer = urand(8*IN_MILLISECONDS, 12*IN_MILLISECONDS);
- m_uiDeathGripTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- SetEquipmentSlots(false, 47518, 51021, EQUIP_NO_CHANGE);
- }
+ public:
+ mob_toc_dk() : CreatureScript("mob_toc_dk") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_dkAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
-
- if (m_uiIceboundFortitudeTimer <= uiDiff)
- {
- if (HealthBelowPct(50))
- DoCast(me, SPELL_ICEBOUND_FORTITUDE);
- m_uiIceboundFortitudeTimer = urand(5*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- } else m_uiIceboundFortitudeTimer -= uiDiff;
-
- if (m_uiChainsOfIceTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CHAINS_OF_ICE);
- m_uiChainsOfIceTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiChainsOfIceTimer -= uiDiff;
-
- if (m_uiDeathCoilTimer <= uiDiff)
- {
- DoCastVictim(SPELL_DEATH_COIL);
- m_uiDeathCoilTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiDeathCoilTimer -= uiDiff;
+ mob_toc_dkAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DEATH_COIL, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DEATH_GRIP, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FROST_STRIKE, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ICEBOUND_FORTITUDE, urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ICY_TOUCH, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_STRANGULATE, urand(5*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 47518, 51021, EQUIP_NO_CHANGE);
+ }
- if (m_uiStrangulateTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (Unit* target = SelectEnemyCaster(false))
- DoCast(target, SPELL_STRANGULATE);
- m_uiStrangulateTimer = urand(10*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- } else m_uiStrangulateTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiFrostStrikeTimer <= uiDiff)
- {
- DoCastVictim(SPELL_FROST_STRIKE);
- m_uiFrostStrikeTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiFrostStrikeTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiIcyTouchTimer <= uiDiff)
- {
- DoCastVictim(SPELL_ICY_TOUCH);
- m_uiIcyTouchTimer = urand(8*IN_MILLISECONDS, 12*IN_MILLISECONDS);
- } else m_uiIcyTouchTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiDeathGripTimer <= uiDiff)
- {
- if (me->IsInRange(me->getVictim(), 10.0f, 30.0f, false))
- DoCastVictim(SPELL_DEATH_GRIP);
- m_uiDeathGripTimer = urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiDeathGripTimer -= uiDiff;
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CHAINS_OF_ICE:
+ DoCastVictim(SPELL_CHAINS_OF_ICE);
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_DEATH_COIL:
+ DoCastVictim(SPELL_DEATH_COIL);
+ events.ScheduleEvent(EVENT_DEATH_COIL, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_DEATH_GRIP:
+ if (me->IsInRange(me->getVictim(), 5.0f, 30.0f, false))
+ {
+ DoCast(me->getVictim(), SPELL_DEATH_GRIP);
+ events.RescheduleEvent(EVENT_DEATH_GRIP, 35*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DEATH_GRIP, 3*IN_MILLISECONDS);
+ return;
+ case EVENT_FROST_STRIKE:
+ DoCastVictim(SPELL_FROST_STRIKE);
+ events.ScheduleEvent(EVENT_FROST_STRIKE, urand(6*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_ICEBOUND_FORTITUDE:
+ if (HealthBelowPct(50))
+ {
+ DoCast(SPELL_ICEBOUND_FORTITUDE);
+ events.RescheduleEvent(EVENT_ICEBOUND_FORTITUDE, 60*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_ICEBOUND_FORTITUDE, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_ICY_TOUCH:
+ DoCastVictim(SPELL_ICY_TOUCH);
+ events.ScheduleEvent(EVENT_ICY_TOUCH, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_STRANGULATE:
+ if (Unit* target = SelectEnemyCaster(false))
+ {
+ DoCast(target, SPELL_STRANGULATE);
+ events.RescheduleEvent(EVENT_STRANGULATE, 120*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_STRANGULATE, 5*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_dkAI (creature);
}
- };
-
-};
-
-enum eRogueSpells
-{
- SPELL_FAN_OF_KNIVES = 65955, //2sec
- SPELL_BLIND = 65960, //2min
- SPELL_CLOAK = 65961, //90sec
- SPELL_BLADE_FLURRY = 65956, //2min
- SPELL_SHADOWSTEP = 66178, //30sec
- SPELL_HEMORRHAGE = 65954,
- SPELL_EVISCERATE = 65957,
};
class mob_toc_rogue : public CreatureScript
{
-public:
- mob_toc_rogue() : CreatureScript("mob_toc_rogue") { }
+ public:
+ mob_toc_rogue() : CreatureScript("mob_toc_rogue") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_rogueAI (creature);
- }
+ struct mob_toc_rogueAI : public boss_faction_championsAI
+ {
+ mob_toc_rogueAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_FAN_OF_KNIVES, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_BLIND, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_CLOAK, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_BLADE_FLURRY, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SHADOWSTEP, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HEMORRHAGE, urand(3*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_EVISCERATE, urand(20*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_WOUND_POISON, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 47422, 49982, EQUIP_NO_CHANGE);
+ me->setPowerType(POWER_ENERGY);
+ me->SetMaxPower(POWER_ENERGY, 100);
+ }
- struct mob_toc_rogueAI : public boss_faction_championsAI
- {
- mob_toc_rogueAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- uint32 m_uiFanOfKnivesTimer;
- uint32 m_uiHemorrhageTimer;
- uint32 m_uiEviscerateTimer;
- uint32 m_uiShadowstepTimer;
- uint32 m_uiBlindTimer;
- uint32 m_uiCloakTimer;
- uint32 m_uiBladeFlurryTimer;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FAN_OF_KNIVES:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCastAOE(SPELL_FAN_OF_KNIVES);
+ events.ScheduleEvent(EVENT_FAN_OF_KNIVES, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_BLIND:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ DoCast(target, SPELL_BLIND);
+ events.ScheduleEvent(EVENT_BLIND, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_CLOAK:
+ if (HealthBelowPct(50))
+ {
+ DoCast(SPELL_CLOAK);
+ events.RescheduleEvent(EVENT_CLOAK, 90*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_CLOAK, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_BLADE_FLURRY:
+ if (EnemiesInRange(10.0f) >= 2)
+ {
+ DoCast(SPELL_BLADE_FLURRY);
+ events.RescheduleEvent(EVENT_BLADE_FLURRY, 120*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_BLADE_FLURRY, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_SHADOWSTEP:
+ if (me->IsInRange(me->getVictim(), 10.0f, 40.0f, false))
+ {
+ DoCast(me->getVictim(), SPELL_SHADOWSTEP);
+ events.RescheduleEvent(EVENT_SHADOWSTEP, 30*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_SHADOWSTEP, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_HEMORRHAGE:
+ DoCastVictim(SPELL_HEMORRHAGE);
+ events.ScheduleEvent(EVENT_HEMORRHAGE, urand(3*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_EVISCERATE:
+ DoCastVictim(SPELL_EVISCERATE);
+ events.ScheduleEvent(EVENT_EVISCERATE, urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS));
+ return;
+ case EVENT_WOUND_POISON:
+ DoCastVictim(SPELL_WOUND_POISON);
+ events.ScheduleEvent(EVENT_WOUND_POISON, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ };
- void Reset()
+ CreatureAI* GetAI(Creature* creature) const
{
- boss_faction_championsAI::Reset();
- m_uiFanOfKnivesTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- m_uiHemorrhageTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- m_uiEviscerateTimer = urand(15*IN_MILLISECONDS, 20*IN_MILLISECONDS);
- m_uiShadowstepTimer = urand(10*IN_MILLISECONDS, 80*IN_MILLISECONDS);
- m_uiBlindTimer = urand(7*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- m_uiCloakTimer = urand(20*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- m_uiBladeFlurryTimer = urand(12*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- SetEquipmentSlots(false, 47422, 49982, EQUIP_NO_CHANGE);
+ return new mob_toc_rogueAI (creature);
}
+};
+
+class mob_toc_enh_shaman : public CreatureScript
+{
+ public:
+ mob_toc_enh_shaman() : CreatureScript("mob_toc_enh_shaman") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_toc_enh_shamanAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_enh_shamanAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_DPS_EARTH_SHOCK, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_LAVA_LASH, urand(3*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_STORMSTRIKE, urand(2*IN_MILLISECONDS, 5*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DPS_BLOODLUST_HEROISM, 20*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_DEPLOY_TOTEM, 1*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_WINDFURY, urand(20*IN_MILLISECONDS, 50*IN_MILLISECONDS));
+
+ _totemCount = 0;
+ _totemOldCenterX = me->GetPositionX();
+ _totemOldCenterY = me->GetPositionY();
+ SetEquipmentSlots(false, 51803, 48013, EQUIP_NO_CHANGE);
+ summons.DespawnAll();
+ }
- if (m_uiFanOfKnivesTimer <= uiDiff)
+ void JustSummoned(Creature* summoned)
{
- if (EnemiesInRange(15.0f) > 2)
- DoCastAOE(SPELL_FAN_OF_KNIVES);
- m_uiFanOfKnivesTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- } else m_uiFanOfKnivesTimer -= uiDiff;
+ summons.Summon(summoned);
+ }
- if (m_uiHemorrhageTimer <= uiDiff)
+ void SummonedCreatureDespawn(Creature* /*pSummoned*/)
{
- DoCastVictim(SPELL_HEMORRHAGE);
- m_uiHemorrhageTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- } else m_uiHemorrhageTimer -= uiDiff;
+ --_totemCount;
+ }
- if (m_uiEviscerateTimer <= uiDiff)
+ void DeployTotem()
{
- DoCastVictim(SPELL_EVISCERATE);
- m_uiEviscerateTimer = urand(15*IN_MILLISECONDS, 20*IN_MILLISECONDS);
- } else m_uiEviscerateTimer -= uiDiff;
+ _totemCount = 4;
+ _totemOldCenterX = me->GetPositionX();
+ _totemOldCenterY = me->GetPositionY();
+ /*
+ -Windfury (16% melee haste)
+ -Grounding (redirects one harmful magic spell to the totem)
- if (m_uiShadowstepTimer <= uiDiff)
- {
- if (me->IsInRange(me->getVictim(), 10.0f, 40.0f))
- DoCastVictim(SPELL_SHADOWSTEP);
- m_uiShadowstepTimer = urand(10*IN_MILLISECONDS, 80*IN_MILLISECONDS);
- } else m_uiShadowstepTimer -= uiDiff;
+ -Healing Stream (unable to find amount of healing in our logs)
- if (m_uiBlindTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
- if (me->IsInRange(target, 0.0f, 15.0f, false))
- DoCast(target, SPELL_BLIND);
- m_uiBlindTimer = urand(7*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- } else m_uiBlindTimer -= uiDiff;
+ -Tremor (prevents fear effects)
+ -Strength of Earth (155 strength and agil for the opposing team)
- if (m_uiCloakTimer <= uiDiff)
- {
- if (HealthBelowPct(50))
- DoCast(me, SPELL_CLOAK);
- m_uiCloakTimer = urand(20*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- } else m_uiCloakTimer -= uiDiff;
+ -Searing (average ~3500 damage on a random target every ~3.5 seconds)
+ */
+ }
- if (m_uiBladeFlurryTimer <= uiDiff)
+ void JustDied(Unit* killer)
{
- DoCastVictim(SPELL_BLADE_FLURRY);
- m_uiBladeFlurryTimer = urand(12*IN_MILLISECONDS, 120*IN_MILLISECONDS);
- } else m_uiBladeFlurryTimer -= uiDiff;
-
- boss_faction_championsAI::UpdateAI(uiDiff);
- }
- };
-
-};
-
-enum eEnhShamanSpells
-{
- SPELL_EARTH_SHOCK_ENH = 65973,
- SPELL_LAVA_LASH = 65974,
- SPELL_STORMSTRIKE = 65970,
-};
-
-class mob_toc_enh_shaman : public CreatureScript
-{
-public:
- mob_toc_enh_shaman() : CreatureScript("mob_toc_enh_shaman") { }
+ boss_faction_championsAI::JustDied(killer);
+ summons.DespawnAll();
+ }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_enh_shamanAI (creature);
- }
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- struct mob_toc_enh_shamanAI : public boss_faction_championsAI
- {
- mob_toc_enh_shamanAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE), Summons(me) {}
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- SummonList Summons;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- uint32 m_uiHeroismOrBloodlustTimer;
- uint32 m_uiEarthShockTimer;
- uint32 m_uiStormstrikeTimer;
- uint32 m_uiLavaLashTimer;
- uint32 m_uiDeployTotemTimer;
- uint8 m_uiTotemCount;
- float m_fTotemOldCenterX, m_fTotemOldCenterY;
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DPS_EARTH_SHOCK:
+ if (Unit* target = SelectEnemyCaster(true))
+ DoCast(target, SPELL_EARTH_SHOCK);
+ events.ScheduleEvent(EVENT_DPS_EARTH_SHOCK, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_LAVA_LASH:
+ DoCastVictim(SPELL_LAVA_LASH);
+ events.ScheduleEvent(EVENT_LAVA_LASH, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_STORMSTRIKE:
+ DoCastVictim(SPELL_STORMSTRIKE);
+ events.ScheduleEvent(EVENT_STORMSTRIKE, urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_DPS_BLOODLUST_HEROISM:
+ if (me->getFaction()) //Am i alliance?
+ {
+ if (!me->HasAura(AURA_EXHAUSTION))
+ DoCastAOE(SPELL_HEROISM);
+ }
+ else
+ {
+ if (!me->HasAura(AURA_SATED))
+ DoCastAOE(SPELL_BLOODLUST);
+ }
+ events.ScheduleEvent(EVENT_DPS_BLOODLUST_HEROISM, 5*MINUTE*IN_MILLISECONDS);
+ return;
+ case EVENT_DEPLOY_TOTEM:
+ if (_totemCount < 4 || me->GetDistance2d(_totemOldCenterX, _totemOldCenterY) > 20.0f)
+ DeployTotem();
+ events.ScheduleEvent(EVENT_DEPLOY_TOTEM, 1*IN_MILLISECONDS);
+ return;
+ case EVENT_WINDFURY:
+ DoCastVictim(SPELL_WINDFURY);
+ events.ScheduleEvent(EVENT_WINDFURY, urand(20*IN_MILLISECONDS, 60*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ private:
+ uint8 _totemCount;
+ float _totemOldCenterX, _totemOldCenterY;
+ };
- void Reset()
+ CreatureAI* GetAI(Creature* creature) const
{
- boss_faction_championsAI::Reset();
- m_uiHeroismOrBloodlustTimer = urand(25*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- m_uiEarthShockTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- m_uiStormstrikeTimer = urand(5*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- m_uiLavaLashTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- m_uiDeployTotemTimer = urand(1*IN_MILLISECONDS, 3*IN_MILLISECONDS);
- m_uiTotemCount = 0;
- m_fTotemOldCenterX = me->GetPositionX();
- m_fTotemOldCenterY = me->GetPositionY();
- SetEquipmentSlots(false, 51803, 48013, EQUIP_NO_CHANGE);
- Summons.DespawnAll();
+ return new mob_toc_enh_shamanAI (creature);
}
+};
- void JustSummoned(Creature* summoned)
- {
- Summons.Summon(summoned);
- }
+class mob_toc_retro_paladin : public CreatureScript
+{
+ public:
+ mob_toc_retro_paladin() : CreatureScript("mob_toc_retro_paladin") { }
- void SummonedCreatureDespawn(Creature* /*pSummoned*/)
+ struct mob_toc_retro_paladinAI : public boss_faction_championsAI
{
- --m_uiTotemCount;
- }
+ mob_toc_retro_paladinAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_AVENGING_WRATH, urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_CRUSADER_STRIKE, urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DIVINE_STORM, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE_RET, urand(10*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_JUDGEMENT_OF_COMMAND, urand(5*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_REPENTANCE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DPS_HAND_OF_PROTECTION, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_DPS_DIVINE_SHIELD, urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ SetEquipmentSlots(false, 47519, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+ }
- void DeployTotem()
- {
- m_uiTotemCount = 4;
- m_fTotemOldCenterX = me->GetPositionX();
- m_fTotemOldCenterY = me->GetPositionY();
- /*
- -Windfury (16% melee haste)
- -Grounding (redirects one harmful magic spell to the totem)
+ void EnterCombat(Unit* who)
+ {
+ boss_faction_championsAI::EnterCombat(who);
+ DoCast(SPELL_SEAL_OF_COMMAND);
+ }
- -Healing Stream (unable to find amount of healing in our logs)
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- -Tremor (prevents fear effects)
- -Strength of Earth (155 strength and agil for the opposing team)
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- -Searing (average ~3500 damage on a random target every ~3.5 seconds)
- */
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_AVENGING_WRATH:
+ DoCast(SPELL_AVENGING_WRATH);
+ events.ScheduleEvent(EVENT_AVENGING_WRATH, 180*IN_MILLISECONDS);
+ return;
+ case EVENT_CRUSADER_STRIKE:
+ DoCastVictim(SPELL_CRUSADER_STRIKE);
+ events.ScheduleEvent(EVENT_CRUSADER_STRIKE, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_DIVINE_STORM:
+ if (EnemiesInRange(10.0f) >= 2)
+ DoCast(SPELL_DIVINE_STORM);
+ events.ScheduleEvent(EVENT_DIVINE_STORM, urand(10*IN_MILLISECONDS, 20*IN_MILLISECONDS));
+ return;
+ case EVENT_HAMMER_OF_JUSTICE_RET:
+ DoCastVictim(SPELL_HAMMER_OF_JUSTICE_RET);
+ events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE_RET, 40*IN_MILLISECONDS);
+ return;
+ case EVENT_JUDGEMENT_OF_COMMAND:
+ DoCastVictim(SPELL_JUDGEMENT_OF_COMMAND);
+ events.ScheduleEvent(EVENT_JUDGEMENT_OF_COMMAND, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_REPENTANCE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ DoCast(target, SPELL_REPENTANCE);
+ events.ScheduleEvent(EVENT_REPENTANCE, 60*IN_MILLISECONDS);
+ return;
+ case EVENT_DPS_HAND_OF_PROTECTION:
+ if (Unit* target = DoSelectLowestHpFriendly(30.0f))
+ {
+ if (!target->HasAura(SPELL_FORBEARANCE))
+ {
+ DoCast(target, SPELL_HAND_OF_PROTECTION);
+ events.RescheduleEvent(EVENT_DPS_HAND_OF_PROTECTION, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DPS_HAND_OF_PROTECTION, 5*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DPS_HAND_OF_PROTECTION, 5*IN_MILLISECONDS);
+ return;
+ case EVENT_DPS_DIVINE_SHIELD:
+ if (HealthBelowPct(30) && !me->HasAura(SPELL_FORBEARANCE))
+ {
+ DoCast(me, SPELL_DIVINE_SHIELD);
+ events.RescheduleEvent(EVENT_DPS_DIVINE_SHIELD, 5*MINUTE*IN_MILLISECONDS);
+ }
+ else
+ events.RescheduleEvent(EVENT_DPS_DIVINE_SHIELD, 5*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ };
- void JustDied(Unit* killer)
+ CreatureAI* GetAI(Creature* creature) const
{
- boss_faction_championsAI::JustDied(killer);
- Summons.DespawnAll();
+ return new mob_toc_retro_paladinAI (creature);
}
+};
- void UpdateAI(const uint32 uiDiff)
+class mob_toc_pet_warlock : public CreatureScript
+{
+ public:
+ mob_toc_pet_warlock() : CreatureScript("mob_toc_pet_warlock") { }
+
+ struct mob_toc_pet_warlockAI : public boss_faction_championsAI
{
- if (!UpdateVictim())
- return;
+ mob_toc_pet_warlockAI(Creature* creature) : boss_faction_championsAI(creature, AI_PET) {}
- if (m_uiHeroismOrBloodlustTimer <= uiDiff)
+ void Reset()
{
- if (me->getFaction()) //Am i alliance?
- {
- if (!me->HasAura(AURA_EXHAUSTION))
- DoCastAOE(SPELL_HEROISM);
- }
- else
- if (!me->HasAura(AURA_SATED))
- DoCastAOE(SPELL_BLOODLUST);
- m_uiHeroismOrBloodlustTimer = urand(25*IN_MILLISECONDS, 60*IN_MILLISECONDS);
- } else m_uiHeroismOrBloodlustTimer -= uiDiff;
+ boss_faction_championsAI::Reset();
+ events.ScheduleEvent(EVENT_DEVOUR_MAGIC, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_SPELL_LOCK, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ }
- if (m_uiEarthShockTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- DoCastVictim(SPELL_EARTH_SHOCK_ENH);
- m_uiEarthShockTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- } else m_uiEarthShockTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiStormstrikeTimer <= uiDiff)
- {
- DoCastVictim(SPELL_STORMSTRIKE);
- m_uiStormstrikeTimer = urand(5*IN_MILLISECONDS, 90*IN_MILLISECONDS);
- } else m_uiStormstrikeTimer -= uiDiff;
+ events.Update(diff);
+ boss_faction_championsAI::UpdateAI(diff);
- if (m_uiLavaLashTimer <= uiDiff)
- {
- DoCastVictim(SPELL_LAVA_LASH);
- m_uiLavaLashTimer = urand(5*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- } else m_uiLavaLashTimer -= uiDiff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (m_uiDeployTotemTimer <= uiDiff)
- {
- if (m_uiTotemCount < 4 || me->GetDistance2d(m_fTotemOldCenterX, m_fTotemOldCenterY) > 20.0f)
- DeployTotem();
- m_uiDeployTotemTimer = urand(1*IN_MILLISECONDS, 3*IN_MILLISECONDS);
- } else m_uiDeployTotemTimer -= uiDiff;
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DEVOUR_MAGIC:
+ DoCastVictim(SPELL_DEVOUR_MAGIC);
+ events.ScheduleEvent(EVENT_DEVOUR_MAGIC, urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_SPELL_LOCK:
+ DoCast(SPELL_SPELL_LOCK);
+ events.ScheduleEvent(EVENT_SPELL_LOCK, urand(24*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
+ }
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_toc_pet_warlockAI (creature);
}
- };
-
};
-enum eRetroPaladinSpells
+class mob_toc_pet_hunter : public CreatureScript
{
- SPELL_AVENGING_WRATH = 66011, //3min cd
- SPELL_CRUSADER_STRIKE = 66003, //6sec cd
- SPELL_DIVINE_SHIELD = 66010, //5min cd
- SPELL_DIVINE_STORM = 66006, //10sec cd
- SPELL_HAMMER_OF_JUSTICE_RET = 66007, //40sec cd
- SPELL_HAND_OF_PROTECTION_RET = 66009, //5min cd
- SPELL_JUDGEMENT_OF_COMMAND = 66005, //8sec cd
- SPELL_REPENTANCE = 66008, //60sec cd
- SPELL_SEAL_OF_COMMAND = 66004, //no cd
-};
+ public:
+ mob_toc_pet_hunter() : CreatureScript("mob_toc_pet_hunter") { }
-class mob_toc_retro_paladin : public CreatureScript
-{
-public:
- mob_toc_retro_paladin() : CreatureScript("mob_toc_retro_paladin") { }
+ struct mob_toc_pet_hunterAI : public boss_faction_championsAI
+ {
+ mob_toc_pet_hunterAI(Creature* creature) : boss_faction_championsAI(creature, AI_PET) {}
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_retro_paladinAI (creature);
- }
+ void Reset()
+ {
+ boss_faction_championsAI::Reset();
+ _clawTimer = urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS);
+ }
- struct mob_toc_retro_paladinAI : public boss_faction_championsAI
- {
- mob_toc_retro_paladinAI(Creature* creature) : boss_faction_championsAI(creature, AI_MELEE) {}
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
- uint32 m_uiRepeteanceTimer;
- uint32 m_uiCrusaderStrikeTimer;
- uint32 m_uiAvengingWrathTimer;
- uint32 m_uiDivineShieldTimer;
- uint32 m_uiDivineStormTimer;
- uint32 m_uiJudgementOfCommandTimer;
+ boss_faction_championsAI::UpdateAI(diff);
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiRepeteanceTimer = 60*IN_MILLISECONDS;
- m_uiCrusaderStrikeTimer = urand(6*IN_MILLISECONDS, 18*IN_MILLISECONDS);
- m_uiAvengingWrathTimer = 180*IN_MILLISECONDS;
- m_uiDivineShieldTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- m_uiDivineStormTimer = 10*IN_MILLISECONDS;
- m_uiJudgementOfCommandTimer = urand(8*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- SetEquipmentSlots(false, 47519, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- }
+ if (_clawTimer <= diff)
+ {
+ DoCastVictim(SPELL_CLAW);
+ _clawTimer = urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS);
+ }
+ else
+ _clawTimer -= diff;
+ }
+ private:
+ uint32 _clawTimer;
+ };
- void EnterCombat(Unit* who)
+ CreatureAI* GetAI(Creature* creature) const
{
- boss_faction_championsAI::EnterCombat(who);
- DoCast(SPELL_SEAL_OF_COMMAND);
+ return new mob_toc_pet_hunterAI (creature);
}
+};
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
-
- if (m_uiRepeteanceTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_REPENTANCE);
- m_uiRepeteanceTimer = 60*IN_MILLISECONDS;
- } else m_uiRepeteanceTimer -= uiDiff;
-
- if (m_uiCrusaderStrikeTimer <= uiDiff)
- {
- DoCastVictim(SPELL_CRUSADER_STRIKE);
- m_uiCrusaderStrikeTimer = urand(6*IN_MILLISECONDS, 18*IN_MILLISECONDS);
- } else m_uiCrusaderStrikeTimer -= uiDiff;
+class spell_faction_champion_warl_unstable_affliction : public SpellScriptLoader
+{
+ public:
+ spell_faction_champion_warl_unstable_affliction() : SpellScriptLoader("spell_faction_champion_warl_unstable_affliction") { }
- if (m_uiAvengingWrathTimer <= uiDiff)
- {
- DoCastVictim(SPELL_AVENGING_WRATH);
- m_uiAvengingWrathTimer = 180*IN_MILLISECONDS;
- } else m_uiAvengingWrathTimer -= uiDiff;
+ class spell_faction_champion_warl_unstable_affliction_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_faction_champion_warl_unstable_affliction_AuraScript);
- if (m_uiDivineShieldTimer <= uiDiff)
+ bool Validate(SpellInfo const* /*spell*/)
{
- if (HealthBelowPct(20))
- DoCast(me, SPELL_DIVINE_SHIELD);
- m_uiDivineShieldTimer = urand(0*IN_MILLISECONDS, 360*IN_MILLISECONDS);
- } else m_uiDivineShieldTimer -= uiDiff;
+ if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_AFFLICTION_DISPEL))
+ return false;
+ return true;
+ }
- if (m_uiDivineStormTimer <= uiDiff)
+ void HandleDispel(DispelInfo* dispelInfo)
{
- DoCastVictim(SPELL_DIVINE_STORM);
- m_uiDivineStormTimer = 10*IN_MILLISECONDS;
- } else m_uiDivineStormTimer -= uiDiff;
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(dispelInfo->GetDispeller(), SPELL_UNSTABLE_AFFLICTION_DISPEL, true, NULL, GetEffect(EFFECT_0));
+ }
- if (m_uiJudgementOfCommandTimer <= uiDiff)
+ void Register()
{
- DoCastVictim(SPELL_JUDGEMENT_OF_COMMAND);
- m_uiJudgementOfCommandTimer = urand(8*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiJudgementOfCommandTimer -= uiDiff;
+ AfterDispel += AuraDispelFn(spell_faction_champion_warl_unstable_affliction_AuraScript::HandleDispel);
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_faction_champion_warl_unstable_affliction_AuraScript();
}
- };
-
-};
-
-enum eWarlockPetSpells
-{
- SPELL_DEVOUR_MAGIC = 67518,
- SPELL_SPELL_LOCK = 67519,
};
-class mob_toc_pet_warlock : public CreatureScript
+class spell_faction_champion_death_grip : public SpellScriptLoader
{
-public:
- mob_toc_pet_warlock() : CreatureScript("mob_toc_pet_warlock") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_pet_warlockAI (creature);
- }
-
- struct mob_toc_pet_warlockAI : public boss_faction_championsAI
- {
- mob_toc_pet_warlockAI(Creature* creature) : boss_faction_championsAI(creature, AI_PET) {}
-
- uint32 m_uiDevourMagicTimer;
- uint32 m_uiSpellLockTimer;
-
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiDevourMagicTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- m_uiSpellLockTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- }
+ public:
+ spell_faction_champion_death_grip() : SpellScriptLoader("spell_faction_champion_death_grip") { }
- void UpdateAI(const uint32 uiDiff)
+ class spell_faction_champion_death_grip_SpellScript : public SpellScript
{
- if (!UpdateVictim())
- return;
+ PrepareSpellScript(spell_faction_champion_death_grip_SpellScript);
- if (m_uiDevourMagicTimer <= uiDiff)
+ bool Validate(SpellInfo const* /*spell*/)
{
- DoCastVictim(SPELL_DEVOUR_MAGIC);
- m_uiDevourMagicTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiDevourMagicTimer -= uiDiff;
+ if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_GRIP_PULL))
+ return false;
+ return true;
+ }
- if (m_uiSpellLockTimer <= uiDiff)
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
- DoCastVictim(SPELL_SPELL_LOCK);
- m_uiSpellLockTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiSpellLockTimer -= uiDiff;
+ if (Unit* target = GetHitUnit())
+ {
+ if (Unit* caster = GetCaster())
+ target->CastSpell(caster, SPELL_DEATH_GRIP_PULL);
+ }
+ }
- boss_faction_championsAI::UpdateAI(uiDiff);
- }
- };
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_faction_champion_death_grip_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
-};
+ };
-enum eHunterPetSpells
-{
- SPELL_CLAW = 67793,
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_faction_champion_death_grip_SpellScript();
+ }
};
-class mob_toc_pet_hunter : public CreatureScript
+class spell_toc_bloodlust : public SpellScriptLoader
{
-public:
- mob_toc_pet_hunter() : CreatureScript("mob_toc_pet_hunter") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_toc_pet_hunterAI (creature);
- }
+ public:
+ spell_toc_bloodlust() : SpellScriptLoader("spell_toc_bloodlust") { }
- struct mob_toc_pet_hunterAI : public boss_faction_championsAI
- {
- mob_toc_pet_hunterAI(Creature* creature) : boss_faction_championsAI(creature, AI_PET) {}
+ class spell_toc_bloodlust_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_toc_bloodlust_SpellScript);
- uint32 m_uiClawTimer;
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(AURA_SATED))
+ return false;
+ return true;
+ }
- void Reset()
- {
- boss_faction_championsAI::Reset();
- m_uiClawTimer = urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- }
+ void RemoveInvalidTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(Trinity::UnitAuraCheck(true, AURA_SATED));
+ }
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
+ void ApplyDebuff()
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(target, AURA_SATED, true);
+ }
- if (m_uiClawTimer <= uiDiff)
+ void Register()
{
- DoCastVictim(SPELL_CLAW);
- m_uiClawTimer = urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- } else m_uiClawTimer -= uiDiff;
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_toc_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_toc_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
+ AfterHit += SpellHitFn(spell_toc_bloodlust_SpellScript::ApplyDebuff);
+ }
+ };
- boss_faction_championsAI::UpdateAI(uiDiff);
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_toc_bloodlust_SpellScript();
}
- };
};
-class spell_faction_champion_warl_unstable_affliction : public SpellScriptLoader
+class spell_toc_heroism : public SpellScriptLoader
{
public:
- spell_faction_champion_warl_unstable_affliction() : SpellScriptLoader("spell_faction_champion_warl_unstable_affliction") { }
+ spell_toc_heroism() : SpellScriptLoader("spell_toc_heroism") { }
- class spell_faction_champion_warl_unstable_affliction_AuraScript : public AuraScript
+ class spell_toc_heroism_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_faction_champion_warl_unstable_affliction_AuraScript);
+ PrepareSpellScript(spell_toc_heroism_SpellScript);
- bool Validate(SpellInfo const* /*spell*/)
+ bool Validate(SpellInfo const* /*spellEntry*/)
{
- if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_AFFLICTION_DISPEL))
+ if (!sSpellMgr->GetSpellInfo(AURA_EXHAUSTION))
return false;
return true;
}
- void HandleDispel(DispelInfo* dispelInfo)
+ void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
- if (Unit* caster = GetCaster())
- caster->CastSpell(dispelInfo->GetDispeller(), SPELL_UNSTABLE_AFFLICTION_DISPEL, true, NULL, GetEffect(EFFECT_0));
+ targets.remove_if(Trinity::UnitAuraCheck(true, AURA_EXHAUSTION));
+ }
+
+ void ApplyDebuff()
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(target, AURA_EXHAUSTION, true);
}
void Register()
{
- AfterDispel += AuraDispelFn(spell_faction_champion_warl_unstable_affliction_AuraScript::HandleDispel);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_toc_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_toc_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
+ AfterHit += SpellHitFn(spell_toc_heroism_SpellScript::ApplyDebuff);
}
};
- AuraScript* GetAuraScript() const
+ SpellScript* GetSpellScript() const
{
- return new spell_faction_champion_warl_unstable_affliction_AuraScript();
+ return new spell_toc_heroism_SpellScript();
}
};
@@ -2087,5 +2391,9 @@ void AddSC_boss_faction_champions()
new mob_toc_retro_paladin();
new mob_toc_pet_warlock();
new mob_toc_pet_hunter();
+
new spell_faction_champion_warl_unstable_affliction();
+ new spell_faction_champion_death_grip();
+ new spell_toc_bloodlust();
+ new spell_toc_heroism();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
index 87e7801566e..3f2fee303eb 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
@@ -16,20 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: trial_of_the_crusader
-SD%Complete: ??%
-SDComment: based on /dev/rsa
-SDCategory: Crusader Coliseum
-EndScriptData */
-
-// Known bugs:
-// Some visuals aren't appearing right sometimes
-//
-// TODO:
-// Redone summon's scripts in SAI
-// Add immunities to the boss and summons
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "trial_of_the_crusader.h"
@@ -47,15 +33,7 @@ enum Yells
SAY_INFERNAL_ERUPTION = 8,
SAY_KILL_PLAYER = 9,
SAY_DEATH = 10,
- SAY_BERSERK = 11,
-};
-
-enum Equipment
-{
- EQUIP_MAIN = 47266,
- EQUIP_OFFHAND = 46996,
- EQUIP_RANGED = 47267,
- EQUIP_DONE = EQUIP_NO_CHANGE,
+ SAY_BERSERK = 11
};
enum Summons
@@ -64,7 +42,7 @@ enum Summons
NPC_INFERNAL_VOLCANO = 34813,
NPC_FEL_INFERNAL = 34815, // immune to all CC on Heroic (stuns, banish, interrupt, etc)
NPC_NETHER_PORTAL = 34825,
- NPC_MISTRESS_OF_PAIN = 34826,
+ NPC_MISTRESS_OF_PAIN = 34826
};
enum BossSpells
@@ -84,442 +62,530 @@ enum BossSpells
SPELL_BERSERK = 64238, // unused
// Mistress of Pain spells
- SPELL_SHIVAN_SLASH = 67098,
- SPELL_SPINNING_STRIKE = 66283,
- SPELL_MISTRESS_KISS = 67077,
- SPELL_FEL_INFERNO = 67047,
- SPELL_FEL_STREAK = 66494,
+ SPELL_SHIVAN_SLASH = 67098,
+ SPELL_SPINNING_STRIKE = 66283,
+ SPELL_MISTRESS_KISS = 66336,
+ SPELL_FEL_INFERNO = 67047,
+ SPELL_FEL_STREAK = 66494,
+ SPELL_LORD_HITTIN = 66326, // special effect preventing more specific spells be cast on the same player within 10 seconds
+ SPELL_MISTRESS_KISS_DEBUFF = 66334,
+ SPELL_MISTRESS_KISS_DAMAGE_SILENCE = 66359
};
-/*######
-## boss_jaraxxus
-######*/
+enum Events
+{
+ // Lord Jaraxxus
+ EVENT_FEL_FIREBALL = 1,
+ EVENT_FEL_LIGHTNING = 2,
+ EVENT_INCINERATE_FLESH = 3,
+ EVENT_NETHER_POWER = 4,
+ EVENT_LEGION_FLAME = 5,
+ EVENT_SUMMONO_NETHER_PORTAL = 6,
+ EVENT_SUMMON_INFERNAL_ERUPTION = 7,
+
+ // Mistress of Pain
+ EVENT_SHIVAN_SLASH = 8,
+ EVENT_SPINNING_STRIKE = 9,
+ EVENT_MISTRESS_KISS = 10
+};
class boss_jaraxxus : public CreatureScript
{
-public:
- boss_jaraxxus() : CreatureScript("boss_jaraxxus") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_jaraxxusAI(creature);
- }
-
- struct boss_jaraxxusAI : public ScriptedAI
- {
- boss_jaraxxusAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- instance = creature->GetInstanceScript();
- Reset();
- }
-
- InstanceScript* instance;
+ public:
+ boss_jaraxxus() : CreatureScript("boss_jaraxxus") { }
- SummonList Summons;
-
- uint32 m_uiFelFireballTimer;
- uint32 m_uiFelLightningTimer;
- uint32 m_uiIncinerateFleshTimer;
- uint32 m_uiNetherPowerTimer;
- uint32 m_uiLegionFlameTimer;
- uint32 m_uiSummonNetherPortalTimer;
- uint32 m_uiSummonInfernalEruptionTimer;
-
- void Reset()
+ struct boss_jaraxxusAI : public BossAI
{
- if (instance)
- instance->SetData(TYPE_JARAXXUS, NOT_STARTED);
- SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);
- m_uiFelFireballTimer = 5*IN_MILLISECONDS;
- m_uiFelLightningTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- m_uiIncinerateFleshTimer = urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- m_uiNetherPowerTimer = 40*IN_MILLISECONDS;
- m_uiLegionFlameTimer = 30*IN_MILLISECONDS;
- m_uiSummonNetherPortalTimer = 1*MINUTE*IN_MILLISECONDS;
- m_uiSummonInfernalEruptionTimer = 2*MINUTE*IN_MILLISECONDS;
- Summons.DespawnAll();
- }
+ boss_jaraxxusAI(Creature* creature) : BossAI(creature, BOSS_JARAXXUS)
+ {
+ }
- void JustReachedHome()
- {
- if (instance)
- instance->SetData(TYPE_JARAXXUS, FAIL);
- DoCast(me, SPELL_JARAXXUS_CHAINS);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_PASSIVE);
- }
+ void Reset()
+ {
+ _Reset();
+ events.ScheduleEvent(EVENT_FEL_FIREBALL, 5*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_FEL_LIGHTNING, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_INCINERATE_FLESH, urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_NETHER_POWER, 40*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_LEGION_FLAME, 30*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SUMMONO_NETHER_PORTAL, 20*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SUMMON_INFERNAL_ERUPTION, 80*IN_MILLISECONDS);
+ }
- void KilledUnit(Unit* who)
- {
- if (who->GetTypeId() == TYPEID_PLAYER)
+ void JustReachedHome()
{
+ _JustReachedHome();
if (instance)
- instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
+ instance->SetBossState(BOSS_JARAXXUS, FAIL);
+ DoCast(me, SPELL_JARAXXUS_CHAINS);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
- }
- void JustDied(Unit* /*killer*/)
- {
- Summons.DespawnAll();
- Talk(SAY_DEATH);
- if (instance)
- instance->SetData(TYPE_JARAXXUS, DONE);
- }
-
- void JustSummoned(Creature* summoned)
- {
- Summons.Summon(summoned);
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- me->SetInCombatWithZone();
- if (instance)
- instance->SetData(TYPE_JARAXXUS, IN_PROGRESS);
- Talk(SAY_AGGRO);
- }
-
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
-
- if (m_uiSummonInfernalEruptionTimer <= uiDiff)
+ void KilledUnit(Unit* who)
{
- Talk(EMOTE_INFERNAL_ERUPTION);
- Talk(SAY_INFERNAL_ERUPTION);
- DoCast(SPELL_INFERNAL_ERUPTION);
- m_uiSummonInfernalEruptionTimer = 2*MINUTE*IN_MILLISECONDS;
- } else m_uiSummonInfernalEruptionTimer -= uiDiff;
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ {
+ Talk(SAY_KILL_PLAYER);
+ if (instance)
+ instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
+ }
+ }
- if (m_uiSummonNetherPortalTimer <= uiDiff)
+ void JustDied(Unit* /*killer*/)
{
- Talk(EMOTE_NETHER_PORTAL);
- Talk(SAY_MISTRESS_OF_PAIN);
- DoCast(SPELL_NETHER_PORTAL);
- m_uiSummonNetherPortalTimer = 2*MINUTE*IN_MILLISECONDS;
- } else m_uiSummonNetherPortalTimer -= uiDiff;
+ _JustDied();
+ Talk(SAY_DEATH);
+ }
- if (m_uiFelFireballTimer <= uiDiff)
+ void JustSummoned(Creature* summoned)
{
- DoCastVictim(SPELL_FEL_FIREBALL);
- m_uiFelFireballTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiFelFireballTimer -= uiDiff;
+ summons.Summon(summoned);
+ }
- if (m_uiFelLightningTimer <= uiDiff)
+ void EnterCombat(Unit* /*who*/)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_FEL_LIGHTING);
- m_uiFelLightningTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else m_uiFelLightningTimer -= uiDiff;
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
- if (m_uiIncinerateFleshTimer <= uiDiff)
+ void UpdateAI(const uint32 diff)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true))
- {
- Talk(EMOTE_INCINERATE, target->GetGUID());
- Talk(SAY_INCINERATE);
- DoCast(target, SPELL_INCINERATE_FLESH);
- }
- m_uiIncinerateFleshTimer = urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiIncinerateFleshTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- if (m_uiNetherPowerTimer <= uiDiff)
- {
- me->CastCustomSpell(SPELL_NETHER_POWER, SPELLVALUE_AURA_STACK, RAID_MODE<uint32>(5, 10, 5,10), me, true);
- m_uiNetherPowerTimer = 40*IN_MILLISECONDS;
- } else m_uiNetherPowerTimer -= uiDiff;
+ events.Update(diff);
- if (m_uiLegionFlameTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true))
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- Talk(EMOTE_LEGION_FLAME, target->GetGUID());
- DoCast(target, SPELL_LEGION_FLAME);
+ switch (eventId)
+ {
+ case EVENT_FEL_FIREBALL:
+ DoCastVictim(SPELL_FEL_FIREBALL);
+ events.ScheduleEvent(EVENT_FEL_FIREBALL, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_FEL_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_LORD_HITTIN))
+ DoCast(target, SPELL_FEL_LIGHTING);
+ events.ScheduleEvent(EVENT_FEL_LIGHTNING, urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS));
+ return;
+ case EVENT_INCINERATE_FLESH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_LORD_HITTIN))
+ {
+ Talk(EMOTE_INCINERATE, target->GetGUID());
+ Talk(SAY_INCINERATE);
+ DoCast(target, SPELL_INCINERATE_FLESH);
+ }
+ events.ScheduleEvent(EVENT_INCINERATE_FLESH, urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ return;
+ case EVENT_NETHER_POWER:
+ me->CastCustomSpell(SPELL_NETHER_POWER, SPELLVALUE_AURA_STACK, RAID_MODE<uint32>(5, 10, 5,10), me, true);
+ events.ScheduleEvent(EVENT_NETHER_POWER, 40*IN_MILLISECONDS);
+ return;
+ case EVENT_LEGION_FLAME:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_LORD_HITTIN))
+ {
+ Talk(EMOTE_LEGION_FLAME, target->GetGUID());
+ DoCast(target, SPELL_LEGION_FLAME);
+ }
+ events.ScheduleEvent(EVENT_LEGION_FLAME, 30*IN_MILLISECONDS);
+ return;
+ case EVENT_SUMMONO_NETHER_PORTAL:
+ Talk(EMOTE_NETHER_PORTAL);
+ Talk(SAY_MISTRESS_OF_PAIN);
+ DoCast(SPELL_NETHER_PORTAL);
+ events.ScheduleEvent(EVENT_SUMMONO_NETHER_PORTAL, 2*MINUTE*IN_MILLISECONDS);
+ return;
+ case EVENT_SUMMON_INFERNAL_ERUPTION:
+ Talk(EMOTE_INFERNAL_ERUPTION);
+ Talk(SAY_INFERNAL_ERUPTION);
+ DoCast(SPELL_INFERNAL_ERUPTION);
+ events.ScheduleEvent(EVENT_SUMMON_INFERNAL_ERUPTION, 2*MINUTE*IN_MILLISECONDS);
+ return;
+ }
}
- m_uiLegionFlameTimer = 30*IN_MILLISECONDS;
- } else m_uiLegionFlameTimer -= uiDiff;
- DoMeleeAttackIfReady();
- }
- };
+ DoMeleeAttackIfReady();
+ }
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_jaraxxusAI(creature);
+ }
};
class mob_legion_flame : public CreatureScript
{
-public:
- mob_legion_flame() : CreatureScript("mob_legion_flame") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_legion_flameAI(creature);
- }
+ public:
+ mob_legion_flame() : CreatureScript("mob_legion_flame") { }
- struct mob_legion_flameAI : public Scripted_NoMovementAI
- {
- mob_legion_flameAI(Creature* creature) : Scripted_NoMovementAI(creature)
+ struct mob_legion_flameAI : public Scripted_NoMovementAI
{
- Reset();
- }
+ mob_legion_flameAI(Creature* creature) : Scripted_NoMovementAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- void Reset()
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetInCombatWithZone();
- DoCast(SPELL_LEGION_FLAME_EFFECT);
- }
+ void Reset()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetInCombatWithZone();
+ DoCast(SPELL_LEGION_FLAME_EFFECT);
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ UpdateVictim();
+ if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
+ me->DespawnOrUnsummon();
+ }
+ private:
+ InstanceScript* _instance;
+ };
- void UpdateAI(const uint32 /*uiDiff*/)
+ CreatureAI* GetAI(Creature* creature) const
{
- UpdateVictim();
+ return new mob_legion_flameAI(creature);
}
- };
-
};
class mob_infernal_volcano : public CreatureScript
{
-public:
- mob_infernal_volcano() : CreatureScript("mob_infernal_volcano") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_infernal_volcanoAI(creature);
- }
+ public:
+ mob_infernal_volcano() : CreatureScript("mob_infernal_volcano") { }
- struct mob_infernal_volcanoAI : public Scripted_NoMovementAI
- {
- mob_infernal_volcanoAI(Creature* creature) : Scripted_NoMovementAI(creature), Summons(me)
+ struct mob_infernal_volcanoAI : public Scripted_NoMovementAI
{
- instance = creature->GetInstanceScript();
- Reset();
- }
+ mob_infernal_volcanoAI(Creature* creature) : Scripted_NoMovementAI(creature), _summons(me)
+ {
+ }
- InstanceScript* instance;
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
- SummonList Summons;
+ if (!IsHeroic())
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
+ else
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
- void Reset()
- {
- me->SetReactState(REACT_PASSIVE);
+ _summons.DespawnAll();
+ }
- if (!IsHeroic())
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
- else
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
+ void IsSummonedBy(Unit* /*summoner*/)
+ {
+ DoCast(SPELL_INFERNAL_ERUPTION_EFFECT);
+ }
- Summons.DespawnAll();
- }
+ void JustSummoned(Creature* summoned)
+ {
+ _summons.Summon(summoned);
+ // makes immediate corpse despawn of summoned Felflame Infernals
+ summoned->SetCorpseDelay(0);
+ }
- void IsSummonedBy(Unit* /*summoner*/)
- {
- DoCast(SPELL_INFERNAL_ERUPTION_EFFECT);
- }
+ void JustDied(Unit* /*killer*/)
+ {
+ // used to despawn corpse immediately
+ me->DespawnOrUnsummon();
+ }
- void JustSummoned(Creature* summoned)
- {
- Summons.Summon(summoned);
- // makes immediate corpse despawn of summoned Felflame Infernals
- summoned->SetCorpseDelay(0);
- }
+ void UpdateAI(uint32 const /*diff*/) {}
+
+ private:
+ SummonList _summons;
+ };
- void JustDied(Unit* /*killer*/)
+ CreatureAI* GetAI(Creature* creature) const
{
- // used to despawn corpse immediately
- me->DespawnOrUnsummon();
+ return new mob_infernal_volcanoAI(creature);
}
-
- void UpdateAI(uint32 const /*diff*/) {}
- };
-
};
class mob_fel_infernal : public CreatureScript
{
-public:
- mob_fel_infernal() : CreatureScript("mob_fel_infernal") { }
+ public:
+ mob_fel_infernal() : CreatureScript("mob_fel_infernal") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_fel_infernalAI(creature);
- }
-
- struct mob_fel_infernalAI : public ScriptedAI
- {
- mob_fel_infernalAI(Creature* creature) : ScriptedAI(creature)
+ struct mob_fel_infernalAI : public ScriptedAI
{
- instance = creature->GetInstanceScript();
- Reset();
- }
-
- InstanceScript* instance;
- uint32 m_uiFelStreakTimer;
+ mob_fel_infernalAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- void Reset()
- {
- m_uiFelStreakTimer = 30*IN_MILLISECONDS;
- me->SetInCombatWithZone();
- }
+ void Reset()
+ {
+ _felStreakTimer = 30*IN_MILLISECONDS;
+ me->SetInCombatWithZone();
+ }
- /*void SpellHitTarget(Unit* target, const SpellInfo* pSpell)
- {
- if (pSpell->Id == SPELL_FEL_STREAK)
- DoCastAOE(SPELL_FEL_INFERNO); //66517
- }*/
+ void UpdateAI(const uint32 diff)
+ {
+ if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
+ {
+ me->DespawnOrUnsummon();
+ return;
+ }
- void UpdateAI(const uint32 uiDiff)
- {
- if (!UpdateVictim())
- return;
+ if (!UpdateVictim())
+ return;
- if (instance && instance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
- me->DespawnOrUnsummon();
+ if (_felStreakTimer <= diff)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_FEL_STREAK);
+ _felStreakTimer = 30*IN_MILLISECONDS;
+ }
+ else
+ _felStreakTimer -= diff;
- if (m_uiFelStreakTimer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_FEL_STREAK);
- m_uiFelStreakTimer = 30*IN_MILLISECONDS;
- } else m_uiFelStreakTimer -= uiDiff;
+ DoMeleeAttackIfReady();
+ }
+ private:
+ uint32 _felStreakTimer;
+ InstanceScript* _instance;
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_fel_infernalAI(creature);
}
- };
-
};
class mob_nether_portal : public CreatureScript
{
-public:
- mob_nether_portal() : CreatureScript("mob_nether_portal") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_nether_portalAI(creature);
- }
+ public:
+ mob_nether_portal() : CreatureScript("mob_nether_portal") { }
- struct mob_nether_portalAI : public ScriptedAI
- {
- mob_nether_portalAI(Creature* creature) : ScriptedAI(creature), Summons(me)
+ struct mob_nether_portalAI : public ScriptedAI
{
- instance = creature->GetInstanceScript();
- Reset();
- }
+ mob_nether_portalAI(Creature* creature) : ScriptedAI(creature), _summons(me)
+ {
+ }
- InstanceScript* instance;
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
- SummonList Summons;
+ if (!IsHeroic())
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
+ else
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
- void Reset()
- {
- me->SetReactState(REACT_PASSIVE);
+ _summons.DespawnAll();
+ }
- if (!IsHeroic())
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
- else
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED);
+ void IsSummonedBy(Unit* /*summoner*/)
+ {
+ DoCast(SPELL_NETHER_PORTAL_EFFECT);
+ }
- Summons.DespawnAll();
- }
+ void JustSummoned(Creature* summoned)
+ {
+ _summons.Summon(summoned);
+ // makes immediate corpse despawn of summoned Mistress of Pain
+ summoned->SetCorpseDelay(0);
+ }
- void IsSummonedBy(Unit* /*summoner*/)
- {
- DoCast(SPELL_NETHER_PORTAL_EFFECT);
- }
+ void JustDied(Unit* /*killer*/)
+ {
+ // used to despawn corpse immediately
+ me->DespawnOrUnsummon();
+ }
- void JustSummoned(Creature* summoned)
- {
- Summons.Summon(summoned);
- // makes immediate corpse despawn of summoned Mistress of Pain
- summoned->SetCorpseDelay(0);
- }
+ void UpdateAI(uint32 const /*diff*/) {}
+
+ private:
+ SummonList _summons;
+ };
- void JustDied(Unit* /*killer*/)
+ CreatureAI* GetAI(Creature* creature) const
{
- // used to despawn corpse immediately
- me->DespawnOrUnsummon();
+ return new mob_nether_portalAI(creature);
}
-
- void UpdateAI(uint32 const /*diff*/) {}
- };
-
};
class mob_mistress_of_pain : public CreatureScript
{
-public:
- mob_mistress_of_pain() : CreatureScript("mob_mistress_of_pain") { }
+ public:
+ mob_mistress_of_pain() : CreatureScript("mob_mistress_of_pain") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_mistress_of_painAI(creature);
- }
+ struct mob_mistress_of_painAI : public ScriptedAI
+ {
+ mob_mistress_of_painAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ if (_instance)
+ _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
+ }
+
+ void Reset()
+ {
+ _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 30*IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_SPINNING_STRIKE, 30*IN_MILLISECONDS);
+ if (IsHeroic())
+ _events.ScheduleEvent(EVENT_MISTRESS_KISS, 15*IN_MILLISECONDS);
+ me->SetInCombatWithZone();
+ }
- struct mob_mistress_of_painAI : public ScriptedAI
- {
- mob_mistress_of_painAI(Creature* creature) : ScriptedAI(creature)
+ void JustDied(Unit* /*killer*/)
+ {
+ if (_instance)
+ _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
+ {
+ me->DespawnOrUnsummon();
+ return;
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHIVAN_SLASH:
+ DoCastVictim(SPELL_SHIVAN_SLASH);
+ _events.ScheduleEvent(EVENT_SHIVAN_SLASH, 30*IN_MILLISECONDS);
+ return;
+ case EVENT_SPINNING_STRIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_SPINNING_STRIKE);
+ _events.ScheduleEvent(EVENT_SPINNING_STRIKE, 30*IN_MILLISECONDS);
+ return;
+ case EVENT_MISTRESS_KISS:
+ DoCast(me, SPELL_MISTRESS_KISS);
+ _events.ScheduleEvent(EVENT_MISTRESS_KISS, 30*IN_MILLISECONDS);
+ return;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
{
- instance = creature->GetInstanceScript();
- if (instance)
- instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
- Reset();
+ return new mob_mistress_of_painAI(creature);
}
+};
- InstanceScript* instance;
- uint32 m_uiShivanSlashTimer;
- uint32 m_uiSpinningStrikeTimer;
- uint32 m_uiMistressKissTimer;
+class spell_mistress_kiss : public SpellScriptLoader
+{
+ public:
+ spell_mistress_kiss() : SpellScriptLoader("spell_mistress_kiss") { }
- void Reset()
+ class spell_mistress_kiss_AuraScript : public AuraScript
{
- m_uiShivanSlashTimer = 30*IN_MILLISECONDS;
- m_uiSpinningStrikeTimer = 30*IN_MILLISECONDS;
- m_uiMistressKissTimer = 15*IN_MILLISECONDS;
- me->SetInCombatWithZone();
- }
+ PrepareAuraScript(spell_mistress_kiss_AuraScript);
- void JustDied(Unit* /*killer*/)
+ bool Load()
+ {
+ if (GetCaster())
+ if (sSpellMgr->GetSpellIdForDifficulty(SPELL_MISTRESS_KISS_DAMAGE_SILENCE, GetCaster()))
+ return true;
+ return false;
+ }
+
+ void HandleDummyTick(AuraEffect const* /*aurEff*/)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetTarget();
+ if (caster && target)
+ {
+ if (target->HasUnitState(UNIT_STATE_CASTING))
+ {
+ caster->CastSpell(target, SPELL_MISTRESS_KISS_DAMAGE_SILENCE, true);
+ target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_mistress_kiss_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
{
- if (instance)
- instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
+ return new spell_mistress_kiss_AuraScript();
}
+};
- void UpdateAI(const uint32 uiDiff)
+class spell_mistress_kiss_area : public SpellScriptLoader
+{
+ public:
+ spell_mistress_kiss_area() : SpellScriptLoader("spell_mistress_kiss_area") {}
+
+ class spell_mistress_kiss_area_SpellScript : public SpellScript
{
- if (instance && instance->GetData(TYPE_JARAXXUS) != IN_PROGRESS)
+ PrepareSpellScript(spell_mistress_kiss_area_SpellScript)
+
+ bool Load()
{
- me->DespawnOrUnsummon();
- return;
+ if (GetCaster())
+ if (sSpellMgr->GetSpellIdForDifficulty(SPELL_MISTRESS_KISS_DEBUFF, GetCaster()))
+ return true;
+ return false;
}
- if (!UpdateVictim())
- return;
-
- if (m_uiShivanSlashTimer <= uiDiff)
+ void HandleScript(SpellEffIndex /*effIndex*/)
{
- DoCastVictim(SPELL_SHIVAN_SLASH);
- m_uiShivanSlashTimer = 30*IN_MILLISECONDS;
- } else m_uiShivanSlashTimer -= uiDiff;
+ Unit* caster = GetCaster();
+ Unit* target = GetHitUnit();
+ if (caster && target)
+ caster->CastSpell(target, SPELL_MISTRESS_KISS_DEBUFF, true);
+ }
- if (m_uiSpinningStrikeTimer <= uiDiff)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
- DoCast(target, SPELL_SPINNING_STRIKE);
- m_uiSpinningStrikeTimer = 30*IN_MILLISECONDS;
- } else m_uiSpinningStrikeTimer -= uiDiff;
+ // get a list of players with mana
+ std::list<WorldObject*> _targets;
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ if ((*itr)->ToUnit()->getPowerType() == POWER_MANA)
+ _targets.push_back(*itr);
+
+ // pick a random target and kiss him
+ if (WorldObject* _target = Trinity::Containers::SelectRandomContainerElement(_targets))
+ {
+ // correctly fill "targets" for the visual effect
+ targets.clear();
+ targets.push_back(_target);
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(_target->ToUnit(), SPELL_MISTRESS_KISS_DEBUFF, true);
+ }
+ }
- if (IsHeroic() && m_uiMistressKissTimer <= uiDiff)
+ void Register()
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
- DoCast(target, SPELL_MISTRESS_KISS);
- m_uiMistressKissTimer = 30*IN_MILLISECONDS;
- } else m_uiMistressKissTimer -= uiDiff;
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mistress_kiss_area_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
- DoMeleeAttackIfReady();
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mistress_kiss_area_SpellScript();
}
- };
-
};
void AddSC_boss_jaraxxus()
@@ -530,4 +596,7 @@ void AddSC_boss_jaraxxus()
new mob_fel_infernal();
new mob_nether_portal();
new mob_mistress_of_pain();
+
+ new spell_mistress_kiss();
+ new spell_mistress_kiss_area();
}
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 e55cd550a95..2cb0854b3c4 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -15,24 +15,14 @@
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: northrend_beasts
-SD%Complete: 90%
-SDComment: based on /dev/rsa
-SDCategory:
-EndScriptData */
// Known bugs:
-// Gormok - Not implemented as a vehicle
-// - Snobold Firebomb
-// - Snobolled (creature at back)
-// Snakes - miss the 1-hitkill from emerging
-// - visual changes between mobile and stationary models seems not to work sometimes
+// Gormok - Snobolled (creature at back)
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "trial_of_the_crusader.h"
-#include "Player.h"
+#include "Vehicle.h"
enum Yells
{
@@ -45,7 +35,7 @@ enum Yells
// Icehowl
EMOTE_TRAMPLE_START = 0,
EMOTE_TRAMPLE_CRASH = 1,
- EMOTE_TRAMPLE_FAIL = 2,
+ EMOTE_TRAMPLE_FAIL = 2
};
enum Equipment
@@ -53,7 +43,7 @@ enum Equipment
EQUIP_MAIN = 50760,
EQUIP_OFFHAND = 48040,
EQUIP_RANGED = 47267,
- EQUIP_DONE = EQUIP_NO_CHANGE,
+ EQUIP_DONE = EQUIP_NO_CHANGE
};
enum Model
@@ -61,13 +51,15 @@ enum Model
MODEL_ACIDMAW_STATIONARY = 29815,
MODEL_ACIDMAW_MOBILE = 29816,
MODEL_DREADSCALE_STATIONARY = 26935,
- MODEL_DREADSCALE_MOBILE = 24564,
+ MODEL_DREADSCALE_MOBILE = 24564
};
-enum Summons
+enum BeastSummons
{
NPC_SNOBOLD_VASSAL = 34800,
+ NPC_FIRE_BOMB = 34854,
NPC_SLIME_POOL = 35176,
+ MAX_SNOBOLDS = 4
};
enum BossSpells
@@ -108,332 +100,446 @@ enum BossSpells
SPELL_ARCTIC_BREATH = 66689,
SPELL_TRAMPLE = 66734,
SPELL_FROTHING_RAGE = 66759,
- SPELL_STAGGERED_DAZE = 66758,
+ SPELL_STAGGERED_DAZE = 66758
};
-class boss_gormok : public CreatureScript
+enum MyActions
{
-public:
- boss_gormok() : CreatureScript("boss_gormok") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_gormokAI(creature);
- }
+ ACTION_ENABLE_FIRE_BOMB = 1,
+ ACTION_DISABLE_FIRE_BOMB = 2
+};
- struct boss_gormokAI : public ScriptedAI
- {
- boss_gormokAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- instance = creature->GetInstanceScript();
- }
+enum Events
+{
+ // Gormok
+ EVENT_IMPALE = 1,
+ EVENT_STAGGERING_STOMP = 2,
+ EVENT_THROW = 3,
- InstanceScript* instance;
+ // Snobold
+ EVENT_FIRE_BOMB = 4,
+ EVENT_BATTER = 5,
+ EVENT_HEAD_CRACK = 6,
- uint32 m_uiImpaleTimer;
- uint32 m_uiStaggeringStompTimer;
- SummonList Summons;
- uint32 m_uiSummonTimer;
- uint32 m_uiSummonCount;
+ // Acidmaw & Dreadscale
+ EVENT_BITE = 7,
+ EVENT_SPEW = 8,
+ EVENT_SLIME_POOL = 9,
+ EVENT_SPIT = 10,
+ EVENT_SPRAY = 11,
+ EVENT_SWEEP = 12,
+ EVENT_SUBMERGE = 13,
+ EVENT_EMERGE = 14,
+ EVENT_SUMMON_ACIDMAW = 15,
- void Reset()
- {
- m_uiImpaleTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- m_uiStaggeringStompTimer = 15*IN_MILLISECONDS;
- m_uiSummonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);;
+ // Icehowl
+ EVENT_FEROCIOUS_BUTT = 16,
+ EVENT_MASSIVE_CRASH = 17,
+ EVENT_WHIRL = 18,
+ EVENT_ARCTIC_BREATH = 19,
+ EVENT_TRAMPLE = 20
+};
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL ||
- GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
- m_uiSummonCount = 5;
- else
- m_uiSummonCount = 4;
+enum Phases
+{
+ PHASE_MOBILE = 1,
+ PHASE_STATIONARY = 2,
+ PHASE_SUBMERGED = 3,
- Summons.DespawnAll();
- }
+ PHASE_MASK_MOBILE = 1 << PHASE_MOBILE,
+ PHASE_MASK_STATIONARY = 1 << PHASE_STATIONARY
+};
- void EnterEvadeMode()
- {
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- ScriptedAI::EnterEvadeMode();
- }
+class boss_gormok : public CreatureScript
+{
+ public:
+ boss_gormok() : CreatureScript("boss_gormok") { }
- void MovementInform(uint32 type, uint32 pointId)
+ struct boss_gormokAI : public BossAI
{
- if (type != POINT_MOTION_TYPE)
- return;
-
- switch (pointId)
+ boss_gormokAI(Creature* creature) : BossAI(creature, BOSS_BEASTS)
{
- case 0:
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetInCombatWithZone();
- break;
}
- }
- void JustDied(Unit* /*killer*/)
- {
- if (instance)
- instance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_DONE);
- }
+ void Reset()
+ {
+ events.ScheduleEvent(EVENT_IMPALE, urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_STAGGERING_STOMP, 15*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_THROW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
- void JustReachedHome()
- {
- if (instance)
+ summons.DespawnAll();
+ }
+
+ void EnterEvadeMode()
{
instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- instance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ ScriptedAI::EnterEvadeMode();
}
- me->DespawnOrUnsummon();
- }
- void EnterCombat(Unit* /*who*/)
- {
- me->SetInCombatWithZone();
- instance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_IN_PROGRESS);
- }
-
- void JustSummoned(Creature* summon)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ void MovementInform(uint32 type, uint32 pointId)
{
- if (summon->GetEntry() == NPC_SNOBOLD_VASSAL)
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (pointId)
{
- summon->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 10.0f, 20.0f);
- DoCast(me, SPELL_RISING_ANGER);
- --m_uiSummonCount;
+ case 0:
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetInCombatWithZone();
+ break;
+ default:
+ break;
}
- summon->AI()->AttackStart(target);
}
- Summons.Summon(summon);
- }
- void SummonedCreatureDespawn(Creature* summon)
- {
- if (summon->GetEntry() == NPC_SNOBOLD_VASSAL)
- if (summon->isAlive())
- ++m_uiSummonCount;
- Summons.Despawn(summon);
- }
+ void JustDied(Unit* /*killer*/)
+ {
+ if (instance)
+ instance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_DONE);
+ }
- void UpdateAI(uint32 const diff)
- {
- if (!UpdateVictim())
- return;
+ void JustReachedHome()
+ {
+ if (instance)
+ {
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ instance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ }
+ me->DespawnOrUnsummon();
+ }
- if (m_uiImpaleTimer <= diff)
+ void EnterCombat(Unit* /*who*/)
{
- DoCastVictim(SPELL_IMPALE);
- m_uiImpaleTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- } else m_uiImpaleTimer -= diff;
+ _EnterCombat();
+ me->SetInCombatWithZone();
+ instance->SetData(TYPE_NORTHREND_BEASTS, GORMOK_IN_PROGRESS);
- if (m_uiStaggeringStompTimer <= diff)
+ for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
+ {
+ if (Creature* pSnobold = DoSpawnCreature(NPC_SNOBOLD_VASSAL, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
+ {
+ pSnobold->EnterVehicle(me, i);
+ pSnobold->SetInCombatWithZone();
+ pSnobold->AI()->DoAction(ACTION_ENABLE_FIRE_BOMB);
+ }
+ }
+ }
+
+ void DamageTaken(Unit* /*who*/, uint32& damage)
{
- DoCastVictim(SPELL_STAGGERING_STOMP);
- m_uiStaggeringStompTimer = urand(20*IN_MILLISECONDS, 25*IN_MILLISECONDS);
- } else m_uiStaggeringStompTimer -= diff;
+ // despawn the remaining passengers on death
+ if (damage >= me->GetHealth())
+ for (uint8 i = 0; i < MAX_SNOBOLDS; ++i)
+ if (Unit* pSnobold = me->GetVehicleKit()->GetPassenger(i))
+ pSnobold->ToCreature()->DespawnOrUnsummon();
+ }
- if (m_uiSummonTimer <= diff)
+ void UpdateAI(uint32 const diff)
{
- if (m_uiSummonCount > 0)
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- me->SummonCreature(NPC_SNOBOLD_VASSAL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN);
- Talk(EMOTE_SNOBOLLED);
+ switch (eventId)
+ {
+ case EVENT_IMPALE:
+ DoCastVictim(SPELL_IMPALE);
+ events.ScheduleEvent(EVENT_IMPALE, urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS));
+ return;
+ case EVENT_STAGGERING_STOMP:
+ DoCastVictim(SPELL_STAGGERING_STOMP);
+ events.ScheduleEvent(EVENT_STAGGERING_STOMP, 15*IN_MILLISECONDS);
+ return;
+ case EVENT_THROW:
+ for (uint8 i = 0; i < MAX_SNOBOLDS; ++i)
+ {
+ if (Unit* pSnobold = me->GetVehicleKit()->GetPassenger(i))
+ {
+ pSnobold->ExitVehicle();
+ pSnobold->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ pSnobold->ToCreature()->SetReactState(REACT_AGGRESSIVE);
+ pSnobold->ToCreature()->AI()->DoAction(ACTION_DISABLE_FIRE_BOMB);
+ pSnobold->CastSpell(me, SPELL_RISING_ANGER, true);
+ Talk(EMOTE_SNOBOLLED);
+ break;
+ }
+ }
+ events.ScheduleEvent(EVENT_THROW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ default:
+ return;
+ }
}
- m_uiSummonTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiSummonTimer -= diff;
- DoMeleeAttackIfReady();
- }
- };
+ DoMeleeAttackIfReady();
+ }
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_gormokAI(creature);
+ }
};
class mob_snobold_vassal : public CreatureScript
{
-public:
- mob_snobold_vassal() : CreatureScript("mob_snobold_vassal") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_snobold_vassalAI(creature);
- }
+ public:
+ mob_snobold_vassal() : CreatureScript("mob_snobold_vassal") { }
- struct mob_snobold_vassalAI : public ScriptedAI
- {
- mob_snobold_vassalAI(Creature* creature) : ScriptedAI(creature)
+ struct mob_snobold_vassalAI : public ScriptedAI
{
- instance = creature->GetInstanceScript();
- if (instance)
- instance->SetData(DATA_SNOBOLD_COUNT, INCREASE);
- }
+ mob_snobold_vassalAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ if (_instance)
+ _instance->SetData(DATA_SNOBOLD_COUNT, INCREASE);
+ }
- InstanceScript* instance;
- uint32 m_uiFireBombTimer;
- uint32 m_uiBatterTimer;
- uint32 m_uiHeadCrackTimer;
- uint64 m_uiBossGUID;
- uint64 m_uiTargetGUID;
- bool m_bTargetDied;
+ void Reset()
+ {
+ _events.ScheduleEvent(EVENT_BATTER, 5*IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_HEAD_CRACK, 25*IN_MILLISECONDS);
- void Reset()
- {
- m_uiFireBombTimer = 15000;
- m_uiBatterTimer = 5000;
- m_uiHeadCrackTimer = 25000;
+ _targetGUID = 0;
+ _targetDied = false;
- m_uiTargetGUID = 0;
- m_bTargetDied = false;
- if (instance)
- m_uiBossGUID = instance->GetData64(NPC_GORMOK);
- //Workaround for Snobold
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void EnterEvadeMode()
- {
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- ScriptedAI::EnterEvadeMode();
- }
+ if (_instance)
+ _bossGUID = _instance->GetData64(NPC_GORMOK);
+ //Workaround for Snobold
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ }
- void EnterCombat(Unit* who)
- {
- m_uiTargetGUID = who->GetGUID();
- me->TauntApply(who);
- DoCast(who, SPELL_SNOBOLLED);
- }
+ void EnterEvadeMode()
+ {
+ ScriptedAI::EnterEvadeMode();
+ }
- void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
- {
- if (pDoneBy->GetGUID()==m_uiTargetGUID)
- uiDamage = 0;
- }
+ void EnterCombat(Unit* who)
+ {
+ _targetGUID = who->GetGUID();
+ me->TauntApply(who);
+ DoCast(who, SPELL_SNOBOLLED);
+ }
- void MovementInform(uint32 type, uint32 pointId)
- {
- if (type != POINT_MOTION_TYPE)
- return;
+ void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
+ {
+ if (pDoneBy->GetGUID() == _targetGUID)
+ uiDamage = 0;
+ }
- switch (pointId)
+ void MovementInform(uint32 type, uint32 pointId)
{
- case 0:
- if (m_bTargetDied)
- me->DespawnOrUnsummon();
- break;
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (pointId)
+ {
+ case 0:
+ if (_targetDied)
+ me->DespawnOrUnsummon();
+ break;
+ default:
+ break;
+ }
}
- }
- void JustDied(Unit* /*killer*/)
- {
- if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
- if (target->isAlive())
- target->RemoveAurasDueToSpell(SPELL_SNOBOLLED);
- if (instance)
- instance->SetData(DATA_SNOBOLD_COUNT, DECREASE);
- }
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Unit* target = Unit::GetPlayer(*me, _targetGUID))
+ if (target->isAlive())
+ target->RemoveAurasDueToSpell(SPELL_SNOBOLLED);
+ if (_instance)
+ _instance->SetData(DATA_SNOBOLD_COUNT, DECREASE);
+ }
- void UpdateAI(uint32 const diff)
- {
- if (m_bTargetDied || !UpdateVictim())
- return;
+ void DoAction(int32 const action)
+ {
+ switch (action)
+ {
+ case ACTION_ENABLE_FIRE_BOMB:
+ _events.ScheduleEvent(EVENT_FIRE_BOMB, urand(5*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ break;
+ case ACTION_DISABLE_FIRE_BOMB:
+ _events.CancelEvent(EVENT_FIRE_BOMB);
+ break;
+ default:
+ break;
+ }
+ }
- if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
+ void UpdateAI(uint32 const diff)
{
- if (!target->isAlive())
+ if (!UpdateVictim() || _targetDied)
+ return;
+
+ if (Unit* target = Unit::GetPlayer(*me, _targetGUID))
{
- if (instance)
+ if (!target->isAlive())
{
- Unit* gormok = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_GORMOK));
- if (gormok && gormok->isAlive())
+ if (_instance)
{
- SetCombatMovement(false);
- m_bTargetDied = true;
- me->GetMotionMaster()->MoveJump(gormok->GetPositionX(), gormok->GetPositionY(), gormok->GetPositionZ(), 15.0f, 15.0f);
- }
- else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- m_uiTargetGUID = target2->GetGUID();
- me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f);
+ Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_GORMOK));
+ if (gormok && gormok->isAlive())
+ {
+ SetCombatMovement(false);
+ _targetDied = true;
+
+ // looping through Gormoks seats
+ for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
+ {
+ if (!gormok->GetVehicleKit()->GetPassenger(i))
+ {
+ me->EnterVehicle(gormok, i);
+ DoAction(ACTION_ENABLE_FIRE_BOMB);
+ break;
+ }
+ }
+ }
+ else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ {
+ _targetGUID = target2->GetGUID();
+ me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f);
+ }
}
}
}
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FIRE_BOMB:
+ if (me->GetVehicleBase())
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, -me->GetVehicleBase()->GetCombatReach(), true))
+ me->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), SPELL_FIRE_BOMB, true);
+ _events.ScheduleEvent(EVENT_FIRE_BOMB, 20*IN_MILLISECONDS);
+ return;
+ case EVENT_HEAD_CRACK:
+ // commented out while SPELL_SNOBOLLED gets fixed
+ //if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
+ DoCastVictim(SPELL_HEAD_CRACK);
+ _events.ScheduleEvent(EVENT_HEAD_CRACK, 30*IN_MILLISECONDS);
+ return;
+ case EVENT_BATTER:
+ // commented out while SPELL_SNOBOLLED gets fixed
+ //if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
+ DoCastVictim(SPELL_BATTER);
+ _events.ScheduleEvent(EVENT_BATTER, 10*IN_MILLISECONDS);
+ return;
+ default:
+ return;
+ }
+ }
+
+ // do melee attack only when not on Gormoks back
+ if (!me->GetVehicleBase())
+ DoMeleeAttackIfReady();
}
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ uint64 _bossGUID;
+ uint64 _targetGUID;
+ bool _targetDied;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_snobold_vassalAI(creature);
+ }
+};
+
+class npc_firebomb : public CreatureScript
+{
+ public:
+ npc_firebomb() : CreatureScript("npc_firebomb") { }
- if (m_uiFireBombTimer < diff)
+ struct npc_firebombAI : public ScriptedAI
+ {
+ npc_firebombAI(Creature* creature) : ScriptedAI(creature)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_FIRE_BOMB);
- m_uiFireBombTimer = 20000;
+ _instance = creature->GetInstanceScript();
}
- else m_uiFireBombTimer -= diff;
- if (m_uiBatterTimer < diff)
+ void Reset()
{
- if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
- DoCast(target, SPELL_BATTER);
- m_uiBatterTimer = 10000;
+ DoCast(me, SPELL_FIRE_BOMB_DOT, true);
+ SetCombatMovement(false);
+ me->SetReactState(REACT_PASSIVE);
+ me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
}
- else m_uiBatterTimer -= diff;
- if (m_uiHeadCrackTimer < diff)
+ void UpdateAI(uint32 const /*diff*/)
{
- if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
- DoCast(target, SPELL_HEAD_CRACK);
- m_uiHeadCrackTimer = 35000;
+ if (_instance->GetData(TYPE_NORTHREND_BEASTS) != GORMOK_IN_PROGRESS)
+ me->DespawnOrUnsummon();
}
- else m_uiHeadCrackTimer -= diff;
- DoMeleeAttackIfReady();
- }
- };
+ private:
+ InstanceScript* _instance;
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_firebombAI(creature);
+ }
};
-struct boss_jormungarAI : public ScriptedAI
+struct boss_jormungarAI : public BossAI
{
- boss_jormungarAI(Creature* creature) : ScriptedAI(creature)
+ boss_jormungarAI(Creature* creature) : BossAI(creature, BOSS_BEASTS)
{
- instanceScript = creature->GetInstanceScript();
}
void Reset()
{
- enraged = false;
- biteTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- spewTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- slimePoolTimer = 15*IN_MILLISECONDS;
- spitTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- sprayTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- sweepTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
+ Enraged = false;
+
+ events.ScheduleEvent(EVENT_SPIT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_SPRAY, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_SWEEP, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_BITE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_SPEW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_SLIME_POOL, 15*IN_MILLISECONDS, 0, PHASE_MOBILE);
}
void JustDied(Unit* /*killer*/)
{
- if (instanceScript)
+ if (instance)
{
- if (Creature* otherWorm = Unit::GetCreature(*me, instanceScript->GetData64(otherWormEntry)))
+ if (Creature* otherWorm = Unit::GetCreature(*me, instance->GetData64(OtherWormEntry)))
{
if (!otherWorm->isAlive())
{
- instanceScript->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE);
+ instance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_DONE);
me->DespawnOrUnsummon();
otherWorm->DespawnOrUnsummon();
}
else
- instanceScript->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL);
+ instance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_SPECIAL);
}
}
}
void JustReachedHome()
{
- if (instanceScript && instanceScript->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
- {
- instanceScript->SetData(TYPE_NORTHREND_BEASTS, FAIL);
- }
+ // prevent losing 2 attempts at once on heroics
+ if (instance && instance->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
+ instance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
me->DespawnOrUnsummon();
}
@@ -441,17 +547,16 @@ struct boss_jormungarAI : public ScriptedAI
void KilledUnit(Unit* who)
{
if (who->GetTypeId() == TYPEID_PLAYER)
- {
- if (instanceScript)
- instanceScript->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
- }
+ if (instance)
+ instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
void EnterCombat(Unit* /*who*/)
{
+ _EnterCombat();
me->SetInCombatWithZone();
- if (instanceScript)
- instanceScript->SetData(TYPE_NORTHREND_BEASTS, SNAKES_IN_PROGRESS);
+ if (instance)
+ instance->SetData(TYPE_NORTHREND_BEASTS, SNAKES_IN_PROGRESS);
}
void UpdateAI(uint32 const diff)
@@ -459,563 +564,597 @@ struct boss_jormungarAI : public ScriptedAI
if (!UpdateVictim())
return;
- if (instanceScript && instanceScript->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL && !enraged)
+ if (!Enraged && instance && instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL)
{
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
DoCast(SPELL_ENRAGE);
- enraged = true;
+ Enraged = true;
Talk(EMOTE_ENRAGE);
- switch (stage)
- {
- case 0:
- break;
- case 4:
- stage = 5;
- submergeTimer = 5*IN_MILLISECONDS;
- break;
- default:
- stage = 7;
- }
}
- switch (stage)
- {
- case 0: // Mobile
- if (biteTimer <= diff)
- {
- DoCastVictim(biteSpell);
- biteTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else biteTimer -= diff;
+ events.Update(diff);
- if (spewTimer <= diff)
- {
- DoCastAOE(spewSpell);
- spewTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else spewTimer -= diff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (slimePoolTimer <= diff)
- {
- /* Spell summon has only 30s duration */
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_EMERGE:
+ Emerge();
+ return;
+ case EVENT_SUBMERGE:
+ Submerge();
+ return;
+ case EVENT_BITE:
+ DoCastVictim(BiteSpell);
+ events.ScheduleEvent(EVENT_BITE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
+ return;
+ case EVENT_SPEW:
+ DoCastAOE(SpewSpell);
+ events.ScheduleEvent(EVENT_SPEW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
+ return;
+ case EVENT_SLIME_POOL:
DoCast(me, SUMMON_SLIME_POOL);
- slimePoolTimer = 30*IN_MILLISECONDS;
- } else slimePoolTimer -= diff;
-
- if (submergeTimer <= diff && !enraged)
- {
- stage = 1;
- submergeTimer = 5*IN_MILLISECONDS;
- } else submergeTimer -= diff;
-
- DoMeleeAttackIfReady();
- break;
- case 1: // Submerge
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- DoCast(me, SPELL_SUBMERGE_0);
- me->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX()+ frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionY() + frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionZ());
- stage = 2;
- case 2: // Wait til emerge
- if (submergeTimer <= diff)
- {
- stage = 3;
- submergeTimer = 50*IN_MILLISECONDS;
- } else submergeTimer -= diff;
- break;
- case 3: // Emerge
- me->SetDisplayId(modelStationary);
- me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
- DoCast(me, SPELL_EMERGE_0);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
- SetCombatMovement(false);
- me->GetMotionMaster()->MoveIdle();
- stage = 4;
- break;
- case 4: // Stationary
- if (sprayTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, spraySpell);
- sprayTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else sprayTimer -= diff;
-
- if (sweepTimer <= diff)
- {
+ events.ScheduleEvent(EVENT_SLIME_POOL, 30*IN_MILLISECONDS, 0, PHASE_MOBILE);
+ return;
+ case EVENT_SUMMON_ACIDMAW:
+ if (Creature* acidmaw = me->SummonCreature(NPC_ACIDMAW, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ acidmaw->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ acidmaw->SetReactState(REACT_AGGRESSIVE);
+ acidmaw->SetInCombatWithZone();
+ acidmaw->CastSpell(acidmaw, SPELL_EMERGE_0);
+ }
+ return;
+ case EVENT_SPRAY:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SpraySpell);
+ events.ScheduleEvent(EVENT_SPRAY, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ return;
+ case EVENT_SWEEP:
DoCastAOE(SPELL_SWEEP_0);
- sweepTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else sweepTimer -= diff;
-
- if (submergeTimer <= diff)
- {
- stage = 5;
- submergeTimer = 10*IN_MILLISECONDS;
- } else submergeTimer -= diff;
-
- DoSpellAttackIfReady(spitSpell);
- break;
- case 5: // Submerge
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- DoCast(me, SPELL_SUBMERGE_0);
- me->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX() + frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionY() + frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionZ());
- stage = 6;
- case 6: // Wait til emerge
- if (submergeTimer <= diff)
- {
- stage = 7;
- submergeTimer = 45*IN_MILLISECONDS;
- } else submergeTimer -= diff;
- break;
- case 7: // Emerge
- me->SetDisplayId(modelMobile);
- me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
- DoCast(me, SPELL_EMERGE_0);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
- SetCombatMovement(true);
- me->GetMotionMaster()->MoveChase(me->getVictim());
- stage = 0;
- break;
+ events.ScheduleEvent(EVENT_SWEEP, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ return;
+ default:
+ return;
+ }
}
+ if (events.GetPhaseMask() & PHASE_MASK_MOBILE)
+ DoMeleeAttackIfReady();
+ if (events.GetPhaseMask() & PHASE_MASK_STATIONARY)
+ DoSpellAttackIfReady(SpitSpell);
}
- InstanceScript* instanceScript;
+ void Submerge()
+ {
+ DoCast(me, SPELL_SUBMERGE_0);
+ me->RemoveAurasDueToSpell(SPELL_EMERGE_0);
+ me->SetInCombatWithZone();
+ events.SetPhase(PHASE_SUBMERGED);
+ events.ScheduleEvent(EVENT_EMERGE, 5*IN_MILLISECONDS, 0, PHASE_SUBMERGED);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX()+ frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionY() + frand(-40.0f, 40.0f), ToCCommonLoc[1].GetPositionZ());
+ WasMobile = !WasMobile;
+ }
- uint32 otherWormEntry;
+ void Emerge()
+ {
+ DoCast(me, SPELL_EMERGE_0);
+ me->SetDisplayId(ModelMobile);
+ me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->GetMotionMaster()->Clear();
+
+ // if the worm was mobile before submerging, make him stationary now
+ if (WasMobile)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ SetCombatMovement(false);
+ me->SetDisplayId(ModelStationary);
+ events.SetPhase(PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_SUBMERGE, 45*IN_MILLISECONDS, 0, PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_SPIT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_SPRAY, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ events.ScheduleEvent(EVENT_SWEEP, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_STATIONARY);
+ }
+ else
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ SetCombatMovement(true);
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ me->SetDisplayId(ModelMobile);
+ events.SetPhase(PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_SUBMERGE, 45*IN_MILLISECONDS, 0, PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_BITE, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_SPEW, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS), 0, PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_SLIME_POOL, 15*IN_MILLISECONDS, 0, PHASE_MOBILE);
+ }
+ }
- uint32 modelStationary;
- uint32 modelMobile;
+ protected:
+ uint32 OtherWormEntry;
+ uint32 ModelStationary;
+ uint32 ModelMobile;
- uint32 biteSpell;
- uint32 spewSpell;
- uint32 spitSpell;
- uint32 spraySpell;
+ uint32 BiteSpell;
+ uint32 SpewSpell;
+ uint32 SpitSpell;
+ uint32 SpraySpell;
- uint32 biteTimer;
- uint32 spewTimer;
- uint32 slimePoolTimer;
- uint32 spitTimer;
- uint32 sprayTimer;
- uint32 sweepTimer;
- uint32 submergeTimer;
- uint8 stage;
- bool enraged;
+ Phases Phase;
+ bool Enraged;
+ bool WasMobile;
};
class boss_acidmaw : public CreatureScript
{
public:
- boss_acidmaw() : CreatureScript("boss_acidmaw") { }
+ boss_acidmaw() : CreatureScript("boss_acidmaw") { }
- struct boss_acidmawAI : public boss_jormungarAI
- {
- boss_acidmawAI(Creature* creature) : boss_jormungarAI(creature) { }
+ struct boss_acidmawAI : public boss_jormungarAI
+ {
+ boss_acidmawAI(Creature* creature) : boss_jormungarAI(creature) { }
- void Reset()
+ void Reset()
+ {
+ boss_jormungarAI::Reset();
+ BiteSpell = SPELL_PARALYTIC_BITE;
+ SpewSpell = SPELL_ACID_SPEW;
+ SpitSpell = SPELL_ACID_SPIT;
+ SpraySpell = SPELL_PARALYTIC_SPRAY;
+ ModelStationary = MODEL_ACIDMAW_STATIONARY;
+ ModelMobile = MODEL_ACIDMAW_MOBILE;
+ OtherWormEntry = NPC_DREADSCALE;
+
+ WasMobile = true;
+ Emerge();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
{
- boss_jormungarAI::Reset();
- biteSpell = SPELL_PARALYTIC_BITE;
- spewSpell = SPELL_ACID_SPEW;
- spitSpell = SPELL_ACID_SPIT;
- spraySpell = SPELL_PARALYTIC_SPRAY;
- modelStationary = MODEL_ACIDMAW_STATIONARY;
- modelMobile = MODEL_ACIDMAW_MOBILE;
- otherWormEntry = NPC_DREADSCALE;
-
- submergeTimer = 500;
- DoCast(me, SPELL_SUBMERGE_0);
- stage = 2;
+ return new boss_acidmawAI(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_acidmawAI(creature);
- }
};
class boss_dreadscale : public CreatureScript
{
-public:
- boss_dreadscale() : CreatureScript("boss_dreadscale") { }
+ public:
+ boss_dreadscale() : CreatureScript("boss_dreadscale") { }
- struct boss_dreadscaleAI : public boss_jormungarAI
- {
- boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature)
+ struct boss_dreadscaleAI : public boss_jormungarAI
{
- instanceScript = creature->GetInstanceScript();
- }
+ boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature)
+ {
+ }
- InstanceScript* instanceScript;
+ void Reset()
+ {
+ boss_jormungarAI::Reset();
+ BiteSpell = SPELL_BURNING_BITE;
+ SpewSpell = SPELL_MOLTEN_SPEW;
+ SpitSpell = SPELL_FIRE_SPIT;
+ SpraySpell = SPELL_BURNING_SPRAY;
+ ModelStationary = MODEL_DREADSCALE_STATIONARY;
+ ModelMobile = MODEL_DREADSCALE_MOBILE;
+ OtherWormEntry = NPC_ACIDMAW;
+
+ events.SetPhase(PHASE_MOBILE);
+ events.ScheduleEvent(EVENT_SUMMON_ACIDMAW, 3*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SUBMERGE, 45*IN_MILLISECONDS, 0, PHASE_MOBILE);
+ WasMobile = false;
+ }
- void Reset()
- {
- boss_jormungarAI::Reset();
- biteSpell = SPELL_BURNING_BITE;
- spewSpell = SPELL_MOLTEN_SPEW;
- spitSpell = SPELL_FIRE_SPIT;
- spraySpell = SPELL_BURNING_SPRAY;
- modelStationary = MODEL_DREADSCALE_STATIONARY;
- modelMobile = MODEL_DREADSCALE_MOBILE;
- otherWormEntry = NPC_ACIDMAW;
-
- submergeTimer = 45 * IN_MILLISECONDS;
- stage = 0;
- }
+ void MovementInform(uint32 type, uint32 pointId)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
- void MovementInform(uint32 type, uint32 pointId)
- {
- if (type != POINT_MOTION_TYPE)
- return;
+ switch (pointId)
+ {
+ case 0:
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetInCombatWithZone();
+ break;
+ default:
+ break;
+ }
+ }
- switch (pointId)
+ void EnterEvadeMode()
{
- case 0:
- instanceScript->DoUseDoorOrButton(instanceScript->GetData64(GO_MAIN_GATE_DOOR));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetInCombatWithZone();
- if (Creature* otherWorm = Unit::GetCreature(*me, instanceScript->GetData64(otherWormEntry)))
- {
- otherWorm->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- otherWorm->SetReactState(REACT_AGGRESSIVE);
- otherWorm->SetVisible(true);
- otherWorm->SetInCombatWithZone();
- }
- break;
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ boss_jormungarAI::EnterEvadeMode();
}
- }
- void EnterEvadeMode()
- {
- instanceScript->DoUseDoorOrButton(instanceScript->GetData64(GO_MAIN_GATE_DOOR));
- boss_jormungarAI::EnterEvadeMode();
- }
+ void JustReachedHome()
+ {
+ if (instance)
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- void JustReachedHome()
- {
- if (instanceScript)
- instanceScript->DoUseDoorOrButton(instanceScript->GetData64(GO_MAIN_GATE_DOOR));
+ boss_jormungarAI::JustReachedHome();
+ }
+ };
- boss_jormungarAI::JustReachedHome();
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_dreadscaleAI(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_dreadscaleAI(creature);
- }
};
class mob_slime_pool : public CreatureScript
{
-public:
- mob_slime_pool() : CreatureScript("mob_slime_pool") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_slime_poolAI(creature);
- }
-
- struct mob_slime_poolAI : public ScriptedAI
- {
- mob_slime_poolAI(Creature* creature) : ScriptedAI(creature)
- {
- }
+ public:
+ mob_slime_pool() : CreatureScript("mob_slime_pool") { }
- bool casted;
- void Reset()
+ struct mob_slime_poolAI : public ScriptedAI
{
- casted = false;
- me->SetReactState(REACT_PASSIVE);
- }
+ mob_slime_poolAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- void UpdateAI(uint32 const /*diff*/)
- {
- if (!casted)
+ void Reset()
{
- casted = true;
- DoCast(me, SPELL_SLIME_POOL_EFFECT);
+ _cast = false;
+ me->SetReactState(REACT_PASSIVE);
}
- }
- };
-};
+ void UpdateAI(uint32 const /*diff*/)
+ {
+ if (!_cast)
+ {
+ _cast = true;
+ DoCast(me, SPELL_SLIME_POOL_EFFECT);
+ }
-class boss_icehowl : public CreatureScript
-{
-public:
- boss_icehowl() : CreatureScript("boss_icehowl") { }
+ if (_instance->GetData(TYPE_NORTHREND_BEASTS) != SNAKES_IN_PROGRESS && _instance->GetData(TYPE_NORTHREND_BEASTS) != SNAKES_SPECIAL)
+ me->DespawnOrUnsummon();
+ }
+ private:
+ InstanceScript* _instance;
+ bool _cast;
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_icehowlAI(creature);
- }
+ };
- struct boss_icehowlAI : public ScriptedAI
- {
- boss_icehowlAI(Creature* creature) : ScriptedAI(creature)
+ CreatureAI* GetAI(Creature* creature) const
{
- instance = creature->GetInstanceScript();
+ return new mob_slime_poolAI(creature);
}
+};
- InstanceScript* instance;
-
- uint32 m_uiFerociousButtTimer;
- uint32 m_uiArticBreathTimer;
- uint32 m_uiWhirlTimer;
- uint32 m_uiMassiveCrashTimer;
- uint32 m_uiTrampleTimer;
- float m_fTrampleTargetX, m_fTrampleTargetY, m_fTrampleTargetZ;
- uint64 m_uiTrampleTargetGUID;
- bool m_bMovementStarted;
- bool m_bMovementFinish;
- bool m_bTrampleCasted;
- uint8 m_uiStage;
- Unit* target;
-
- void Reset()
+class spell_gormok_fire_bomb : public SpellScriptLoader
+{
+ public:
+ spell_gormok_fire_bomb() : SpellScriptLoader("spell_gormok_fire_bomb") {}
+
+ class spell_gormok_fire_bomb_SpellScript : public SpellScript
{
- m_uiFerociousButtTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- m_uiArticBreathTimer = urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- m_uiWhirlTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- m_uiMassiveCrashTimer = 30*IN_MILLISECONDS;
- m_uiTrampleTimer = IN_MILLISECONDS;
- m_bMovementStarted = false;
- m_bMovementFinish = false;
- m_bTrampleCasted = false;
- m_uiTrampleTargetGUID = 0;
- m_fTrampleTargetX = 0;
- m_fTrampleTargetY = 0;
- m_fTrampleTargetZ = 0;
- m_uiStage = 0;
- }
+ PrepareSpellScript(spell_gormok_fire_bomb_SpellScript);
+
+ void TriggerFireBomb(SpellEffIndex /*effIndex*/)
+ {
+ if (const WorldLocation* pos = GetExplTargetDest())
+ {
+ if (Unit* caster = GetCaster())
+ caster->SummonCreature(NPC_FIRE_BOMB, pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30*IN_MILLISECONDS);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHit += SpellEffectFn(spell_gormok_fire_bomb_SpellScript::TriggerFireBomb, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE);
+ }
+ };
- void JustDied(Unit* /*killer*/)
+ SpellScript* GetSpellScript() const
{
- if (instance)
- instance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_DONE);
+ return new spell_gormok_fire_bomb_SpellScript();
}
+};
+
+class boss_icehowl : public CreatureScript
+{
+ public:
+ boss_icehowl() : CreatureScript("boss_icehowl") { }
- void MovementInform(uint32 type, uint32 pointId)
+ struct boss_icehowlAI : public BossAI
{
- if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
- return;
+ boss_icehowlAI(Creature* creature) : BossAI(creature, BOSS_BEASTS)
+ {
+ }
- switch (pointId)
+ void Reset()
{
- case 0:
- if (me->GetDistance2d(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY()) < 6.0f)
- {
- // Middle of the room
- m_uiStage = 1;
- }
- else
- {
- // Landed from Hop backwards (start trample)
- if (Unit::GetPlayer(*me, m_uiTrampleTargetGUID))
+ events.ScheduleEvent(EVENT_FEROCIOUS_BUTT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_ARCTIC_BREATH, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_WHIRL, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_MASSIVE_CRASH, 30*IN_MILLISECONDS);
+ _movementStarted = false;
+ _movementFinish = false;
+ _trampleCasted = false;
+ _trampleTargetGUID = 0;
+ _trampleTargetX = 0;
+ _trampleTargetY = 0;
+ _trampleTargetZ = 0;
+ _stage = 0;
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ _JustDied();
+ if (instance)
+ instance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_DONE);
+ }
+
+ void MovementInform(uint32 type, uint32 pointId)
+ {
+ if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
+ return;
+
+ switch (pointId)
+ {
+ case 0:
+ if (_stage != 0)
{
- m_uiStage = 4;
+ if (me->GetDistance2d(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY()) < 6.0f)
+ // Middle of the room
+ _stage = 1;
+ else
+ {
+ // Landed from Hop backwards (start trample)
+ if (Unit::GetPlayer(*me, _trampleTargetGUID))
+ _stage = 4;
+ else
+ _stage = 6;
+ }
}
- else
- m_uiStage = 6;
- }
- break;
- case 1: // Finish trample
- m_bMovementFinish = true;
- break;
- case 2:
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetInCombatWithZone();
- break;
+ break;
+ case 1: // Finish trample
+ _movementFinish = true;
+ break;
+ case 2:
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetInCombatWithZone();
+ break;
+ default:
+ break;
+ }
}
- }
- void EnterEvadeMode()
- {
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- ScriptedAI::EnterEvadeMode();
- }
-
- void JustReachedHome()
- {
- if (instance)
+ void EnterEvadeMode()
{
instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- instance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ ScriptedAI::EnterEvadeMode();
}
- me->DespawnOrUnsummon();
- }
- void KilledUnit(Unit* who)
- {
- if (who->GetTypeId() == TYPEID_PLAYER)
+ void JustReachedHome()
{
if (instance)
- instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
+ {
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ instance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
+ }
+ me->DespawnOrUnsummon();
}
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- if (instance)
- instance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_IN_PROGRESS);
- me->SetInCombatWithZone();
- }
- void SpellHitTarget(Unit* target, SpellInfo const* spell)
- {
- if (spell->Id == SPELL_TRAMPLE && target->GetTypeId() == TYPEID_PLAYER)
+ void KilledUnit(Unit* who)
{
- if (!m_bTrampleCasted)
+ if (who->GetTypeId() == TYPEID_PLAYER)
{
- DoCast(me, SPELL_FROTHING_RAGE, true);
- m_bTrampleCasted = true;
+ if (instance)
+ instance->SetData(DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE, 0);
}
}
- }
- void UpdateAI(uint32 const diff)
- {
- if (!UpdateVictim())
- return;
+ void EnterCombat(Unit* /*who*/)
+ {
+ _EnterCombat();
+ if (instance)
+ instance->SetData(TYPE_NORTHREND_BEASTS, ICEHOWL_IN_PROGRESS);
+ }
- switch (m_uiStage)
+ void SpellHitTarget(Unit* target, SpellInfo const* spell)
{
- case 0:
- if (m_uiFerociousButtTimer <= diff)
+ if (spell->Id == SPELL_TRAMPLE && target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (!_trampleCasted)
{
- DoCastVictim(SPELL_FEROCIOUS_BUTT);
- m_uiFerociousButtTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiFerociousButtTimer -= diff;
+ DoCast(me, SPELL_FROTHING_RAGE, true);
+ _trampleCasted = true;
+ }
+ }
+ }
- if (m_uiArticBreathTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ARCTIC_BREATH);
- m_uiArticBreathTimer = urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS);
- } else m_uiArticBreathTimer -= diff;
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
- if (m_uiWhirlTimer <= diff)
- {
- DoCastAOE(SPELL_WHIRL);
- m_uiWhirlTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
- } else m_uiWhirlTimer -= diff;
+ events.Update(diff);
- if (m_uiMassiveCrashTimer <= diff)
- {
- me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 10.0f, 20.0f); // 1: Middle of the room
- SetCombatMovement(false);
- me->AttackStop();
- m_uiStage = 7; //Invalid (Do nothing more than move)
- m_uiMassiveCrashTimer = 30*IN_MILLISECONDS;
- } else m_uiMassiveCrashTimer -= diff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- DoMeleeAttackIfReady();
- break;
- case 1:
- DoCastAOE(SPELL_MASSIVE_CRASH);
- me->StopMoving();
- me->AttackStop();
- m_uiStage = 2;
- break;
- case 2:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
+ switch (_stage)
+ {
+ case 0:
{
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FEROCIOUS_BUTT:
+ DoCastVictim(SPELL_FEROCIOUS_BUTT);
+ events.ScheduleEvent(EVENT_FEROCIOUS_BUTT, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_ARCTIC_BREATH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_ARCTIC_BREATH);
+ return;
+ case EVENT_WHIRL:
+ DoCastAOE(SPELL_WHIRL);
+ events.ScheduleEvent(EVENT_WHIRL, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
+ return;
+ case EVENT_MASSIVE_CRASH:
+ me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 20.0f, 20.0f); // 1: Middle of the room
+ SetCombatMovement(false);
+ me->AttackStop();
+ _stage = 7; //Invalid (Do nothing more than move)
+ return;
+ default:
+ break;
+ }
+ }
+ DoMeleeAttackIfReady();
+ break;
+ }
+ case 1:
+ DoCastAOE(SPELL_MASSIVE_CRASH);
me->StopMoving();
me->AttackStop();
- m_uiTrampleTargetGUID = target->GetGUID();
- me->SetTarget(m_uiTrampleTargetGUID);
- m_bTrampleCasted = false;
- //SetCombatMovement(false);
- //me->GetMotionMaster()->MoveIdle();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_uiTrampleTimer = 4*IN_MILLISECONDS;
- m_uiStage = 3;
- } else m_uiStage = 6;
- break;
- case 3:
- me->StopMoving();
- me->AttackStop();
- if (m_uiTrampleTimer <= diff)
- {
- if (Unit* target = Unit::GetPlayer(*me, m_uiTrampleTargetGUID))
+ _stage = 2;
+ break;
+ case 2:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
- m_bTrampleCasted = false;
- m_bMovementStarted = true;
- m_fTrampleTargetX = target->GetPositionX();
- m_fTrampleTargetY = target->GetPositionY();
- m_fTrampleTargetZ = target->GetPositionZ();
- me->GetMotionMaster()->MoveJump(2*me->GetPositionX()-m_fTrampleTargetX,
- 2*me->GetPositionY()-m_fTrampleTargetY,
- me->GetPositionZ(),
- 20.0f, 30.0f); // 2: Hop Backwards
- m_uiStage = 7; //Invalid (Do nothing more than move)
- } else m_uiStage = 6;
- } else m_uiTrampleTimer -= diff;
- break;
- case 4:
- me->StopMoving();
- me->AttackStop();
- Talk(EMOTE_TRAMPLE_START, m_uiTrampleTargetGUID);
- me->GetMotionMaster()->MoveCharge(m_fTrampleTargetX, m_fTrampleTargetY, m_fTrampleTargetZ+2, 42, 1);
- me->SetTarget(0);
- m_uiStage = 5;
- break;
- case 5:
- if (m_bMovementFinish)
- {
- if (m_uiTrampleTimer <= diff) DoCastAOE(SPELL_TRAMPLE);
- m_bMovementFinish = false;
- m_uiStage = 6;
- return;
- }
- if (m_uiTrampleTimer <= diff)
- {
- Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ me->StopMoving();
+ me->AttackStop();
+ _trampleTargetGUID = target->GetGUID();
+ me->SetTarget(_trampleTargetGUID);
+ _trampleCasted = false;
+ SetCombatMovement(false);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveIdle();
+ events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS);
+ _stage = 3;
+ }
+ else
+ _stage = 6;
+ break;
+ case 3:
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (Unit* player = itr->getSource())
- if (player->isAlive() && player->IsWithinDistInMap(me, 6.0f))
+ switch (eventId)
+ {
+ case EVENT_TRAMPLE:
{
- DoCastAOE(SPELL_TRAMPLE);
- m_uiTrampleTimer = IN_MILLISECONDS;
+ if (Unit* target = Unit::GetPlayer(*me, _trampleTargetGUID))
+ {
+ me->StopMoving();
+ me->AttackStop();
+ _trampleCasted = false;
+ _movementStarted = true;
+ _trampleTargetX = target->GetPositionX();
+ _trampleTargetY = target->GetPositionY();
+ _trampleTargetZ = target->GetPositionZ();
+ // 2: Hop Backwards
+ me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), 30.0f, 20.0f);
+ _stage = 7; //Invalid (Do nothing more than move)
+ }
+ else
+ _stage = 6;
break;
}
+ default:
+ break;
+ }
}
- } else m_uiTrampleTimer -= diff;
- break;
- case 6:
- if (!m_bTrampleCasted)
- {
- DoCast(me, SPELL_STAGGERED_DAZE);
- Talk(EMOTE_TRAMPLE_CRASH);
- }
- else
- {
- DoCast(me, SPELL_FROTHING_RAGE, true);
- Talk(EMOTE_TRAMPLE_FAIL);
- }
- m_bMovementStarted = false;
- me->GetMotionMaster()->MovementExpired();
- me->GetMotionMaster()->MoveChase(me->getVictim());
- SetCombatMovement(true);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_uiStage = 0;
- break;
+ break;
+ case 4:
+ me->StopMoving();
+ me->AttackStop();
+ Talk(EMOTE_TRAMPLE_START, _trampleTargetGUID);
+ me->GetMotionMaster()->MoveCharge(_trampleTargetX, _trampleTargetY, _trampleTargetZ, 42, 1);
+ me->SetTarget(0);
+ _stage = 5;
+ break;
+ case 5:
+ if (_movementFinish)
+ {
+ DoCastAOE(SPELL_TRAMPLE);
+ _movementFinish = false;
+ _stage = 6;
+ return;
+ }
+ if (events.ExecuteEvent() == EVENT_TRAMPLE)
+ {
+ Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
+ {
+ if (Unit* player = itr->getSource())
+ {
+ if (player->isAlive() && player->IsWithinDistInMap(me, 6.0f))
+ {
+ DoCastAOE(SPELL_TRAMPLE);
+ events.ScheduleEvent(EVENT_TRAMPLE, 4*IN_MILLISECONDS);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case 6:
+ if (!_trampleCasted)
+ {
+ DoCast(me, SPELL_STAGGERED_DAZE);
+ Talk(EMOTE_TRAMPLE_CRASH);
+ }
+ else
+ {
+ DoCast(me, SPELL_FROTHING_RAGE, true);
+ Talk(EMOTE_TRAMPLE_FAIL);
+ }
+ _movementStarted = false;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
+ SetCombatMovement(true);
+ me->GetMotionMaster()->MovementExpired();
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ AttackStart(me->getVictim());
+ events.ScheduleEvent(EVENT_MASSIVE_CRASH, 40*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_ARCTIC_BREATH, urand(15*IN_MILLISECONDS, 25*IN_MILLISECONDS));
+ _stage = 0;
+ break;
+ default:
+ break;
+ }
}
- }
- };
+ private:
+ float _trampleTargetX, _trampleTargetY, _trampleTargetZ;
+ uint64 _trampleTargetGUID;
+ bool _movementStarted;
+ bool _movementFinish;
+ bool _trampleCasted;
+ uint8 _stage;
+ Unit* _target;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_icehowlAI(creature);
+ }
};
void AddSC_boss_northrend_beasts()
{
new boss_gormok();
new mob_snobold_vassal();
+ new npc_firebomb();
+ new spell_gormok_fire_bomb();
+
new boss_acidmaw();
new boss_dreadscale();
new mob_slime_pool();
+
new boss_icehowl();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
index a65eaebbc0c..4d99429bcb8 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
@@ -16,13 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: trial_of_the_crusader
-SD%Complete: ??%
-SDComment: based on /dev/rsa
-SDCategory: Crusader Coliseum
-EndScriptData */
-
// Known bugs:
// - They should be floating but they aren't respecting the floor =(
// - Hardcoded bullets spawner
@@ -48,13 +41,13 @@ enum Yells
SAY_TWINK_PACT = 5,
SAY_KILL_PLAYER = 6,
SAY_BERSERK = 7,
- SAY_DEATH = 8,
+ SAY_DEATH = 8
};
enum Equipment
{
EQUIP_MAIN_1 = 9423,
- EQUIP_MAIN_2 = 37377,
+ EQUIP_MAIN_2 = 37377
};
enum Summons
@@ -62,7 +55,7 @@ enum Summons
NPC_BULLET_CONTROLLER = 34743,
NPC_BULLET_DARK = 34628,
- NPC_BULLET_LIGHT = 34630,
+ NPC_BULLET_LIGHT = 34630
};
enum BossSpells
@@ -72,6 +65,7 @@ enum BossSpells
SPELL_LIGHT_SHIELD = 65858,
SPELL_LIGHT_TWIN_PACT = 65876,
SPELL_LIGHT_VORTEX = 66046,
+ SPELL_LIGHT_VORTEX_DAMAGE = 66048,
SPELL_LIGHT_TOUCH = 67297,
SPELL_LIGHT_ESSENCE = 65686,
SPELL_EMPOWERED_LIGHT = 65748,
@@ -83,17 +77,18 @@ enum BossSpells
SPELL_DARK_SHIELD = 65874,
SPELL_DARK_TWIN_PACT = 65875,
SPELL_DARK_VORTEX = 66058,
+ SPELL_DARK_VORTEX_DAMAGE = 66059,
SPELL_DARK_TOUCH = 67282,
SPELL_DARK_ESSENCE = 65684,
SPELL_EMPOWERED_DARK = 65724,
SPELL_TWIN_EMPATHY_DARK = 66132,
SPELL_UNLEASHED_DARK = 65808,
- SPELL_CONTROLLER_PERIODIC = 66149,
+ SPELL_CONTROLLER_PERIODIC = 66149,
SPELL_POWER_TWINS = 65879,
SPELL_BERSERK = 64238,
SPELL_POWERING_UP = 67590,
- SPELL_SURGE_OF_SPEED = 65828,
+ SPELL_SURGE_OF_SPEED = 65828
};
#define SPELL_DARK_ESSENCE_HELPER RAID_MODE<uint32>(65684, 67176, 67177, 67178)
@@ -106,13 +101,12 @@ enum BossSpells
enum Actions
{
- ACTION_VORTEX,
- ACTION_PACT
+ ACTION_VORTEX = 0,
+ ACTION_PACT = 1
};
-/*######
-## boss_twin_base
-######*/
+#define ESSENCE_REMOVE 0
+#define ESSENCE_APPLY 1
class OrbsDespawner : public BasicEvent
{
@@ -145,61 +139,36 @@ class OrbsDespawner : public BasicEvent
Creature* _creature;
};
-struct boss_twin_baseAI : public ScriptedAI
+struct boss_twin_baseAI : public BossAI
{
- boss_twin_baseAI(Creature* creature) : ScriptedAI(creature), Summons(me)
+ boss_twin_baseAI(Creature* creature) : BossAI(creature, BOSS_VALKIRIES)
{
- instance = creature->GetInstanceScript();
}
- InstanceScript* instance;
- SummonList Summons;
-
- AuraStateType m_uiAuraState;
-
- uint8 m_uiStage;
- bool m_bIsBerserk;
- uint32 m_uiWeapon;
- uint32 m_uiSpecialAbilityTimer;
- uint32 m_uiSpikeTimer;
- uint32 m_uiTouchTimer;
- uint32 m_uiBerserkTimer;
-
- int32 m_uiVortexEmote;
- uint32 m_uiSisterNpcId;
- uint32 m_uiMyEmphatySpellId;
- uint32 m_uiOtherEssenceSpellId;
- uint32 m_uiSurgeSpellId;
- uint32 m_uiVortexSpellId;
- uint32 m_uiShieldSpellId;
- uint32 m_uiTwinPactSpellId;
- uint32 m_uiSpikeSpellId;
- uint32 m_uiTouchSpellId;
-
void Reset()
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
- me->ModifyAuraState(m_uiAuraState, true);
- /* Uncomment this once that they are flying above the ground
+ me->ModifyAuraState(AuraState, true);
+ /* Uncomment this once that they are floating above the ground
me->SetLevitate(true);
me->SetFlying(true); */
- m_bIsBerserk = false;
+ IsBerserk = false;
- m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS;
- m_uiSpikeTimer = 20*IN_MILLISECONDS;
- m_uiTouchTimer = urand(10, 15)*IN_MILLISECONDS;
- m_uiBerserkTimer = IsHeroic() ? 6*MINUTE*IN_MILLISECONDS : 10*MINUTE*IN_MILLISECONDS;
+ SpecialAbilityTimer = 1*MINUTE*IN_MILLISECONDS;
+ SpikeTimer = 20*IN_MILLISECONDS;
+ TouchTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
+ BerserkTimer = IsHeroic() ? 6*MINUTE*IN_MILLISECONDS : 10*MINUTE*IN_MILLISECONDS;
- Summons.DespawnAll();
+ summons.DespawnAll();
}
void JustReachedHome()
{
if (instance)
- instance->SetData(TYPE_VALKIRIES, FAIL);
+ instance->SetBossState(BOSS_VALKIRIES, FAIL);
- Summons.DespawnAll();
+ summons.DespawnAll();
me->DespawnOrUnsummon();
}
@@ -211,10 +180,11 @@ struct boss_twin_baseAI : public ScriptedAI
switch (uiId)
{
case 1:
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_AGGRESSIVE);
break;
+ default:
+ break;
}
}
@@ -230,7 +200,7 @@ struct boss_twin_baseAI : public ScriptedAI
void JustSummoned(Creature* summoned)
{
- Summons.Summon(summoned);
+ summons.Summon(summoned);
}
void SummonedCreatureDespawn(Creature* summoned)
@@ -248,8 +218,10 @@ struct boss_twin_baseAI : public ScriptedAI
case NPC_BULLET_CONTROLLER:
me->m_Events.AddEvent(new OrbsDespawner(me), me->m_Events.CalculateTime(100));
break;
+ default:
+ break;
}
- Summons.Despawn(summoned);
+ summons.Despawn(summoned);
}
void JustDied(Unit* /*killer*/)
@@ -263,24 +235,22 @@ struct boss_twin_baseAI : public ScriptedAI
{
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
pSister->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-
- instance->SetData(TYPE_VALKIRIES, DONE);
- Summons.DespawnAll();
+ _JustDied();
}
else
{
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- instance->SetData(TYPE_VALKIRIES, SPECIAL);
+ instance->SetBossState(BOSS_VALKIRIES, SPECIAL);
}
}
}
- Summons.DespawnAll();
+ summons.DespawnAll();
}
// Called when sister pointer needed
Creature* GetSister()
{
- return Unit::GetCreature((*me), instance->GetData64(m_uiSisterNpcId));
+ return Unit::GetCreature((*me), instance->GetData64(SisterNpcId));
}
void EnterCombat(Unit* /*who*/)
@@ -290,14 +260,14 @@ struct boss_twin_baseAI : public ScriptedAI
{
if (Creature* pSister = GetSister())
{
- me->AddAura(m_uiMyEmphatySpellId, pSister);
+ me->AddAura(MyEmphatySpellId, pSister);
pSister->SetInCombatWithZone();
}
- instance->SetData(TYPE_VALKIRIES, IN_PROGRESS);
+ instance->SetBossState(BOSS_VALKIRIES, IN_PROGRESS);
}
Talk(SAY_AGGRO);
- DoCast(me, m_uiSurgeSpellId);
+ DoCast(me, SurgeSpellId);
}
void DoAction(const int32 action)
@@ -305,45 +275,50 @@ struct boss_twin_baseAI : public ScriptedAI
switch (action)
{
case ACTION_VORTEX:
- m_uiStage = me->GetEntry() == NPC_LIGHTBANE ? 2 : 1;
+ Stage = me->GetEntry() == NPC_LIGHTBANE ? 2 : 1;
break;
case ACTION_PACT:
- m_uiStage = me->GetEntry() == NPC_LIGHTBANE ? 1 : 2;
+ Stage = me->GetEntry() == NPC_LIGHTBANE ? 1 : 2;
+ break;
+ default:
break;
}
}
void EnableDualWield(bool mode = true)
{
- SetEquipmentSlots(false, m_uiWeapon, mode ? m_uiWeapon : int32(EQUIP_UNEQUIP), EQUIP_UNEQUIP);
+ SetEquipmentSlots(false, Weapon, mode ? Weapon : int32(EQUIP_UNEQUIP), EQUIP_UNEQUIP);
me->SetCanDualWield(mode);
me->UpdateDamagePhysical(mode ? OFF_ATTACK : BASE_ATTACK);
}
- void UpdateAI(const uint32 uiDiff)
+ void UpdateAI(const uint32 diff)
{
if (!instance || !UpdateVictim())
return;
- switch (m_uiStage)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ switch (Stage)
{
case 0:
break;
case 1: // Vortex
- if (m_uiSpecialAbilityTimer <= uiDiff)
+ if (SpecialAbilityTimer <= diff)
{
if (Creature* pSister = GetSister())
pSister->AI()->DoAction(ACTION_VORTEX);
- Talk(m_uiVortexEmote);
- DoCastAOE(m_uiVortexSpellId);
- m_uiStage = 0;
- m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS;
+ Talk(VortexEmote);
+ DoCastAOE(VortexSpellId);
+ Stage = 0;
+ SpecialAbilityTimer = 1*MINUTE*IN_MILLISECONDS;
}
else
- m_uiSpecialAbilityTimer -= uiDiff;
+ SpecialAbilityTimer -= diff;
break;
- case 2: // Shield+Pact
- if (m_uiSpecialAbilityTimer <= uiDiff)
+ case 2: // Shield + Pact
+ if (SpecialAbilityTimer <= diff)
{
Talk(EMOTE_TWINK_PACT);
Talk(SAY_TWINK_PACT);
@@ -352,164 +327,169 @@ struct boss_twin_baseAI : public ScriptedAI
pSister->AI()->DoAction(ACTION_PACT);
pSister->CastSpell(pSister, SPELL_POWER_TWINS, false);
}
- DoCast(me, m_uiShieldSpellId);
- DoCast(me, m_uiTwinPactSpellId);
- m_uiStage = 0;
- m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS;
+ DoCast(me, ShieldSpellId);
+ DoCast(me, TwinPactSpellId);
+ Stage = 0;
+ SpecialAbilityTimer = 1*MINUTE*IN_MILLISECONDS;
}
else
- m_uiSpecialAbilityTimer -= uiDiff;
+ SpecialAbilityTimer -= diff;
break;
default:
break;
}
- if (m_uiSpikeTimer <= uiDiff)
+ if (SpikeTimer <= diff)
{
- DoCastVictim(m_uiSpikeSpellId);
- m_uiSpikeTimer = 20*IN_MILLISECONDS;
+ DoCastVictim(SpikeSpellId);
+ SpikeTimer = 20*IN_MILLISECONDS;
}
else
- m_uiSpikeTimer -= uiDiff;
+ SpikeTimer -= diff;
- if (IsHeroic() && m_uiTouchTimer <= uiDiff)
+ if (IsHeroic() && TouchTimer <= diff)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true, m_uiOtherEssenceSpellId))
- me->CastCustomSpell(m_uiTouchSpellId, SPELLVALUE_MAX_TARGETS, 1, target, false);
- m_uiTouchTimer = urand(10, 15)*IN_MILLISECONDS;
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 200.0f, true, OtherEssenceSpellId))
+ me->CastCustomSpell(TouchSpellId, SPELLVALUE_MAX_TARGETS, 1, target, false);
+ TouchTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
}
else
- m_uiTouchTimer -= uiDiff;
+ TouchTimer -= diff;
- if (!m_bIsBerserk && m_uiBerserkTimer <= uiDiff)
+ if (!IsBerserk && BerserkTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
Talk(SAY_BERSERK);
- m_bIsBerserk = true;
+ IsBerserk = true;
}
else
- m_uiBerserkTimer -= uiDiff;
+ BerserkTimer -= diff;
DoMeleeAttackIfReady();
}
-};
-/*######
-## boss_fjola
-######*/
+ protected:
+ AuraStateType AuraState;
+
+ uint8 Stage;
+ bool IsBerserk;
+
+ uint32 Weapon;
+ uint32 SpecialAbilityTimer;
+ uint32 SpikeTimer;
+ uint32 TouchTimer;
+ uint32 BerserkTimer;
+
+ int32 VortexEmote;
+ uint32 SisterNpcId;
+ uint32 MyEmphatySpellId;
+ uint32 OtherEssenceSpellId;
+ uint32 SurgeSpellId;
+ uint32 VortexSpellId;
+ uint32 ShieldSpellId;
+ uint32 TwinPactSpellId;
+ uint32 SpikeSpellId;
+ uint32 TouchSpellId;
+};
class boss_fjola : public CreatureScript
{
-public:
- boss_fjola() : CreatureScript("boss_fjola") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_fjolaAI(creature);
- }
+ public:
+ boss_fjola() : CreatureScript("boss_fjola") { }
- struct boss_fjolaAI : public boss_twin_baseAI
- {
- boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature)
+ struct boss_fjolaAI : public boss_twin_baseAI
{
- instance = creature->GetInstanceScript();
- }
+ boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature)
+ {
+ }
- InstanceScript* instance;
-
- void Reset() {
- boss_twin_baseAI::Reset();
- SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
- m_uiStage = 0;
- m_uiWeapon = EQUIP_MAIN_1;
- m_uiAuraState = AURA_STATE_UNKNOWN22;
- m_uiVortexEmote = EMOTE_VORTEX;
- m_uiSisterNpcId = NPC_DARKBANE;
- m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_DARK;
- m_uiOtherEssenceSpellId = SPELL_DARK_ESSENCE_HELPER;
- m_uiSurgeSpellId = SPELL_LIGHT_SURGE;
- m_uiVortexSpellId = SPELL_LIGHT_VORTEX;
- m_uiShieldSpellId = SPELL_LIGHT_SHIELD;
- m_uiTwinPactSpellId = SPELL_LIGHT_TWIN_PACT;
- m_uiTouchSpellId = SPELL_LIGHT_TOUCH;
- m_uiSpikeSpellId = SPELL_LIGHT_TWIN_SPIKE;
+ void Reset()
+ {
+ SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
+ Stage = 0;
+ Weapon = EQUIP_MAIN_1;
+ AuraState = AURA_STATE_UNKNOWN22;
+ VortexEmote = EMOTE_VORTEX;
+ SisterNpcId = NPC_DARKBANE;
+ MyEmphatySpellId = SPELL_TWIN_EMPATHY_DARK;
+ OtherEssenceSpellId = SPELL_DARK_ESSENCE_HELPER;
+ SurgeSpellId = SPELL_LIGHT_SURGE;
+ VortexSpellId = SPELL_LIGHT_VORTEX;
+ ShieldSpellId = SPELL_LIGHT_SHIELD;
+ TwinPactSpellId = SPELL_LIGHT_TWIN_PACT;
+ TouchSpellId = SPELL_LIGHT_TOUCH;
+ SpikeSpellId = SPELL_LIGHT_TWIN_SPIKE;
+
+ if (instance)
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
+ boss_twin_baseAI::Reset();
+ }
- if (instance)
+ void EnterCombat(Unit* who)
{
- instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
+
+ me->SummonCreature(NPC_BULLET_CONTROLLER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN);
+ boss_twin_baseAI::EnterCombat(who);
}
- }
- void EnterCombat(Unit* who)
- {
- if (instance)
+ void EnterEvadeMode()
{
- instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT);
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ boss_twin_baseAI::EnterEvadeMode();
}
- me->SummonCreature(NPC_BULLET_CONTROLLER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN);
- boss_twin_baseAI::EnterCombat(who);
- }
+ void JustReachedHome()
+ {
+ if (instance)
+ instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- void EnterEvadeMode()
- {
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- boss_twin_baseAI::EnterEvadeMode();
- }
+ boss_twin_baseAI::JustReachedHome();
+ }
+ };
- void JustReachedHome()
+ CreatureAI* GetAI(Creature* creature) const
{
- if (instance)
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
-
- boss_twin_baseAI::JustReachedHome();
+ return new boss_fjolaAI(creature);
}
- };
-
};
-/*######
-## boss_eydis
-######*/
-
class boss_eydis : public CreatureScript
{
-public:
- boss_eydis() : CreatureScript("boss_eydis") { }
+ public:
+ boss_eydis() : CreatureScript("boss_eydis") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_eydisAI(creature);
- }
+ struct boss_eydisAI : public boss_twin_baseAI
+ {
+ boss_eydisAI(Creature* creature) : boss_twin_baseAI(creature) {}
- struct boss_eydisAI : public boss_twin_baseAI
- {
- boss_eydisAI(Creature* creature) : boss_twin_baseAI(creature) {}
-
- void Reset() {
- boss_twin_baseAI::Reset();
- SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
- m_uiStage = 1;
- m_uiWeapon = EQUIP_MAIN_2;
- m_uiAuraState = AURA_STATE_UNKNOWN19;
- m_uiVortexEmote = EMOTE_VORTEX;
- m_uiSisterNpcId = NPC_LIGHTBANE;
- m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_LIGHT;
- m_uiOtherEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER;
- m_uiSurgeSpellId = SPELL_DARK_SURGE;
- m_uiVortexSpellId = SPELL_DARK_VORTEX;
- m_uiShieldSpellId = SPELL_DARK_SHIELD;
- m_uiTwinPactSpellId = SPELL_DARK_TWIN_PACT;
- m_uiTouchSpellId = SPELL_DARK_TOUCH;
- m_uiSpikeSpellId = SPELL_DARK_TWIN_SPIKE;
- }
- };
+ void Reset()
+ {
+ SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
+ Stage = 1;
+ Weapon = EQUIP_MAIN_2;
+ AuraState = AURA_STATE_UNKNOWN19;
+ VortexEmote = EMOTE_VORTEX;
+ SisterNpcId = NPC_LIGHTBANE;
+ MyEmphatySpellId = SPELL_TWIN_EMPATHY_LIGHT;
+ OtherEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER;
+ SurgeSpellId = SPELL_DARK_SURGE;
+ VortexSpellId = SPELL_DARK_VORTEX;
+ ShieldSpellId = SPELL_DARK_SHIELD;
+ TwinPactSpellId = SPELL_DARK_TWIN_PACT;
+ TouchSpellId = SPELL_DARK_TOUCH;
+ SpikeSpellId = SPELL_DARK_TWIN_SPIKE;
+ boss_twin_baseAI::Reset();
+ }
+ };
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_eydisAI(creature);
+ }
};
-#define ESSENCE_REMOVE 0
-#define ESSENCE_APPLY 1
-
class mob_essence_of_twin : public CreatureScript
{
public:
@@ -525,10 +505,10 @@ class mob_essence_of_twin : public CreatureScript
switch (me->GetEntry())
{
case NPC_LIGHT_ESSENCE:
- spellReturned = data == ESSENCE_REMOVE? SPELL_DARK_ESSENCE_HELPER : SPELL_LIGHT_ESSENCE_HELPER;
+ spellReturned = (data == ESSENCE_REMOVE) ? SPELL_DARK_ESSENCE_HELPER : SPELL_LIGHT_ESSENCE_HELPER;
break;
case NPC_DARK_ESSENCE:
- spellReturned = data == ESSENCE_REMOVE? SPELL_LIGHT_ESSENCE_HELPER : SPELL_DARK_ESSENCE_HELPER;
+ spellReturned = (data == ESSENCE_REMOVE) ? SPELL_LIGHT_ESSENCE_HELPER : SPELL_DARK_ESSENCE_HELPER;
break;
default:
break;
@@ -556,12 +536,8 @@ struct mob_unleashed_ballAI : public ScriptedAI
{
mob_unleashed_ballAI(Creature* creature) : ScriptedAI(creature)
{
- instance = creature->GetInstanceScript();
}
- InstanceScript* instance;
- uint32 m_uiRangeCheckTimer;
-
void MoveToNextPoint()
{
float x0 = ToCCommonLoc[1].GetPositionX(), y0 = ToCCommonLoc[1].GetPositionY(), r = 47.0f;
@@ -578,13 +554,13 @@ struct mob_unleashed_ballAI : public ScriptedAI
void Reset()
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
me->SetDisableGravity(true);
me->SetCanFly(true);
SetCombatMovement(false);
MoveToNextPoint();
- m_uiRangeCheckTimer = IN_MILLISECONDS;
+ RangeCheckTimer = 0.5*IN_MILLISECONDS;
}
void MovementInform(uint32 uiType, uint32 uiId)
@@ -600,160 +576,112 @@ struct mob_unleashed_ballAI : public ScriptedAI
else
me->DisappearAndDie();
break;
+ default:
+ break;
}
}
+
+ protected:
+ uint32 RangeCheckTimer;
};
class mob_unleashed_dark : public CreatureScript
{
-public:
- mob_unleashed_dark() : CreatureScript("mob_unleashed_dark") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_unleashed_darkAI(creature);
- }
-
- struct mob_unleashed_darkAI : public mob_unleashed_ballAI
- {
- mob_unleashed_darkAI(Creature* creature) : mob_unleashed_ballAI(creature) {}
+ public:
+ mob_unleashed_dark() : CreatureScript("mob_unleashed_dark") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_unleashed_darkAI : public mob_unleashed_ballAI
{
- if (m_uiRangeCheckTimer < uiDiff)
+ mob_unleashed_darkAI(Creature* creature) : mob_unleashed_ballAI(creature) {}
+
+ void UpdateAI(const uint32 diff)
{
- if (me->SelectNearestPlayer(2.0f))
+ if (RangeCheckTimer < diff)
+ {
+ if (me->SelectNearestPlayer(3.0f))
{
- DoCastAOE(SPELL_UNLEASHED_DARK);
+ DoCastAOE(SPELL_UNLEASHED_DARK_HELPER);
me->GetMotionMaster()->MoveIdle();
- me->DespawnOrUnsummon(500);
+ me->DespawnOrUnsummon(1*IN_MILLISECONDS);
}
- m_uiRangeCheckTimer = IN_MILLISECONDS;
+ RangeCheckTimer = 0.5*IN_MILLISECONDS;
+ }
+ else
+ RangeCheckTimer -= diff;
}
- else m_uiRangeCheckTimer -= uiDiff;
- }
+ };
- void SpellHitTarget(Unit* who, SpellInfo const* spell)
+ CreatureAI* GetAI(Creature* creature) const
{
- if (spell->Id == SPELL_UNLEASHED_DARK_HELPER)
- {
- if (who->HasAura(SPELL_DARK_ESSENCE_HELPER))
- who->CastSpell(who, SPELL_POWERING_UP, true);
- }
+ return new mob_unleashed_darkAI(creature);
}
- };
-
};
class mob_unleashed_light : public CreatureScript
{
-public:
- mob_unleashed_light() : CreatureScript("mob_unleashed_light") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_unleashed_lightAI(creature);
- }
-
- struct mob_unleashed_lightAI : public mob_unleashed_ballAI
- {
- mob_unleashed_lightAI(Creature* creature) : mob_unleashed_ballAI(creature) {}
+ public:
+ mob_unleashed_light() : CreatureScript("mob_unleashed_light") { }
- void UpdateAI(const uint32 uiDiff)
+ struct mob_unleashed_lightAI : public mob_unleashed_ballAI
{
- if (m_uiRangeCheckTimer < uiDiff)
+ mob_unleashed_lightAI(Creature* creature) : mob_unleashed_ballAI(creature) {}
+
+ void UpdateAI(const uint32 diff)
{
- if (me->SelectNearestPlayer(2.0f))
+ if (RangeCheckTimer < diff)
+ {
+ if (me->SelectNearestPlayer(3.0f))
{
- DoCastAOE(SPELL_UNLEASHED_LIGHT);
+ DoCastAOE(SPELL_UNLEASHED_LIGHT_HELPER);
me->GetMotionMaster()->MoveIdle();
- me->DespawnOrUnsummon(500);
+ me->DespawnOrUnsummon(1*IN_MILLISECONDS);
}
- m_uiRangeCheckTimer = IN_MILLISECONDS;
+ RangeCheckTimer = 0.5*IN_MILLISECONDS;
+ }
+ else
+ RangeCheckTimer -= diff;
}
- else m_uiRangeCheckTimer -= uiDiff;
- }
+ };
- void SpellHitTarget(Unit* who, SpellInfo const* spell)
+ CreatureAI* GetAI(Creature* creature) const
{
- if (spell->Id == SPELL_UNLEASHED_LIGHT_HELPER)
- {
- if (who->HasAura(SPELL_LIGHT_ESSENCE_HELPER))
- who->CastSpell(who, SPELL_POWERING_UP, true);
- }
+ return new mob_unleashed_lightAI(creature);
}
- };
-
};
class mob_bullet_controller : public CreatureScript
{
-public:
- mob_bullet_controller() : CreatureScript("mob_bullet_controller") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_bullet_controllerAI(creature);
- }
-
- struct mob_bullet_controllerAI : public Scripted_NoMovementAI
- {
- mob_bullet_controllerAI(Creature* creature) : Scripted_NoMovementAI(creature)
- {
- Reset();
- }
-
- void Reset()
- {
- DoCastAOE(SPELL_CONTROLLER_PERIODIC);
- }
-
- void UpdateAI(const uint32 /*uiDiff*/)
- {
- UpdateVictim();
- }
- };
-};
-
-class spell_powering_up : public SpellScriptLoader
-{
public:
- spell_powering_up() : SpellScriptLoader("spell_powering_up") { }
+ mob_bullet_controller() : CreatureScript("mob_bullet_controller") { }
- class spell_powering_up_AuraScript : public AuraScript
+ struct mob_bullet_controllerAI : public Scripted_NoMovementAI
{
- PrepareAuraScript(spell_powering_up_AuraScript);
-
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ mob_bullet_controllerAI(Creature* creature) : Scripted_NoMovementAI(creature)
{
- if (Unit* target = GetTarget())
- {
- if (Aura* pAura = target->GetAura(GetId()))
- {
- if (pAura->GetStackAmount() == 100)
- {
- if (target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2206, EFFECT_1))
- target->CastSpell(target, SPELL_EMPOWERED_DARK, true);
-
- if (target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2845, EFFECT_1))
- target->CastSpell(target, SPELL_EMPOWERED_LIGHT, true);
+ Reset();
+ }
- target->RemoveAurasDueToSpell(GetId());
- }
- }
- }
+ void Reset()
+ {
+ DoCastAOE(SPELL_CONTROLLER_PERIODIC);
}
- void Register()
+ void UpdateAI(const uint32 /*diff*/)
{
- OnEffectApply += AuraEffectApplyFn(spell_powering_up_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ UpdateVictim();
}
};
- AuraScript* GetAuraScript() const
+ CreatureAI* GetAI(Creature* creature) const
{
- return new spell_powering_up_AuraScript();
+ return new mob_bullet_controllerAI(creature);
}
+};
+
+class spell_powering_up : public SpellScriptLoader
+{
+ public:
+ spell_powering_up() : SpellScriptLoader("spell_powering_up") { }
class spell_powering_up_SpellScript : public SpellScript
{
@@ -761,20 +689,39 @@ class spell_powering_up : public SpellScriptLoader
PrepareSpellScript(spell_powering_up_SpellScript)
uint32 spellId;
+ uint32 poweringUp;
bool Load()
{
spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_SURGE_OF_SPEED, GetCaster());
if (!sSpellMgr->GetSpellInfo(spellId))
return false;
+
+ poweringUp = sSpellMgr->GetSpellIdForDifficulty(SPELL_POWERING_UP, GetCaster());
+ if (!sSpellMgr->GetSpellInfo(poweringUp))
+ return false;
+
return true;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- if (Unit* target = GetExplTargetUnit())
- if (urand(0, 99) < 15)
- target->CastSpell(target, spellId, true);
+ if (Unit* target = GetHitUnit())
+ {
+ if (Aura* pAura = target->GetAura(poweringUp))
+ {
+ if (pAura->GetStackAmount() >= 100)
+ {
+ if (target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2206, EFFECT_1))
+ target->CastSpell(target, SPELL_EMPOWERED_DARK, true);
+
+ if (target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2845, EFFECT_1))
+ target->CastSpell(target, SPELL_EMPOWERED_LIGHT, true);
+
+ target->RemoveAurasDueToSpell(poweringUp);
+ }
+ }
+ }
}
void Register()
@@ -808,10 +755,68 @@ class spell_valkyr_essences : public SpellScriptLoader
return true;
}
- void Absorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & /*absorbAmount*/)
+ void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & /*absorbAmount*/)
{
- if (urand(0, 99) < 5)
- GetTarget()->CastSpell(GetTarget(), spellId, true);
+ if (Unit* owner = GetUnitOwner())
+ {
+ if (dmgInfo.GetSpellInfo())
+ {
+ if (uint32 poweringUp = sSpellMgr->GetSpellIdForDifficulty(SPELL_POWERING_UP, owner))
+ {
+ if (urand(0, 99) < 5)
+ GetTarget()->CastSpell(GetTarget(), spellId, true);
+
+ // Twin Vortex part
+ uint32 lightVortex = sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHT_VORTEX_DAMAGE, owner);
+ uint32 darkVortex = sSpellMgr->GetSpellIdForDifficulty(SPELL_DARK_VORTEX_DAMAGE, owner);
+ int32 stacksCount = int32(dmgInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue()) * 0.001 - 1;
+
+ if (lightVortex && darkVortex && stacksCount)
+ {
+ if (dmgInfo.GetSpellInfo()->Id == darkVortex || dmgInfo.GetSpellInfo()->Id == lightVortex)
+ {
+ Aura* pAura = owner->GetAura(poweringUp);
+ if (pAura)
+ {
+ pAura->ModStackAmount(stacksCount);
+ owner->CastSpell(owner, poweringUp, true);
+ }
+ else
+ {
+ owner->CastSpell(owner, poweringUp, true);
+ if (Aura* pTemp = owner->GetAura(poweringUp))
+ pTemp->ModStackAmount(stacksCount);
+ }
+ }
+ }
+
+ // Picking floating balls
+ uint32 unleashedDark = sSpellMgr->GetSpellIdForDifficulty(SPELL_UNLEASHED_DARK, owner);
+ uint32 unleashedLight = sSpellMgr->GetSpellIdForDifficulty(SPELL_UNLEASHED_LIGHT, owner);
+
+ if (unleashedDark && unleashedLight)
+ {
+ if (dmgInfo.GetSpellInfo()->Id == unleashedDark || dmgInfo.GetSpellInfo()->Id == unleashedLight)
+ {
+ // need to do the things in this order, else players might have 100 charges of Powering Up without anything happening
+ Aura* pAura = owner->GetAura(poweringUp);
+ if (pAura)
+ {
+ // 2 lines together add the correct amount of buff stacks
+ pAura->ModStackAmount(stacksCount);
+ owner->CastSpell(owner, poweringUp, true);
+ }
+ else
+ {
+ owner->CastSpell(owner, poweringUp, true);
+ if (Aura* pTemp = owner->GetAura(poweringUp))
+ pTemp->ModStackAmount(stacksCount);
+ }
+ }
+ }
+ }
+ }
+ }
}
void Register()
@@ -880,6 +885,7 @@ void AddSC_boss_twin_valkyr()
new mob_unleashed_dark();
new mob_essence_of_twin();
new mob_bullet_controller();
+
new spell_powering_up();
new spell_valkyr_essences();
new spell_power_of_the_twins();
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 98c1cf24f2b..7b0cd31bc67 100755
--- 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
@@ -16,13 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: instance_trial_of_the_crusader
-SD%Complete: 80%
-SDComment: by /dev/rsa
-SDCategory: Trial of the Crusader
-EndScriptData */
-
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "trial_of_the_crusader.h"
@@ -37,82 +30,55 @@ class instance_trial_of_the_crusader : public InstanceMapScript
{
instance_trial_of_the_crusader_InstanceMapScript(Map* map) : InstanceScript(map) {}
- uint32 EncounterStatus[MAX_ENCOUNTERS];
- uint32 TrialCounter;
- uint32 EventStage;
- uint32 EventTimer;
- uint32 EventNPCId;
- uint32 NorthrendBeasts;
- std::string SaveDataBuffer;
- bool NeedSave;
-
- uint64 BarrentGUID;
- uint64 TirionGUID;
- uint64 TirionFordringGUID;
- uint64 FizzlebangGUID;
- uint64 GarroshGUID;
- uint64 VarianGUID;
-
- uint64 GormokGUID;
- uint64 AcidmawGUID;
- uint64 DreadscaleGUID;
- uint64 IcehowlGUID;
- uint64 JaraxxusGUID;
- uint64 ChampionsControllerGUID;
- uint64 DarkbaneGUID;
- uint64 LightbaneGUID;
- uint64 AnubarakGUID;
-
- uint64 CrusadersCacheGUID;
- uint64 FloorGUID;
-
- uint64 TributeChestGUID;
-
- uint64 MainGateDoorGUID;
- uint64 EastPortcullisGUID;
- uint64 WebDoorGUID;
-
- // Achievement stuff
- uint32 NotOneButTwoJormungarsTimer;
- uint32 ResilienceWillFixItTimer;
- uint8 SnoboldCount;
- uint8 MistressOfPainCount;
- bool TributeToImmortalityElegible;
-
void Initialize()
{
- for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
- EncounterStatus[i] = NOT_STARTED;
-
+ SetBossNumber(MAX_ENCOUNTERS);
TrialCounter = 50;
EventStage = 0;
-
- TirionFordringGUID = 0;
-
- TributeChestGUID = 0;
-
- MainGateDoorGUID = 0;
- EastPortcullisGUID = 0;
- WebDoorGUID = 0;
-
NorthrendBeasts = NOT_STARTED;
-
EventTimer = 1000;
-
NotOneButTwoJormungarsTimer = 0;
ResilienceWillFixItTimer = 0;
SnoboldCount = 0;
MistressOfPainCount = 0;
TributeToImmortalityElegible = true;
-
NeedSave = false;
+ EventNPCId = 0;
+
+ TirionFordringGUID = 0;
+ BarrentGUID = 0;
+ TirionGUID = 0;
+ FizzlebangGUID = 0;
+ GarroshGUID = 0;
+ VarianGUID = 0;
+ GormokGUID = 0;
+ AcidmawGUID = 0;
+ DreadscaleGUID = 0;
+ IcehowlGUID = 0;
+ JaraxxusGUID = 0;
+ ChampionsControllerGUID = 0;
+ DarkbaneGUID = 0;
+ LightbaneGUID = 0;
+ AnubarakGUID = 0;
+
+ TributeChestGUID = 0;
+ MainGateDoorGUID = 0;
+ EastPortcullisGUID = 0;
+ WebDoorGUID = 0;
+ CrusadersCacheGUID = 0;
+ FloorGUID = 0;
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
- if (EncounterStatus[i] == IN_PROGRESS)
+ if (GetBossState(i) == IN_PROGRESS)
return true;
+
+ // Special state is set at Faction Champions after first champ dead, encounter is still in combat
+ if (GetBossState(BOSS_CRUSADERS) == SPECIAL)
+ return true;
+
return false;
}
@@ -123,12 +89,26 @@ class instance_trial_of_the_crusader : public InstanceMapScript
player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 1);
player->SendUpdateWorldState(UPDATE_STATE_UI_COUNT, GetData(TYPE_COUNTER));
}
+ else
+ player->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 0);
+
+ // make sure Anub'arak isnt missing and floor is destroyed after a crash
+ if (GetBossState(BOSS_LICH_KING) == DONE && TrialCounter && GetBossState(BOSS_ANUBARAK) != DONE)
+ {
+ Creature* anubArak = Unit::GetCreature(*player, GetData64(NPC_ANUBARAK));
+ if (!anubArak)
+ anubArak = player->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+
+ if (GameObject* floor = GameObject::GetGameObject(*player, GetData64(GO_ARGENT_COLISEUM_FLOOR)))
+ floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
+ }
}
void OpenDoor(uint64 guid)
{
if (!guid)
return;
+
if (GameObject* go = instance->GetGameObject(guid))
go->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
@@ -137,6 +117,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
{
if (!guid)
return;
+
if (GameObject* go = instance->GetGameObject(guid))
go->SetGoState(GO_STATE_READY);
}
@@ -147,6 +128,8 @@ class instance_trial_of_the_crusader : public InstanceMapScript
{
case NPC_BARRENT:
BarrentGUID = creature->GetGUID();
+ if (!TrialCounter)
+ creature->DespawnOrUnsummon();
break;
case NPC_TIRION:
TirionGUID = creature->GetGUID();
@@ -191,6 +174,8 @@ class instance_trial_of_the_crusader : public InstanceMapScript
case NPC_ANUBARAK:
AnubarakGUID = creature->GetGUID();
break;
+ default:
+ break;
}
}
@@ -237,34 +222,41 @@ class instance_trial_of_the_crusader : public InstanceMapScript
case GO_TRIBUTE_CHEST_25H_99:
TributeChestGUID = go->GetGUID();
break;
+ default:
+ break;
}
}
- void SetData(uint32 type, uint32 data)
+ bool SetBossState(uint32 type, EncounterState state)
{
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
switch (type)
{
- case TYPE_JARAXXUS:
+ case BOSS_BEASTS:
+ break;
+ case BOSS_JARAXXUS:
// Cleanup Icehowl
if (Creature* icehowl = instance->GetCreature(IcehowlGUID))
icehowl->DespawnOrUnsummon();
- if (data == DONE)
+ if (state == DONE)
EventStage = 2000;
break;
- case TYPE_CRUSADERS:
+ case BOSS_CRUSADERS:
// Cleanup Jaraxxus
if (Creature* jaraxxus = instance->GetCreature(JaraxxusGUID))
jaraxxus->DespawnOrUnsummon();
if (Creature* fizzlebang = instance->GetCreature(FizzlebangGUID))
fizzlebang->DespawnOrUnsummon();
- switch (data)
+ switch (state)
{
case IN_PROGRESS:
ResilienceWillFixItTimer = 0;
break;
case SPECIAL: //Means the first blood
ResilienceWillFixItTimer = 60*IN_MILLISECONDS;
- data = IN_PROGRESS;
+ state = IN_PROGRESS;
break;
case DONE:
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DEFEAT_FACTION_CHAMPIONS);
@@ -273,21 +265,23 @@ class instance_trial_of_the_crusader : public InstanceMapScript
DoRespawnGameObject(CrusadersCacheGUID, 7*DAY);
EventStage = 3100;
break;
+ default:
+ break;
}
break;
- case TYPE_VALKIRIES:
+ case BOSS_VALKIRIES:
// Cleanup chest
if (GameObject* cache = instance->GetGameObject(CrusadersCacheGUID))
cache->Delete();
- switch (data)
+ switch (state)
{
case FAIL:
- if (EncounterStatus[TYPE_VALKIRIES] == NOT_STARTED)
- data = NOT_STARTED;
+ if (GetBossState(BOSS_VALKIRIES) == NOT_STARTED)
+ state = NOT_STARTED;
break;
case SPECIAL:
- if (EncounterStatus[TYPE_VALKIRIES] == SPECIAL)
- data = DONE;
+ if (GetBossState(BOSS_VALKIRIES) == SPECIAL)
+ state = DONE;
break;
case DONE:
if (instance->GetPlayers().getFirst()->getSource()->GetTeam() == ALLIANCE)
@@ -295,50 +289,122 @@ class instance_trial_of_the_crusader : public InstanceMapScript
else
EventStage = 4030;
break;
+ default:
+ break;
}
break;
- case TYPE_ANUBARAK:
- switch (data)
+ case BOSS_LICH_KING:
+ break;
+ case BOSS_ANUBARAK:
+ switch (state)
{
case DONE:
+ {
EventStage = 6000;
- break;
- case SPECIAL:
uint32 tributeChest = 0;
if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
{
if (TrialCounter >= 50)
tributeChest = GO_TRIBUTE_CHEST_10H_99;
else
+ {
if (TrialCounter >= 45)
tributeChest = GO_TRIBUTE_CHEST_10H_50;
else
+ {
if (TrialCounter >= 25)
tributeChest = GO_TRIBUTE_CHEST_10H_45;
else
tributeChest = GO_TRIBUTE_CHEST_10H_25;
+ }
+ }
}
else if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
{
if (TrialCounter >= 50)
tributeChest = GO_TRIBUTE_CHEST_25H_99;
else
+ {
if (TrialCounter >= 45)
tributeChest = GO_TRIBUTE_CHEST_25H_50;
else
+ {
if (TrialCounter >= 25)
tributeChest = GO_TRIBUTE_CHEST_25H_45;
else
tributeChest = GO_TRIBUTE_CHEST_25H_25;
+ }
+ }
}
+
if (tributeChest)
if (Creature* tirion = instance->GetCreature(TirionGUID))
- // need proper location.this one is guessed based on videos
- if (GameObject* chest = tirion->SummonGameObject(tributeChest, 643.814f, 136.027f, 141.295f, 0, 0, 0, 0, 0, 90000000))
+ if (GameObject* chest = tirion->SummonGameObject(tributeChest, 805.62f, 134.87f, 142.16f, 3.27f, 0, 0, 0, 0, WEEK))
chest->SetRespawnTime(chest->GetRespawnDelay());
break;
+ }
+ default:
+ break;
}
break;
+ default:
+ break;
+ }
+
+ if (IsEncounterInProgress())
+ {
+ CloseDoor(GetData64(GO_EAST_PORTCULLIS));
+ CloseDoor(GetData64(GO_WEB_DOOR));
+ }
+ else
+ {
+ OpenDoor(GetData64(GO_EAST_PORTCULLIS));
+ OpenDoor(GetData64(GO_WEB_DOOR));
+ }
+
+ if (type < MAX_ENCOUNTERS)
+ {
+ sLog->outInfo(LOG_FILTER_TSCR, "[ToCr] BossState(type %u) %u = state %u;", type, GetBossState(type), state);
+ if (state == FAIL)
+ {
+ if (instance->IsHeroic())
+ {
+ --TrialCounter;
+ // decrease attempt counter at wipe
+ Map::PlayerList const &PlayerList = instance->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
+ if (Player* player = itr->getSource())
+ player->SendUpdateWorldState(UPDATE_STATE_UI_COUNT, TrialCounter);
+
+ // if theres no more attemps allowed
+ if (!TrialCounter)
+ {
+ if (Unit* announcer = instance->GetCreature(GetData64(NPC_BARRENT)))
+ announcer->ToCreature()->DespawnOrUnsummon();
+
+ if (Creature* anubArak = instance->GetCreature(GetData64(NPC_ANUBARAK)))
+ anubArak->DespawnOrUnsummon();
+ }
+ }
+ NeedSave = true;
+ EventStage = (type == BOSS_BEASTS ? 666 : 0);
+ state = NOT_STARTED;
+ }
+
+ if (state == DONE || NeedSave)
+ {
+ if (Unit* announcer = instance->GetCreature(GetData64(NPC_BARRENT)))
+ announcer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ Save();
+ }
+ }
+ return true;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch (type)
+ {
case TYPE_COUNTER:
TrialCounter = data;
data = DONE;
@@ -358,7 +424,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript
case GORMOK_DONE:
EventStage = 200;
SetData(TYPE_NORTHREND_BEASTS, IN_PROGRESS);
- SetData(TYPE_BEASTS, IN_PROGRESS);
break;
case SNAKES_IN_PROGRESS:
NotOneButTwoJormungarsTimer = 0;
@@ -371,15 +436,16 @@ class instance_trial_of_the_crusader : public InstanceMapScript
DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_WORMS_KILLED_IN_10_SECONDS);
EventStage = 300;
SetData(TYPE_NORTHREND_BEASTS, IN_PROGRESS);
- SetData(TYPE_BEASTS, IN_PROGRESS);
break;
case ICEHOWL_DONE:
EventStage = 400;
SetData(TYPE_NORTHREND_BEASTS, DONE);
- SetData(TYPE_BEASTS, DONE);
+ SetBossState(BOSS_BEASTS, DONE);
break;
case FAIL:
- SetData(TYPE_BEASTS, FAIL);
+ SetBossState(BOSS_BEASTS, FAIL);
+ break;
+ default:
break;
}
break;
@@ -399,37 +465,8 @@ class instance_trial_of_the_crusader : public InstanceMapScript
case DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE:
TributeToImmortalityElegible = false;
break;
- }
- if (IsEncounterInProgress())
- {
- CloseDoor(GetData64(GO_EAST_PORTCULLIS));
- CloseDoor(GetData64(GO_WEB_DOOR));
- }
- else
- {
- OpenDoor(GetData64(GO_EAST_PORTCULLIS));
- OpenDoor(GetData64(GO_WEB_DOOR));
- }
-
- if (type < MAX_ENCOUNTERS)
- {
- sLog->outInfo(LOG_FILTER_TSCR, "[ToCr] EncounterStatus[type %u] %u = data %u;", type, EncounterStatus[type], data);
- if (data == FAIL)
- {
- --TrialCounter;
- NeedSave = true;
- EventStage = (type == TYPE_BEASTS ? 666 : 0);
- data = NOT_STARTED;
- }
-
- EncounterStatus[type] = data;
-
- if (data == DONE || NeedSave == true)
- {
- if (Unit* announcer = instance->GetCreature(GetData64(NPC_BARRENT)))
- announcer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- Save();
- }
+ default:
+ break;
}
}
@@ -488,18 +525,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript
{
switch (type)
{
- case TYPE_BEASTS:
- return EncounterStatus[TYPE_BEASTS];
- case TYPE_JARAXXUS:
- return EncounterStatus[TYPE_JARAXXUS];
- case TYPE_CRUSADERS:
- return EncounterStatus[TYPE_CRUSADERS];
- case TYPE_VALKIRIES:
- return EncounterStatus[TYPE_VALKIRIES];
- case TYPE_LICH_KING:
- return EncounterStatus[TYPE_LICH_KING];
- case TYPE_ANUBARAK:
- return EncounterStatus[TYPE_ANUBARAK];
case TYPE_COUNTER:
return TrialCounter;
case TYPE_EVENT:
@@ -613,7 +638,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
NotOneButTwoJormungarsTimer -= diff;
}
- if (GetData(TYPE_CRUSADERS) == IN_PROGRESS && ResilienceWillFixItTimer)
+ if (GetBossState(BOSS_CRUSADERS) == SPECIAL && ResilienceWillFixItTimer)
{
if (ResilienceWillFixItTimer <= diff)
ResilienceWillFixItTimer = 0;
@@ -629,7 +654,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
std::ostringstream saveStream;
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
- saveStream << EncounterStatus[i] << ' ';
+ saveStream << GetBossState(i) << ' ';
saveStream << TrialCounter;
SaveDataBuffer = saveStream.str();
@@ -658,10 +683,11 @@ class instance_trial_of_the_crusader : public InstanceMapScript
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
{
- loadStream >> EncounterStatus[i];
-
- if (EncounterStatus[i] == IN_PROGRESS)
- EncounterStatus[i] = NOT_STARTED;
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+ SetBossState(i, EncounterState(tmpState));
}
loadStream >> TrialCounter;
@@ -700,10 +726,52 @@ class instance_trial_of_the_crusader : public InstanceMapScript
return TrialCounter == 50 && TributeToImmortalityElegible;
case A_TRIBUTE_TO_DEDICATED_INSANITY:
return false/*uiGrandCrusaderAttemptsLeft == 50 && !bHasAtAnyStagePlayerEquippedTooGoodItem*/;
+ default:
+ break;
}
return false;
}
+
+ protected:
+ uint32 TrialCounter;
+ uint32 EventStage;
+ uint32 EventTimer;
+ uint32 EventNPCId;
+ uint32 NorthrendBeasts;
+ bool NeedSave;
+ std::string SaveDataBuffer;
+
+ uint64 BarrentGUID;
+ uint64 TirionGUID;
+ uint64 TirionFordringGUID;
+ uint64 FizzlebangGUID;
+ uint64 GarroshGUID;
+ uint64 VarianGUID;
+
+ uint64 GormokGUID;
+ uint64 AcidmawGUID;
+ uint64 DreadscaleGUID;
+ uint64 IcehowlGUID;
+ uint64 JaraxxusGUID;
+ uint64 ChampionsControllerGUID;
+ uint64 DarkbaneGUID;
+ uint64 LightbaneGUID;
+ uint64 AnubarakGUID;
+
+ uint64 CrusadersCacheGUID;
+ uint64 FloorGUID;
+ uint64 TributeChestGUID;
+ uint64 MainGateDoorGUID;
+ uint64 EastPortcullisGUID;
+ uint64 WebDoorGUID;
+
+ // Achievement stuff
+ uint32 NotOneButTwoJormungarsTimer;
+ uint32 ResilienceWillFixItTimer;
+ uint8 SnoboldCount;
+ uint8 MistressOfPainCount;
+ bool TributeToImmortalityElegible;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index 2494fec87a9..b4d35afa8fb 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -16,13 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Trial Of the crusader
-SD%Complete: ??%
-SDComment: event script based on /dev/rsa
-SDCategory: trial_of_the_crusader
-EndScriptData */
-
//Known Bugs:
// - Need better implementation of Gossip and correct gossip text and option
@@ -85,7 +78,7 @@ enum eYells
// Highlord Tirion Fordring - 36095
SAY_STAGE_4_06 = 0,
- SAY_STAGE_4_07 = 1,
+ SAY_STAGE_4_07 = 1
};
struct _Messages
@@ -98,23 +91,22 @@ struct _Messages
static _Messages _GossipMessage[]=
{
- {MSG_BEASTS, GOSSIP_ACTION_INFO_DEF+1, false, TYPE_BEASTS},
- {MSG_JARAXXUS, GOSSIP_ACTION_INFO_DEF+2, false, TYPE_JARAXXUS},
- {MSG_CRUSADERS, GOSSIP_ACTION_INFO_DEF+3, false, TYPE_CRUSADERS},
- {MSG_VALKIRIES, GOSSIP_ACTION_INFO_DEF+4, false, TYPE_VALKIRIES},
- {MSG_LICH_KING, GOSSIP_ACTION_INFO_DEF+5, false, TYPE_ANUBARAK},
- {MSG_ANUBARAK, GOSSIP_ACTION_INFO_DEF+6, true, TYPE_ANUBARAK}
+ {MSG_BEASTS, GOSSIP_ACTION_INFO_DEF + 1, false, BOSS_BEASTS},
+ {MSG_JARAXXUS, GOSSIP_ACTION_INFO_DEF + 2, false, BOSS_JARAXXUS},
+ {MSG_CRUSADERS, GOSSIP_ACTION_INFO_DEF + 3, false, BOSS_CRUSADERS},
+ {MSG_VALKIRIES, GOSSIP_ACTION_INFO_DEF + 4, false, BOSS_VALKIRIES},
+ {MSG_LICH_KING, GOSSIP_ACTION_INFO_DEF + 5, false, BOSS_ANUBARAK},
+ {MSG_ANUBARAK, GOSSIP_ACTION_INFO_DEF + 6, true, BOSS_ANUBARAK}
};
enum
{
- NUM_MESSAGES = 6,
+ NUM_MESSAGES = 6
};
class npc_announcer_toc10 : public CreatureScript
{
public:
-
npc_announcer_toc10() : CreatureScript("npc_announcer_toc10") { }
struct npc_announcer_toc10AI : public ScriptedAI
@@ -137,20 +129,20 @@ class npc_announcer_toc10 : public CreatureScript
bool OnGossipHello(Player* player, Creature* creature)
{
- InstanceScript* instanceScript = creature->GetInstanceScript();
- if (!instanceScript)
+ InstanceScript* instance = creature->GetInstanceScript();
+ if (!instance)
return true;
char const* _message = "We are ready!";
- if (player->isInCombat() || instanceScript->IsEncounterInProgress() || instanceScript->GetData(TYPE_EVENT))
+ if (player->isInCombat() || instance->IsEncounterInProgress() || instance->GetData(TYPE_EVENT))
return true;
uint8 i = 0;
for (; i < NUM_MESSAGES; ++i)
{
- if ((!_GossipMessage[i].state && instanceScript->GetData(_GossipMessage[i].encounter) != DONE)
- || (_GossipMessage[i].state && instanceScript->GetData(_GossipMessage[i].encounter) == DONE))
+ if ((!_GossipMessage[i].state && instance->GetBossState(_GossipMessage[i].encounter) != DONE)
+ || (_GossipMessage[i].state && instance->GetBossState(_GossipMessage[i].encounter) == DONE))
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, _message, GOSSIP_SENDER_MAIN, _GossipMessage[i].id);
break;
@@ -161,75 +153,65 @@ class npc_announcer_toc10 : public CreatureScript
return true;
}
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 /*action*/)
{
player->PlayerTalkClass->ClearMenus();
player->CLOSE_GOSSIP_MENU();
- InstanceScript* instanceScript = creature->GetInstanceScript();
- if (!instanceScript)
+ InstanceScript* instance = creature->GetInstanceScript();
+ if (!instance)
return true;
- switch (action)
+ if (instance->GetBossState(BOSS_BEASTS) != DONE)
{
- case GOSSIP_ACTION_INFO_DEF+1:
- if (instanceScript->GetData(TYPE_BEASTS) != DONE)
- {
- instanceScript->SetData(TYPE_EVENT, 110);
- instanceScript->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED);
- instanceScript->SetData(TYPE_BEASTS, NOT_STARTED);
- }
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- if (Creature* jaraxxus = Unit::GetCreature(*player, instanceScript->GetData64(NPC_JARAXXUS)))
- {
- jaraxxus->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
- jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- jaraxxus->SetReactState(REACT_AGGRESSIVE);
- jaraxxus->SetInCombatWithZone();
- }
- else if (instanceScript->GetData(TYPE_JARAXXUS) != DONE)
- {
- instanceScript->SetData(TYPE_EVENT, 1010);
- instanceScript->SetData(TYPE_JARAXXUS, NOT_STARTED);
- }
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- if (instanceScript->GetData(TYPE_CRUSADERS) != DONE)
- {
- if (player->GetTeam() == ALLIANCE)
- instanceScript->SetData(TYPE_EVENT, 3000);
- else
- instanceScript->SetData(TYPE_EVENT, 3001);
- instanceScript->SetData(TYPE_CRUSADERS, NOT_STARTED);
- }
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- if (instanceScript->GetData(TYPE_VALKIRIES) != DONE)
- {
- instanceScript->SetData(TYPE_EVENT, 4000);
- instanceScript->SetData(TYPE_VALKIRIES, NOT_STARTED);
- }
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
+ instance->SetData(TYPE_EVENT, 110);
+ instance->SetData(TYPE_NORTHREND_BEASTS, NOT_STARTED);
+ instance->SetBossState(BOSS_BEASTS, NOT_STARTED);
+ }
+ else if (instance->GetBossState(BOSS_JARAXXUS) != DONE)
+ {
+ // if Jaraxxus is spawned, but the raid wiped
+ if (Creature* jaraxxus = Unit::GetCreature(*player, instance->GetData64(NPC_JARAXXUS)))
{
- if (instanceScript->GetData(TYPE_LICH_KING) != DONE && !player->isGameMaster())
- return true;
-
- if (GameObject* floor = GameObject::GetGameObject(*player, instanceScript->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
- floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
+ jaraxxus->RemoveAurasDueToSpell(SPELL_JARAXXUS_CHAINS);
+ jaraxxus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ jaraxxus->SetReactState(REACT_DEFENSIVE);
+ jaraxxus->SetInCombatWithZone();
+ }
+ else
+ {
+ instance->SetData(TYPE_EVENT, 1010);
+ instance->SetBossState(BOSS_JARAXXUS, NOT_STARTED);
+ }
+ }
+ else if (instance->GetBossState(BOSS_CRUSADERS) != DONE)
+ {
+ if (player->GetTeam() == ALLIANCE)
+ instance->SetData(TYPE_EVENT, 3000);
+ else
+ instance->SetData(TYPE_EVENT, 3001);
+ instance->SetBossState(BOSS_CRUSADERS, NOT_STARTED);
+ }
+ else if (instance->GetBossState(BOSS_VALKIRIES) != DONE)
+ {
+ instance->SetData(TYPE_EVENT, 4000);
+ instance->SetBossState(BOSS_VALKIRIES, NOT_STARTED);
+ }
+ else if (instance->GetBossState(BOSS_LICH_KING) != DONE)
+ {
+ if (GameObject* floor = GameObject::GetGameObject(*player, instance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
+ floor->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
- creature->CastSpell(creature, 69016, false);
+ creature->CastSpell(creature, SPELL_CORPSE_TELEPORT, false);
+ creature->CastSpell(creature, SPELL_DESTROY_FLOOR_KNOCKUP, false);
- Creature* anubArak = Unit::GetCreature(*creature, instanceScript->GetData64(NPC_ANUBARAK));
- if (!anubArak || !anubArak->isAlive())
- anubArak = creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+ Creature* anubArak = Unit::GetCreature(*creature, instance->GetData64(NPC_ANUBARAK));
+ if (!anubArak || !anubArak->isAlive())
+ anubArak = creature->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
- instanceScript->SetData(TYPE_ANUBARAK, NOT_STARTED);
+ instance->SetBossState(BOSS_ANUBARAK, NOT_STARTED);
- if (creature->IsVisible())
- creature->SetVisible(false);
- break;
- }
+ if (creature->IsVisible())
+ creature->SetVisible(false);
}
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
return true;
@@ -244,112 +226,130 @@ class npc_announcer_toc10 : public CreatureScript
class boss_lich_king_toc : public CreatureScript
{
public:
-
boss_lich_king_toc() : CreatureScript("boss_lich_king_toc") { }
struct boss_lich_king_tocAI : public ScriptedAI
{
boss_lich_king_tocAI(Creature* creature) : ScriptedAI(creature)
{
- instance = creature->GetInstanceScript();
+ _instance = creature->GetInstanceScript();
}
- InstanceScript* instance;
- uint32 m_uiUpdateTimer;
-
void Reset()
{
- m_uiUpdateTimer = 0;
+ _updateTimer = 0;
me->SetReactState(REACT_PASSIVE);
- if (Creature* summoned = me->SummonCreature(NPC_TRIGGER, ToCCommonLoc[2].GetPositionX(), ToCCommonLoc[2].GetPositionY(), ToCCommonLoc[2].GetPositionZ(), 5, TEMPSUMMON_TIMED_DESPAWN, 60000))
+ if (Creature* summoned = me->SummonCreature(NPC_TRIGGER, ToCCommonLoc[2].GetPositionX(), ToCCommonLoc[2].GetPositionY(), ToCCommonLoc[2].GetPositionZ(), 5, TEMPSUMMON_TIMED_DESPAWN, 1*MINUTE*IN_MILLISECONDS))
{
summoned->CastSpell(summoned, 51807, false);
- summoned->SetDisplayId(11686);
+ summoned->SetDisplayId(summoned->GetCreatureTemplate()->Modelid2);
}
- if (instance) instance->SetData(TYPE_LICH_KING, IN_PROGRESS);
+ if (_instance)
+ _instance->SetBossState(BOSS_LICH_KING, IN_PROGRESS);
me->SetWalk(true);
}
void MovementInform(uint32 uiType, uint32 uiId)
{
- if (uiType != POINT_MOTION_TYPE || !instance)
+ if (uiType != POINT_MOTION_TYPE || !_instance)
return;
+
switch (uiId)
{
case 0:
- instance->SetData(TYPE_EVENT, 5030);
+ _instance->SetData(TYPE_EVENT, 5030);
break;
case 1:
- instance->SetData(TYPE_EVENT, 5050);
+ _instance->SetData(TYPE_EVENT, 5050);
+ break;
+ default:
break;
}
}
void UpdateAI(const uint32 uiDiff)
{
- if (!instance)
+ if (!_instance)
return;
- if (instance->GetData(TYPE_EVENT_NPC) != NPC_LICH_KING_1)
+ if (_instance->GetData(TYPE_EVENT_NPC) != NPC_LICH_KING_1)
return;
- m_uiUpdateTimer = instance->GetData(TYPE_EVENT_TIMER);
- if (m_uiUpdateTimer <= uiDiff)
+ _updateTimer = _instance->GetData(TYPE_EVENT_TIMER);
+ if (_updateTimer <= uiDiff)
{
- switch (instance->GetData(TYPE_EVENT))
+ switch (_instance->GetData(TYPE_EVENT))
{
case 5010:
Talk(SAY_STAGE_4_02);
- m_uiUpdateTimer = 3000;
+ _updateTimer = 3*IN_MILLISECONDS;
me->GetMotionMaster()->MovePoint(0, LichKingLoc[0]);
- instance->SetData(TYPE_EVENT, 5020);
+ _instance->SetData(TYPE_EVENT, 5020);
break;
case 5030:
Talk(SAY_STAGE_4_04);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
- m_uiUpdateTimer = 10000;
- instance->SetData(TYPE_EVENT, 5040);
+ _updateTimer = 10*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5040);
break;
case 5040:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
me->GetMotionMaster()->MovePoint(1, LichKingLoc[1]);
- m_uiUpdateTimer = 1000;
- instance->SetData(TYPE_EVENT, 0);
+ _updateTimer = 1*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 5050:
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 5060);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5060);
break;
case 5060:
Talk(SAY_STAGE_4_05);
me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
- m_uiUpdateTimer = 2500;
- instance->SetData(TYPE_EVENT, 5070);
+ _updateTimer = 2.5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5070);
break;
case 5070:
me->CastSpell(me, 68198, false);
- m_uiUpdateTimer = 1500;
- instance->SetData(TYPE_EVENT, 5080);
+ _updateTimer = 1.5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5080);
break;
case 5080:
- if (GameObject* go = instance->instance->GetGameObject(instance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
- go->SetDestructibleState(GO_DESTRUCTIBLE_DAMAGED);
- me->CastSpell(me, 69016, false);
- instance->SetData(TYPE_LICH_KING, DONE);
- Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_ANUBARAK));
- if (!temp || !temp->isAlive())
- temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
-
- instance->SetData(TYPE_EVENT, 0);
+ if (GameObject* go = _instance->instance->GetGameObject(_instance->GetData64(GO_ARGENT_COLISEUM_FLOOR)))
+ {
+ go->SetDisplayId(DISPLAYID_DESTROYED_FLOOR);
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_NODESPAWN);
+ go->SetGoState(GO_STATE_ACTIVE);
+ }
+
+ me->CastSpell(me, SPELL_CORPSE_TELEPORT, false);
+ me->CastSpell(me, SPELL_DESTROY_FLOOR_KNOCKUP, false);
+
+ if (_instance)
+ {
+ _instance->SetBossState(BOSS_LICH_KING, DONE);
+ Creature* temp = Unit::GetCreature(*me, _instance->GetData64(NPC_ANUBARAK));
+ if (!temp || !temp->isAlive())
+ temp = me->SummonCreature(NPC_ANUBARAK, AnubarakLoc[0].GetPositionX(), AnubarakLoc[0].GetPositionY(), AnubarakLoc[0].GetPositionZ(), 3, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
+
+ _instance->SetData(TYPE_EVENT, 0);
+ }
me->DespawnOrUnsummon();
- m_uiUpdateTimer = 20000;
+ _updateTimer = 20*IN_MILLISECONDS;
+ break;
+ default:
break;
}
- } else m_uiUpdateTimer -= uiDiff;
+ }
+ else
+ _updateTimer -= uiDiff;
- instance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
+ _instance->SetData(TYPE_EVENT_TIMER, _updateTimer);
}
+
+ private:
+ InstanceScript* _instance;
+ uint32 _updateTimer;
};
CreatureAI* GetAI(Creature* creature) const
@@ -361,27 +361,20 @@ class boss_lich_king_toc : public CreatureScript
class npc_fizzlebang_toc : public CreatureScript
{
public:
-
npc_fizzlebang_toc() : CreatureScript("npc_fizzlebang_toc") { }
struct npc_fizzlebang_tocAI : public ScriptedAI
{
- npc_fizzlebang_tocAI(Creature* creature) : ScriptedAI(creature), Summons(me)
+ npc_fizzlebang_tocAI(Creature* creature) : ScriptedAI(creature), _summons(me)
{
- instance = me->GetInstanceScript();
+ _instance = me->GetInstanceScript();
}
- InstanceScript* instance;
- SummonList Summons;
- uint32 m_uiUpdateTimer;
- uint64 m_uiPortalGUID;
- uint64 m_uiTriggerGUID;
-
void JustDied(Unit* killer)
{
Talk(SAY_STAGE_1_06, killer->GetGUID());
- instance->SetData(TYPE_EVENT, 1180);
- if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_JARAXXUS)))
+ _instance->SetData(TYPE_EVENT, 1180);
+ if (Creature* temp = Unit::GetCreature(*me, _instance->GetData64(NPC_JARAXXUS)))
{
temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
temp->SetReactState(REACT_AGGRESSIVE);
@@ -392,7 +385,7 @@ class npc_fizzlebang_toc : public CreatureScript
void Reset()
{
me->SetWalk(true);
- m_uiPortalGUID = 0;
+ _portalGUID = 0;
me->GetMotionMaster()->MovePoint(1, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY()-60, ToCCommonLoc[10].GetPositionZ());
}
@@ -405,42 +398,44 @@ class npc_fizzlebang_toc : public CreatureScript
{
case 1:
me->SetWalk(false);
- if (instance)
+ if (_instance)
{
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- instance->SetData(TYPE_EVENT, 1120);
- instance->SetData(TYPE_EVENT_TIMER, 1000);
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
+ _instance->SetData(TYPE_EVENT, 1120);
+ _instance->SetData(TYPE_EVENT_TIMER, 1*IN_MILLISECONDS);
}
break;
+ default:
+ break;
}
}
void JustSummoned(Creature* summoned)
{
- Summons.Summon(summoned);
+ _summons.Summon(summoned);
}
void UpdateAI(const uint32 uiDiff)
{
- if (!instance)
+ if (!_instance)
return;
- if (instance->GetData(TYPE_EVENT_NPC) != NPC_FIZZLEBANG)
+ if (_instance->GetData(TYPE_EVENT_NPC) != NPC_FIZZLEBANG)
return;
- m_uiUpdateTimer = instance->GetData(TYPE_EVENT_TIMER);
- if (m_uiUpdateTimer <= uiDiff)
+ _updateTimer = _instance->GetData(TYPE_EVENT_TIMER);
+ if (_updateTimer <= uiDiff)
{
- switch (instance->GetData(TYPE_EVENT))
+ switch (_instance->GetData(TYPE_EVENT))
{
case 1110:
- instance->SetData(TYPE_EVENT, 1120);
- m_uiUpdateTimer = 4000;
+ _instance->SetData(TYPE_EVENT, 1120);
+ _updateTimer = 4*IN_MILLISECONDS;
break;
case 1120:
Talk(SAY_STAGE_1_02);
- instance->SetData(TYPE_EVENT, 1130);
- m_uiUpdateTimer = 12000;
+ _instance->SetData(TYPE_EVENT, 1130);
+ _updateTimer = 12*IN_MILLISECONDS;
break;
case 1130:
me->GetMotionMaster()->MovementExpired();
@@ -448,18 +443,18 @@ class npc_fizzlebang_toc : public CreatureScript
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELL_CAST_OMNI);
if (Unit* pTrigger = me->SummonCreature(NPC_TRIGGER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 4.69494f, TEMPSUMMON_MANUAL_DESPAWN))
{
- m_uiTriggerGUID = pTrigger->GetGUID();
+ _triggerGUID = pTrigger->GetGUID();
pTrigger->SetObjectScale(2.0f);
- pTrigger->SetDisplayId(22862);
+ pTrigger->SetDisplayId(pTrigger->ToCreature()->GetCreatureTemplate()->Modelid1);
pTrigger->CastSpell(pTrigger, SPELL_WILFRED_PORTAL, false);
}
- instance->SetData(TYPE_EVENT, 1132);
- m_uiUpdateTimer = 4000;
+ _instance->SetData(TYPE_EVENT, 1132);
+ _updateTimer = 4*IN_MILLISECONDS;
break;
case 1132:
me->GetMotionMaster()->MovementExpired();
- instance->SetData(TYPE_EVENT, 1134);
- m_uiUpdateTimer = 4000;
+ _instance->SetData(TYPE_EVENT, 1134);
+ _updateTimer = 4*IN_MILLISECONDS;
break;
case 1134:
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELL_CAST_OMNI);
@@ -468,14 +463,14 @@ class npc_fizzlebang_toc : public CreatureScript
pPortal->SetReactState(REACT_PASSIVE);
pPortal->SetObjectScale(2.0f);
pPortal->CastSpell(pPortal, SPELL_WILFRED_PORTAL, false);
- m_uiPortalGUID = pPortal->GetGUID();
+ _portalGUID = pPortal->GetGUID();
}
- m_uiUpdateTimer = 4000;
- instance->SetData(TYPE_EVENT, 1135);
+ _updateTimer = 4*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 1135);
break;
case 1135:
- instance->SetData(TYPE_EVENT, 1140);
- m_uiUpdateTimer = 3000;
+ _instance->SetData(TYPE_EVENT, 1140);
+ _updateTimer = 3*IN_MILLISECONDS;
break;
case 1140:
Talk(SAY_STAGE_1_04);
@@ -485,27 +480,27 @@ class npc_fizzlebang_toc : public CreatureScript
temp->SetReactState(REACT_PASSIVE);
temp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY()-10, ToCCommonLoc[1].GetPositionZ());
}
- instance->SetData(TYPE_EVENT, 1142);
- m_uiUpdateTimer = 5000;
+ _instance->SetData(TYPE_EVENT, 1142);
+ _updateTimer = 5*IN_MILLISECONDS;
break;
case 1142:
- if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_JARAXXUS)))
+ if (Creature* temp = Unit::GetCreature(*me, _instance->GetData64(NPC_JARAXXUS)))
temp->SetTarget(me->GetGUID());
- if (Creature* pTrigger = Unit::GetCreature(*me, m_uiTriggerGUID))
+ if (Creature* pTrigger = Unit::GetCreature(*me, _triggerGUID))
pTrigger->DespawnOrUnsummon();
- if (Creature* pPortal = Unit::GetCreature(*me, m_uiPortalGUID))
+ if (Creature* pPortal = Unit::GetCreature(*me, _portalGUID))
pPortal->DespawnOrUnsummon();
- instance->SetData(TYPE_EVENT, 1144);
- m_uiUpdateTimer = 10000;
+ _instance->SetData(TYPE_EVENT, 1144);
+ _updateTimer = 10*IN_MILLISECONDS;
break;
case 1144:
- if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_JARAXXUS)))
+ if (Creature* temp = Unit::GetCreature(*me, _instance->GetData64(NPC_JARAXXUS)))
temp->AI()->Talk(SAY_STAGE_1_05);
- instance->SetData(TYPE_EVENT, 1150);
- m_uiUpdateTimer = 5000;
+ _instance->SetData(TYPE_EVENT, 1150);
+ _updateTimer = 5*IN_MILLISECONDS;
break;
case 1150:
- if (Creature* temp = Unit::GetCreature(*me, instance->GetData64(NPC_JARAXXUS)))
+ if (Creature* temp = Unit::GetCreature(*me, _instance->GetData64(NPC_JARAXXUS)))
{
//1-shot Fizzlebang
temp->CastSpell(me, 67888, false);
@@ -513,13 +508,22 @@ class npc_fizzlebang_toc : public CreatureScript
temp->AddThreat(me, 1000.0f);
temp->AI()->AttackStart(me);
}
- instance->SetData(TYPE_EVENT, 1160);
- m_uiUpdateTimer = 3000;
+ _instance->SetData(TYPE_EVENT, 1160);
+ _updateTimer = 3*IN_MILLISECONDS;
break;
}
- } else m_uiUpdateTimer -= uiDiff;
- instance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
+ }
+ else
+ _updateTimer -= uiDiff;
+ _instance->SetData(TYPE_EVENT_TIMER, _updateTimer);
}
+
+ private:
+ InstanceScript* _instance;
+ SummonList _summons;
+ uint32 _updateTimer;
+ uint64 _portalGUID;
+ uint64 _triggerGUID;
};
CreatureAI* GetAI(Creature* creature) const
@@ -531,53 +535,49 @@ class npc_fizzlebang_toc : public CreatureScript
class npc_tirion_toc : public CreatureScript
{
public:
-
npc_tirion_toc() : CreatureScript("npc_tirion_toc") { }
struct npc_tirion_tocAI : public ScriptedAI
{
npc_tirion_tocAI(Creature* creature) : ScriptedAI(creature)
{
- instance = me->GetInstanceScript();
+ _instance = me->GetInstanceScript();
}
- InstanceScript* instance;
- uint32 m_uiUpdateTimer;
-
void Reset() {}
void AttackStart(Unit* /*who*/) {}
void UpdateAI(const uint32 uiDiff)
{
- if (!instance)
+ if (!_instance)
return;
- if (instance->GetData(TYPE_EVENT_NPC) != NPC_TIRION)
+ if (_instance->GetData(TYPE_EVENT_NPC) != NPC_TIRION)
return;
- m_uiUpdateTimer = instance->GetData(TYPE_EVENT_TIMER);
- if (m_uiUpdateTimer <= uiDiff)
+ _updateTimer = _instance->GetData(TYPE_EVENT_TIMER);
+ if (_updateTimer <= uiDiff)
{
- switch (instance->GetData(TYPE_EVENT))
+ switch (_instance->GetData(TYPE_EVENT))
{
case 110:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
Talk(SAY_STAGE_0_01);
- m_uiUpdateTimer = 22000;
- instance->SetData(TYPE_EVENT, 120);
+ _updateTimer = 22*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 120);
break;
case 140:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
Talk(SAY_STAGE_0_02);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 150);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 150);
break;
case 150:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
- if (instance->GetData(TYPE_BEASTS) != DONE)
+ if (_instance->GetBossState(BOSS_BEASTS) != DONE)
{
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
if (Creature* temp = me->SummonCreature(NPC_GORMOK, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS))
{
@@ -586,154 +586,133 @@ class npc_tirion_toc : public CreatureScript
temp->SetReactState(REACT_PASSIVE);
}
}
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 155);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 155);
break;
case 155:
- instance->SetData(TYPE_BEASTS, IN_PROGRESS);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 160);
+ // keep the raid in combat for the whole encounter, pauses included
+ me->SetInCombatWithZone();
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 160);
break;
case 200:
Talk(SAY_STAGE_0_04);
- m_uiUpdateTimer = 8000;
- instance->SetData(TYPE_EVENT, 205);
- break;
- case 205:
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 210);
- break;
- case 210:
- if (instance->GetData(TYPE_BEASTS) != DONE)
+ if (_instance->GetBossState(BOSS_BEASTS) != DONE)
{
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
if (Creature* temp = me->SummonCreature(NPC_DREADSCALE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN))
{
- temp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ());
- temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- temp->SetReactState(REACT_PASSIVE);
- }
- if (Creature* temp = me->SummonCreature(NPC_ACIDMAW, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN))
- {
- temp->SetVisible(true);
+ temp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
temp->SetReactState(REACT_PASSIVE);
}
}
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 220);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 220);
break;
case 220:
- instance->SetData(TYPE_EVENT, 230);
+ _instance->SetData(TYPE_EVENT, 230);
break;
case 300:
Talk(SAY_STAGE_0_05);
- m_uiUpdateTimer = 8000;
- instance->SetData(TYPE_EVENT, 305);
- break;
- case 305:
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 310);
- break;
- case 310:
- if (instance->GetData(TYPE_BEASTS) != DONE)
+ if (_instance->GetBossState(BOSS_BEASTS) != DONE)
{
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
if (Creature* temp = me->SummonCreature(NPC_ICEHOWL, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN))
{
temp->GetMotionMaster()->MovePoint(2, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ());
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
-
}
}
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 315);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 315);
break;
case 315:
- instance->SetData(TYPE_EVENT, 320);
+ _instance->SetData(TYPE_EVENT, 320);
break;
case 400:
Talk(SAY_STAGE_0_06);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 0);
+ me->getThreatManager().clearReferences();
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 666:
Talk(SAY_STAGE_0_WIPE);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 0);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 1010:
Talk(SAY_STAGE_1_01);
- m_uiUpdateTimer = 7000;
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
+ _updateTimer = 7*IN_MILLISECONDS;
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
me->SummonCreature(NPC_FIZZLEBANG, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME);
- instance->SetData(TYPE_EVENT, 0);
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 1180:
Talk(SAY_STAGE_1_07);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 0);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 2000:
Talk(SAY_STAGE_1_08);
- m_uiUpdateTimer = 18000;
- instance->SetData(TYPE_EVENT, 2010);
+ _updateTimer = 18*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 2010);
break;
case 2030:
Talk(SAY_STAGE_1_11);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 0);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 3000:
Talk(SAY_STAGE_2_01);
- m_uiUpdateTimer = 12000;
- instance->SetData(TYPE_EVENT, 3050);
+ _updateTimer = 12*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3050);
break;
case 3001:
Talk(SAY_STAGE_2_01);
- m_uiUpdateTimer = 12000;
- instance->SetData(TYPE_EVENT, 3051);
+ _updateTimer = 10*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3051);
break;
case 3060:
Talk(SAY_STAGE_2_03);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 3070);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3070);
break;
case 3061:
Talk(SAY_STAGE_2_03);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 3071);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3071);
break;
//Summoning crusaders
case 3091:
if (Creature* pChampionController = me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1]))
pChampionController->AI()->SetData(0, HORDE);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 3092);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3092);
break;
//Summoning crusaders
case 3090:
if (Creature* pChampionController = me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1]))
pChampionController->AI()->SetData(0, ALLIANCE);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 3092);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3092);
break;
case 3092:
- if (Creature* pChampionController = Unit::GetCreature((*me), instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
+ if (Creature* pChampionController = Unit::GetCreature((*me), _instance->GetData64(NPC_CHAMPIONS_CONTROLLER)))
pChampionController->AI()->SetData(1, NOT_STARTED);
- instance->SetData(TYPE_EVENT, 3095);
+ _instance->SetData(TYPE_EVENT, 3095);
break;
//Crusaders battle end
case 3100:
Talk(SAY_STAGE_2_06);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 0);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 4000:
Talk(SAY_STAGE_3_01);
- m_uiUpdateTimer = 13000;
- instance->SetData(TYPE_EVENT, 4010);
+ _updateTimer = 13*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 4010);
break;
case 4010:
Talk(SAY_STAGE_3_02);
@@ -751,78 +730,88 @@ class npc_tirion_toc : public CreatureScript
temp->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[2].GetPositionX(), TwinValkyrsLoc[2].GetPositionY(), TwinValkyrsLoc[2].GetPositionZ());
temp->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[3].GetPositionX(), TwinValkyrsLoc[3].GetPositionY(), TwinValkyrsLoc[3].GetPositionZ());
}
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 4015);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 4015);
break;
case 4015:
- instance->DoUseDoorOrButton(instance->GetData64(GO_MAIN_GATE_DOOR));
- if (Creature* temp = Unit::GetCreature((*me), instance->GetData64(NPC_LIGHTBANE)))
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
+ if (Creature* temp = Unit::GetCreature((*me), _instance->GetData64(NPC_LIGHTBANE)))
{
temp->GetMotionMaster()->MovePoint(1, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ());
temp->SetVisible(true);
}
- if (Creature* temp = Unit::GetCreature((*me), instance->GetData64(NPC_DARKBANE)))
+ if (Creature* temp = Unit::GetCreature((*me), _instance->GetData64(NPC_DARKBANE)))
{
temp->GetMotionMaster()->MovePoint(1, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ());
temp->SetVisible(true);
}
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 4016);
+ _updateTimer = 10*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 4016);
break;
case 4016:
- instance->SetData(TYPE_EVENT, 4017);
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
+ _instance->SetData(TYPE_EVENT, 4017);
break;
case 4040:
- m_uiUpdateTimer = 60000;
- instance->SetData(TYPE_EVENT, 5000);
+ _updateTimer = 1*MINUTE*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5000);
break;
case 5000:
Talk(SAY_STAGE_4_01);
- m_uiUpdateTimer = 10000;
- instance->SetData(TYPE_EVENT, 5005);
+ _updateTimer = 10*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5005);
break;
case 5005:
- m_uiUpdateTimer = 8000;
- instance->SetData(TYPE_EVENT, 5010);
+ _updateTimer = 8*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 5010);
me->SummonCreature(NPC_LICH_KING_1, ToCCommonLoc[2].GetPositionX(), ToCCommonLoc[2].GetPositionY(), ToCCommonLoc[2].GetPositionZ(), 5);
break;
case 5020:
Talk(SAY_STAGE_4_03);
- m_uiUpdateTimer = 1000;
- instance->SetData(TYPE_EVENT, 0);
+ _updateTimer = 1*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 0);
break;
case 6000:
me->SummonCreature(NPC_TIRION_FORDRING, EndSpawnLoc[0].GetPositionX(), EndSpawnLoc[0].GetPositionY(), EndSpawnLoc[0].GetPositionZ());
me->SummonCreature(NPC_ARGENT_MAGE, EndSpawnLoc[1].GetPositionX(), EndSpawnLoc[1].GetPositionY(), EndSpawnLoc[1].GetPositionZ());
me->SummonGameObject(GO_PORTAL_TO_DALARAN, EndSpawnLoc[2].GetPositionX(), EndSpawnLoc[2].GetPositionY(), EndSpawnLoc[2].GetPositionZ(), 5, 0, 0, 0, 0, 0);
- m_uiUpdateTimer = 20000;
- instance->SetData(TYPE_EVENT, 6005);
+ _updateTimer = 20*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 6005);
break;
case 6005:
- if (Creature* tirionFordring = Unit::GetCreature((*me), instance->GetData64(NPC_TIRION_FORDRING)))
+ if (Creature* tirionFordring = Unit::GetCreature((*me), _instance->GetData64(NPC_TIRION_FORDRING)))
tirionFordring->AI()->Talk(SAY_STAGE_4_06);
- m_uiUpdateTimer = 20000;
- instance->SetData(TYPE_EVENT, 6010);
+ _updateTimer = 20*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 6010);
break;
case 6010:
if (IsHeroic())
{
- if (Creature* tirionFordring = Unit::GetCreature((*me), instance->GetData64(NPC_TIRION_FORDRING)))
+ if (Creature* tirionFordring = Unit::GetCreature((*me), _instance->GetData64(NPC_TIRION_FORDRING)))
tirionFordring->AI()->Talk(SAY_STAGE_4_07);
- m_uiUpdateTimer = 60000;
- instance->SetData(TYPE_ANUBARAK, SPECIAL);
- instance->SetData(TYPE_EVENT, 6020);
- } else instance->SetData(TYPE_EVENT, 6030);
+ _updateTimer = 1*MINUTE*IN_MILLISECONDS;
+ _instance->SetBossState(BOSS_ANUBARAK, SPECIAL);
+ _instance->SetData(TYPE_EVENT, 6020);
+ }
+ else
+ _instance->SetData(TYPE_EVENT, 6030);
break;
case 6020:
me->DespawnOrUnsummon();
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 6030);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 6030);
+ break;
+ default:
break;
}
- } else m_uiUpdateTimer -= uiDiff;
- instance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
+ }
+ else
+ _updateTimer -= uiDiff;
+ _instance->SetData(TYPE_EVENT_TIMER, _updateTimer);
}
+ private:
+ InstanceScript* _instance;
+ uint32 _updateTimer;
};
CreatureAI* GetAI(Creature* creature) const
@@ -834,76 +823,79 @@ class npc_tirion_toc : public CreatureScript
class npc_garrosh_toc : public CreatureScript
{
public:
-
npc_garrosh_toc() : CreatureScript("npc_garrosh_toc") { }
struct npc_garrosh_tocAI : public ScriptedAI
{
npc_garrosh_tocAI(Creature* creature) : ScriptedAI(creature)
{
- instance = me->GetInstanceScript();
+ _instance = me->GetInstanceScript();
}
- InstanceScript* instance;
- uint32 m_uiUpdateTimer;
-
void Reset() {}
void AttackStart(Unit* /*who*/) {}
void UpdateAI(const uint32 uiDiff)
{
- if (!instance)
+ if (!_instance)
return;
- if (instance->GetData(TYPE_EVENT_NPC) != NPC_GARROSH)
+ if (_instance->GetData(TYPE_EVENT_NPC) != NPC_GARROSH)
return;
- m_uiUpdateTimer = instance->GetData(TYPE_EVENT_TIMER);
- if (m_uiUpdateTimer <= uiDiff)
+ _updateTimer = _instance->GetData(TYPE_EVENT_TIMER);
+ if (_updateTimer <= uiDiff)
{
- switch (instance->GetData(TYPE_EVENT))
+ switch (_instance->GetData(TYPE_EVENT))
{
case 130:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
Talk(SAY_STAGE_0_03h);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 132);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 132);
break;
case 132:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 140);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 140);
break;
case 2010:
Talk(SAY_STAGE_1_09);
- m_uiUpdateTimer = 9000;
- instance->SetData(TYPE_EVENT, 2020);
+ _updateTimer = 9*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 2020);
break;
case 3050:
Talk(SAY_STAGE_2_02h);
- m_uiUpdateTimer = 15000;
- instance->SetData(TYPE_EVENT, 3060);
+ _updateTimer = 15*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3060);
break;
case 3070:
Talk(SAY_STAGE_2_04h);
- m_uiUpdateTimer = 6000;
- instance->SetData(TYPE_EVENT, 3080);
+ _updateTimer = 6*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3080);
break;
case 3081:
Talk(SAY_STAGE_2_05h);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 3091);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3091);
break;
case 4030:
Talk(SAY_STAGE_3_03h);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 4040);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 4040);
+ break;
+ default:
break;
}
- } else m_uiUpdateTimer -= uiDiff;
- instance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
+ }
+ else
+ _updateTimer -= uiDiff;
+ _instance->SetData(TYPE_EVENT_TIMER, _updateTimer);
}
+ private:
+ InstanceScript* _instance;
+ uint32 _updateTimer;
};
CreatureAI* GetAI(Creature* creature) const
@@ -915,76 +907,79 @@ class npc_garrosh_toc : public CreatureScript
class npc_varian_toc : public CreatureScript
{
public:
-
npc_varian_toc() : CreatureScript("npc_varian_toc") { }
struct npc_varian_tocAI : public ScriptedAI
{
npc_varian_tocAI(Creature* creature) : ScriptedAI(creature)
{
- instance = me->GetInstanceScript();
+ _instance = me->GetInstanceScript();
}
- InstanceScript* instance;
- uint32 m_uiUpdateTimer;
-
void Reset() {}
void AttackStart(Unit* /*who*/) {}
void UpdateAI(const uint32 uiDiff)
{
- if (!instance)
+ if (!_instance)
return;
- if (instance->GetData(TYPE_EVENT_NPC) != NPC_VARIAN)
+ if (_instance->GetData(TYPE_EVENT_NPC) != NPC_VARIAN)
return;
- m_uiUpdateTimer = instance->GetData(TYPE_EVENT_TIMER);
- if (m_uiUpdateTimer <= uiDiff)
+ _updateTimer = _instance->GetData(TYPE_EVENT_TIMER);
+ if (_updateTimer <= uiDiff)
{
- switch (instance->GetData(TYPE_EVENT))
+ switch (_instance->GetData(TYPE_EVENT))
{
case 120:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_TALK);
Talk(SAY_STAGE_0_03a);
- m_uiUpdateTimer = 2000;
- instance->SetData(TYPE_EVENT, 122);
+ _updateTimer = 2*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 122);
break;
case 122:
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 130);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 130);
break;
case 2020:
Talk(SAY_STAGE_1_10);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 2030);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 2030);
break;
case 3051:
Talk(SAY_STAGE_2_02a);
- m_uiUpdateTimer = 10000;
- instance->SetData(TYPE_EVENT, 3061);
+ _updateTimer = 17*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3061);
break;
case 3071:
Talk(SAY_STAGE_2_04a);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 3081);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3081);
break;
case 3080:
Talk(SAY_STAGE_2_05a);
- m_uiUpdateTimer = 3000;
- instance->SetData(TYPE_EVENT, 3090);
+ _updateTimer = 3*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 3090);
break;
case 4020:
Talk(SAY_STAGE_3_03a);
- m_uiUpdateTimer = 5000;
- instance->SetData(TYPE_EVENT, 4040);
+ _updateTimer = 5*IN_MILLISECONDS;
+ _instance->SetData(TYPE_EVENT, 4040);
+ break;
+ default:
break;
}
- } else m_uiUpdateTimer -= uiDiff;
- instance->SetData(TYPE_EVENT_TIMER, m_uiUpdateTimer);
+ }
+ else
+ _updateTimer -= uiDiff;
+ _instance->SetData(TYPE_EVENT_TIMER, _updateTimer);
}
+ private:
+ InstanceScript* _instance;
+ uint32 _updateTimer;
};
CreatureAI* GetAI(Creature* creature) const
@@ -995,8 +990,8 @@ class npc_varian_toc : public CreatureScript
void AddSC_trial_of_the_crusader()
{
- new npc_announcer_toc10();
new boss_lich_king_toc();
+ new npc_announcer_toc10();
new npc_fizzlebang_toc();
new npc_tirion_toc();
new npc_garrosh_toc();
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
index 58cbd727963..fa38b6b46c1 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
@@ -7,12 +7,12 @@
enum
{
- TYPE_BEASTS = 0,
- TYPE_JARAXXUS = 1,
- TYPE_CRUSADERS = 2,
- TYPE_VALKIRIES = 3,
- TYPE_LICH_KING = 4,
- TYPE_ANUBARAK = 5,
+ BOSS_BEASTS = 0,
+ BOSS_JARAXXUS = 1,
+ BOSS_CRUSADERS = 2,
+ BOSS_VALKIRIES = 3,
+ BOSS_LICH_KING = 4, // not really a boss but oh well
+ BOSS_ANUBARAK = 5,
MAX_ENCOUNTERS = 6,
TYPE_COUNTER = 8,
@@ -31,15 +31,19 @@ enum
SPELL_WILFRED_PORTAL = 68424,
SPELL_JARAXXUS_CHAINS = 67924,
+ SPELL_CORPSE_TELEPORT = 69016,
+ SPELL_DESTROY_FLOOR_KNOCKUP = 68193,
DESPAWN_TIME = 300000,
+
+ DISPLAYID_DESTROYED_FLOOR = 9060
};
const Position ToCSpawnLoc[]=
{
{563.912f, 261.625f, 394.73f, 4.70437f}, // 0 Center
{575.451f, 261.496f, 394.73f, 4.6541f}, // 1 Left
- {549.951f, 261.55f, 394.73f, 4.74835f}, // 2 Right
+ {549.951f, 261.55f, 394.73f, 4.74835f} // 2 Right
};
const Position ToCCommonLoc[]=
@@ -68,7 +72,7 @@ const Position ToCCommonLoc[]=
{558.811610f, 195.985779f, 394.671661f, 0}, // 13
{567.641724f, 195.351501f, 394.659943f, 0}, // 14
{560.633972f, 195.391708f, 395.137543f, 0}, // 15
- {565.816956f, 195.477921f, 395.136810f, 0}, // 16
+ {565.816956f, 195.477921f, 395.136810f, 0} // 16
};
const Position JaraxxusLoc[]=
@@ -76,7 +80,7 @@ const Position JaraxxusLoc[]=
{508.104767f, 138.247345f, 395.128052f, 0}, // 0 - Fizzlebang start location
{548.610596f, 139.807800f, 394.321838f, 0}, // 1 - fizzlebang end
{581.854187f, 138.0f, 394.319f, 0}, // 2 - Portal Right
- {550.558838f, 138.0f, 394.319f, 0}, // 3 - Portal Left
+ {550.558838f, 138.0f, 394.319f, 0} // 3 - Portal Left
};
const Position FactionChampionLoc[]=
@@ -102,21 +106,21 @@ const Position FactionChampionLoc[]=
{528.958f, 131.47f, 394.73f, 0}, // 16 - Horde Final Pos 6
{526.309f, 116.667f, 394.833f, 0}, // 17 - Horde Final Pos 7
{524.238f, 122.411f, 394.819f, 0}, // 18 - Horde Final Pos 8
- {521.901f, 128.488f, 394.832f, 0}, // 19 - Horde Final Pos 9
+ {521.901f, 128.488f, 394.832f, 0} // 19 - Horde Final Pos 9
};
const Position TwinValkyrsLoc[]=
{
- {586.060242f, 117.514809f, 394.314026f, 0}, // 0 - Dark essence 1
- {541.602112f, 161.879837f, 394.587952f, 0}, // 1 - Dark essence 2
- {541.021118f, 117.262932f, 395.314819f, 0}, // 2 - Light essence 1
- {586.200562f, 162.145523f, 394.626129f, 0}, // 3 - Light essence 2
+ {586.060242f, 117.514809f, 394.41f, 0}, // 0 - Dark essence 1
+ {541.602112f, 161.879837f, 394.41f, 0}, // 1 - Dark essence 2
+ {541.021118f, 117.262932f, 394.41f, 0}, // 2 - Light essence 1
+ {586.200562f, 162.145523f, 394.41f, 0} // 3 - Light essence 2
};
const Position LichKingLoc[]=
{
{563.549f, 152.474f, 394.393f, 0}, // 0 - Lich king start
- {563.547f, 141.613f, 393.908f, 0}, // 1 - Lich king end
+ {563.547f, 141.613f, 393.908f, 0} // 1 - Lich king end
};
const Position AnubarakLoc[]=
@@ -126,20 +130,20 @@ const Position AnubarakLoc[]=
{694.886353f, 102.484665f, 142.119614f, 0}, // 3 - Nerub Spawn
{694.500671f, 185.363968f, 142.117905f, 0}, // 5 - Nerub Spawn
{731.987244f, 83.3824690f, 142.119614f, 0}, // 2 - Nerub Spawn
- {740.184509f, 193.443390f, 142.117584f, 0}, // 4 - Nerub Spawn
+ {740.184509f, 193.443390f, 142.117584f, 0} // 4 - Nerub Spawn
};
const Position EndSpawnLoc[]=
{
{648.9167f, 131.0208f, 141.6161f, 0}, // 0 - Highlord Tirion Fordring
{649.1614f, 142.0399f, 141.3057f ,0}, // 1 - Argent Mage
- {644.6250f, 149.2743f, 140.6015f ,0}, // 2 - Portal to Dalaran
+ {644.6250f, 149.2743f, 140.6015f ,0} // 2 - Portal to Dalaran
};
enum euiWorldStates
{
UPDATE_STATE_UI_SHOW = 4390,
- UPDATE_STATE_UI_COUNT = 4389,
+ UPDATE_STATE_UI_COUNT = 4389
};
enum eNorthrendBeasts
@@ -152,7 +156,7 @@ enum eNorthrendBeasts
SNAKES_SPECIAL = 2003,
SNAKES_DONE = 2004,
ICEHOWL_IN_PROGRESS = 3000,
- ICEHOWL_DONE = 3001,
+ ICEHOWL_DONE = 3001
};
enum eAnnouncerMessages
@@ -162,7 +166,7 @@ enum eAnnouncerMessages
MSG_CRUSADERS = 724003,
MSG_VALKIRIES = 724004,
MSG_LICH_KING = 724005,
- MSG_ANUBARAK = 724006,
+ MSG_ANUBARAK = 724006
};
enum eCreature
@@ -227,7 +231,7 @@ enum eCreature
NPC_DARK_ESSENCE = 34567,
NPC_LIGHT_ESSENCE = 34568,
- NPC_ANUBARAK = 34564,
+ NPC_ANUBARAK = 34564
};
enum eGameObject
@@ -253,7 +257,7 @@ enum eGameObject
GO_MAIN_GATE_DOOR = 195647,
GO_EAST_PORTCULLIS = 195648,
GO_WEB_DOOR = 195485,
- GO_PORTAL_TO_DALARAN = 195682,
+ GO_PORTAL_TO_DALARAN = 195682
};
enum eAchievementData