aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeader <keader.android@gmail.com>2019-06-17 08:38:37 -0300
committerShauren <shauren.trinity@gmail.com>2021-12-11 14:55:18 +0100
commitf749b3a2e920ff8bd3f79c1868878afd1c0148bc (patch)
treebf16721aa4b84548841c851555e6a64ef7d4e3ed /src
parentc8d0e0fd6df0d107fe80944ca96e3141f572b9b1 (diff)
Scripts/Icecrown Citadel: Fixed Blood Orb Game Object (#23397)
Close #18005 and Update #18529 (cherry picked from commit 394b119664bc16dc5376f1404925b6d0b5a26876)
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp599
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h13
4 files changed, 616 insertions, 2 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index b4352659170..381b3306d5f 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -106,6 +106,7 @@ enum Spells
SPELL_KINETIC_BOMB = 72080,
SPELL_SHOCK_VORTEX = 72037,
SPELL_EMPOWERED_SHOCK_VORTEX = 72039,
+ SPELL_REMOVE_EMPOWERED_BLOOD = 72131,
// Kinetic Bomb
SPELL_UNSTABLE = 72059,
@@ -246,7 +247,10 @@ class boss_blood_council_controller : public CreatureScript
prince->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
prince->SetImmuneToPC(false);
if (bossData == DATA_PRINCE_VALANAR)
+ {
prince->SetHealth(prince->GetMaxHealth());
+ prince->CastSpell(prince, SPELL_REMOVE_EMPOWERED_BLOOD, true);
+ }
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index 4abf76306e9..758c45b13b5 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -69,6 +69,7 @@ enum Spells
SPELL_INCITE_TERROR = 73070,
SPELL_BLOODBOLT_WHIRL = 71772,
SPELL_ANNIHILATE = 71322,
+ SPELL_CLEAR_ALL_STATUS_AILMENTS = 70939,
// Blood Infusion
SPELL_BLOOD_INFUSION_CREDIT = 72934
@@ -190,6 +191,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
DoCast(me, SPELL_SHROUD_OF_SORROW, true);
DoCast(me, SPELL_FRENZIED_BLOODTHIRST_VISUAL, true);
+ DoCastSelf(SPELL_CLEAR_ALL_STATUS_AILMENTS, true);
_creditBloodQuickening = instance->GetData(DATA_BLOOD_QUICKENING_STATE) == IN_PROGRESS;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index a461d67b796..ff9e0c624ca 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -17,6 +17,8 @@
#include "icecrown_citadel.h"
#include "CellImpl.h"
+#include "GameObject.h"
+#include "GameObjectAI.h"
#include "GridNotifiersImpl.h"
#include "InstanceScript.h"
#include "MotionMaster.h"
@@ -164,6 +166,46 @@ enum ICCSpells
// Invisible Stalker (Float, Uninteractible, LargeAOI)
SPELL_SOUL_MISSILE = 72585,
+
+ // Empowering Blood Orb
+ SPELL_EMPOWERED_BLOOD_2 = 70232,
+ SPELL_EMPOWERED_BLOOD_3 = 70304,
+ SPELL_EMPOWERED_BLOOD_4 = 70320,
+ SPELL_ORB_CONTROLLER_ACTIVE = 70293,
+
+ // Darkfallen Generic
+ SPELL_BLOOD_ORB_VISUAL = 72099,
+ SPELL_SIPHON_ESSENCE = 70299,
+
+ // Darkfallen Blood Knight
+ SPELL_VAMPIRIC_AURA = 71736,
+ SPELL_BLOOD_MIRROR = 70450,
+ SPELL_BLOOD_MIRROR_2 = 70451,
+ SPELL_BLOOD_MIRROR_DAMAGE_SHARE = 70445,
+ SPELL_UNHOLY_STRIKE = 70437,
+
+ // Darkfallen Noble
+ SPELL_SHADOW_BOLT = 72960,
+ SPELL_CHAINS_OF_SHADOW = 72960,
+
+ // Darkfallen Archmage
+ SPELL_FIREBALL = 70409,
+ SPELL_AMPLIFY_MAGIC = 70408,
+ SPELL_BLAST_WAVE = 70407,
+ SPELL_POLYMORPH_ALLY = 72106,
+ SPELL_POLYMORPH = 70410,
+
+ // Darkfallen Advisor
+ SPELL_LICH_SLAP = 72057,
+ SPELL_SHROUD_OF_SPELL_WARDING = 72066,
+
+ // Vampiric Fiend
+ SPELL_DISEASE_CLOUD = 41290,
+ SPELL_LEECHING_ROOT = 70671,
+
+ // Darkfallen Tactician
+ SPELL_SHADOWSTEP = 70431,
+ SPELL_BLOOD_SAP = 70432
};
// Helper defines
@@ -261,7 +303,8 @@ enum ICCEventTypes
enum ICCDataTypes
{
- DATA_DAMNED_KILLS = 1,
+ DATA_DAMNED_KILLS = 1,
+ DATA_GUID
};
enum ICCActions
@@ -272,6 +315,9 @@ enum ICCActions
ACTION_RESURRECT_CAPTAINS = 3,
ACTION_CAPTAIN_DIES = 4,
ACTION_RESET_EVENT = 5,
+ ACTION_SIPHON_INTERRUPTED = 6,
+ ACTION_EVADE = 7,
+ ACTION_COMBAT = 8
};
enum ICCEventIds
@@ -1805,6 +1851,542 @@ struct npc_entrance_faction_leader : public ScriptedAI
}
};
+class MinionSearch
+{
+public:
+ MinionSearch(bool checkCasting) : _checkCasting(checkCasting) { }
+
+ bool operator()(Unit* unit) const
+ {
+ if (!unit->IsAlive() || (_checkCasting && unit->HasUnitState(UNIT_STATE_CASTING)))
+ return false;
+
+ switch (unit->GetEntry())
+ {
+ case NPC_DARKFALLEN_BLOOD_KNIGHT:
+ case NPC_DARKFALLEN_NOBLE:
+ case NPC_DARKFALLEN_ARCHMAGE:
+ case NPC_DARKFALLEN_ADVISOR:
+ case NPC_DARKFALLEN_TACTICIAN:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+private:
+ // Need check to not use polymorph in a casting creature
+ bool _checkCasting;
+};
+
+std::vector<uint32> DarkFallensEmotes =
+{
+ EMOTE_ONESHOT_TALK,
+ EMOTE_ONESHOT_EXCLAMATION,
+ EMOTE_ONESHOT_QUESTION,
+ EMOTE_ONESHOT_LAUGH,
+ EMOTE_ONESHOT_YES,
+ EMOTE_ONESHOT_NO
+};
+
+struct npc_icc_orb_controller : public ScriptedAI
+{
+ npc_icc_orb_controller(Creature* creature) : ScriptedAI(creature), _isInCombat(false) { }
+
+ void Reset() override
+ {
+ _minionGuids.clear();
+ std::vector<Creature*> creatures;
+ MinionSearch check(false);
+ Trinity::CreatureListSearcher<MinionSearch> searcher(me, creatures, check);
+ Cell::VisitGridObjects(me, searcher, 10.0f);
+
+ for (Creature* creature : creatures)
+ {
+ creature->AI()->SetGUID(me->GetGUID(), DATA_GUID);
+ _minionGuids.push_back(creature->GetGUID());
+ }
+
+ if (creatures.empty())
+ return;
+
+ bool isLongRepeat = false;
+ _scheduler.Schedule(1s, [this, &isLongRepeat](TaskContext visual)
+ {
+ ObjectGuid guid = Trinity::Containers::SelectRandomContainerElement(_minionGuids);
+ if (Unit* minion = ObjectAccessor::GetUnit(*me, guid))
+ minion->CastSpell(nullptr, SPELL_BLOOD_ORB_VISUAL);
+ visual.Repeat(isLongRepeat ? 21s : 3s);
+ isLongRepeat = !isLongRepeat;
+ });
+ }
+
+ void SpellHit(Unit* caster, SpellInfo const* spell) override
+ {
+ if (spell->Id == SPELL_ORB_CONTROLLER_ACTIVE)
+ {
+ if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 5.0f))
+ orb->AI()->SetGUID(caster->GetGUID(), DATA_GUID);
+ }
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_COMBAT && !_isInCombat)
+ {
+ _isInCombat = true;
+ _scheduler.CancelAll();
+ if (_minionGuids.empty())
+ return;
+
+ if (Unit* minion = ObjectAccessor::GetUnit(*me, Trinity::Containers::SelectRandomContainerElement(_minionGuids)))
+ minion->CastSpell(me, SPELL_SIPHON_ESSENCE);
+
+ for (ObjectGuid guid : _minionGuids)
+ {
+ if (Creature* minion = ObjectAccessor::GetCreature(*me, guid))
+ if (minion->IsAIEnabled() && !minion->IsInCombat())
+ minion->AI()->DoZoneInCombat();
+ }
+ }
+ else if (action == ACTION_EVADE && _isInCombat)
+ {
+ _isInCombat = false;
+ // Update Darkfallens
+ Reset();
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+private:
+ TaskScheduler _scheduler;
+ GuidVector _minionGuids;
+ bool _isInCombat;
+};
+
+struct DarkFallenAI : public ScriptedAI
+{
+ DarkFallenAI(Creature* creature) : ScriptedAI(creature), IsDoingEmotes(true), AttackSpellId(0) { }
+
+ virtual void ScheduleSpells() = 0;
+
+ void Reset() override
+ {
+ IsDoingEmotes = me->GetWaypointPath() ? false : true;
+ Scheduler.CancelAll();
+ Scheduler.SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ })
+ .Schedule(1s, 10s, [this](TaskContext emote)
+ {
+ if (!IsDoingEmotes)
+ return;
+
+ if (roll_chance_i(20))
+ {
+ std::vector<Creature*> creatures;
+ MinionSearch check(true);
+ Trinity::CreatureListSearcher<MinionSearch> searcher(me, creatures, check);
+ Cell::VisitGridObjects(me, searcher, 10.0f);
+ if (!creatures.empty())
+ {
+ Creature* friendly = Trinity::Containers::SelectRandomContainerElement(creatures);
+ DoCast(friendly, SPELL_POLYMORPH_ALLY);
+ }
+ }
+ Scheduler.Schedule(1s, [this](TaskContext /*emote*/)
+ {
+ me->HandleEmoteCommand(Trinity::Containers::SelectRandomContainerElement(DarkFallensEmotes));
+ });
+ emote.Repeat(15s, 30s);
+ });
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ IsDoingEmotes = false;
+ Scheduler.CancelAll();
+ ScheduleSpells();
+ if (Unit* trigger = ObjectAccessor::GetUnit(*me, TriggerGuid))
+ trigger->GetAI()->DoAction(ACTION_COMBAT);
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_SIPHON_INTERRUPTED)
+ if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 10.0f))
+ orb->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ }
+
+ void SetGUID(ObjectGuid const& guid, int32 id) override
+ {
+ if (id == DATA_GUID)
+ TriggerGuid = guid;
+ }
+
+ void JustReachedHome() override
+ {
+ ScriptedAI::JustReachedHome();
+ if (Unit* trigger = ObjectAccessor::GetUnit(*me, TriggerGuid))
+ trigger->GetAI()->DoAction(ACTION_EVADE);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && !IsDoingEmotes)
+ return;
+
+ Scheduler.Update(diff);
+
+ if (AttackSpellId)
+ DoSpellAttackIfReady(AttackSpellId);
+ else
+ DoMeleeAttackIfReady();
+ }
+
+protected:
+ TaskScheduler Scheduler;
+ ObjectGuid TriggerGuid;
+ bool IsDoingEmotes;
+ uint32 AttackSpellId;
+};
+
+struct npc_darkfallen_blood_knight : public DarkFallenAI
+{
+ npc_darkfallen_blood_knight(Creature* creature) : DarkFallenAI(creature) { }
+
+ void ScheduleSpells() override
+ {
+ Scheduler.Schedule(500ms, [this](TaskContext /*context*/)
+ {
+ DoCastSelf(SPELL_VAMPIRIC_AURA);
+ })
+ .Schedule(8s, [this](TaskContext unholyStrike)
+ {
+ DoCastVictim(SPELL_UNHOLY_STRIKE);
+ unholyStrike.Repeat(8s, 9s);
+ })
+ .Schedule(6s, [this](TaskContext bloodMirror)
+ {
+ DoCastSelf(SPELL_BLOOD_MIRROR);
+ bloodMirror.Repeat(34s);
+ });
+ }
+};
+
+struct npc_darkfallen_noble : public DarkFallenAI
+{
+ npc_darkfallen_noble(Creature* creature) : DarkFallenAI(creature) { }
+
+ void ScheduleSpells() override
+ {
+ AttackSpellId = SPELL_SHADOW_BOLT;
+ Scheduler.Schedule(500ms, [this](TaskContext /*context*/)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, false, -SPELL_CHAINS_OF_SHADOW))
+ DoCast(target, SPELL_CHAINS_OF_SHADOW);
+ })
+ .Schedule(11s, [this](TaskContext summonVampiric)
+ {
+ // Vampiric should be summoned by 70647 but i have no idea what is miscB of summon effect
+ if (Unit* target = me->GetVictim())
+ if (Creature* vampiric = me->SummonCreature(NPC_VAMPIRIC_FIEND, target->GetPosition(), TEMPSUMMON_CORPSE_DESPAWN))
+ vampiric->AI()->AttackStart(target);
+ summonVampiric.Repeat(30s);
+ });
+ }
+};
+
+struct npc_vampiric_fiend : public ScriptedAI
+{
+ npc_vampiric_fiend(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ DoCastSelf(SPELL_DISEASE_CLOUD);
+ _scheduler.Schedule(9s, [this](TaskContext /*leechingRoot*/)
+ {
+ DoCastVictim(SPELL_LEECHING_ROOT);
+ })
+ .Schedule(38s, [this](TaskContext /*leechingRoot*/)
+ {
+ me->DespawnOrUnsummon();
+ });
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ _scheduler.CancelAll();
+ me->DespawnOrUnsummon();
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ _scheduler.Update(diff);
+
+ DoMeleeAttackIfReady();
+ }
+
+private:
+ TaskScheduler _scheduler;
+};
+
+struct npc_darkfallen_archmage : public DarkFallenAI
+{
+ npc_darkfallen_archmage(Creature* creature) : DarkFallenAI(creature) { }
+
+ void ScheduleSpells() override
+ {
+ AttackSpellId = SPELL_FIREBALL;
+ Scheduler.Schedule(1s, [this](TaskContext amplifyMagic)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_AMPLIFY_MAGIC);
+ amplifyMagic.Repeat(15s, 24s);
+ })
+ .Schedule(10s, [this](TaskContext blastWave)
+ {
+ DoCastSelf(SPELL_BLAST_WAVE);
+ blastWave.Repeat(25s, 30s);
+ })
+ .Schedule(17s, [this](TaskContext polymorph)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, false, -SPELL_POLYMORPH))
+ DoCast(target, SPELL_POLYMORPH);
+ polymorph.Repeat(25s, 35s);
+ });
+ }
+};
+
+struct npc_darkfallen_advisor : public DarkFallenAI
+{
+ npc_darkfallen_advisor(Creature* creature) : DarkFallenAI(creature) { }
+
+ void ScheduleSpells() override
+ {
+ Scheduler.Schedule(8s, [this](TaskContext lichSlap)
+ {
+ DoCastVictim(SPELL_LICH_SLAP);
+ lichSlap.Repeat(12s);
+ })
+ .Schedule(50s, [this](TaskContext immunity)
+ {
+ if (Unit* target = DoSelectLowestHpFriendly(40.0f))
+ DoCast(target, SPELL_SHROUD_OF_SPELL_WARDING);
+ immunity.Repeat(20s, 25s);
+ });
+ }
+};
+
+struct npc_darkfallen_tactician : public DarkFallenAI
+{
+ npc_darkfallen_tactician(Creature* creature) : DarkFallenAI(creature) { }
+
+ void ScheduleSpells() override
+ {
+ Scheduler.Schedule(8s, [this](TaskContext unholyStrike)
+ {
+ DoCastVictim(SPELL_UNHOLY_STRIKE);
+ unholyStrike.Repeat(8s, 11s);
+ })
+ .Schedule(10s, [this](TaskContext shadowStep)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, false))
+ {
+ DoCast(target, SPELL_SHADOWSTEP);
+ DoCast(target, SPELL_BLOOD_SAP);
+ }
+ shadowStep.Repeat(20s);
+ });
+ }
+};
+
+struct go_empowering_blood_orb : public GameObjectAI
+{
+ go_empowering_blood_orb(GameObject* go) : GameObjectAI(go) { }
+
+ bool GossipHello(Player* player) override
+ {
+ me->CastSpell(player, SPELL_EMPOWERED_BLOOD, true);
+ HandleObjectUse();
+ return true;
+ }
+
+ void HandleObjectUse()
+ {
+ me->AddFlag(GO_FLAG_IN_USE);
+ me->SetGoAnimProgress(255);
+ me->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ if (Creature* target = me->FindNearestCreature(NPC_ORB_VISUAL_STALKER, 10.0f, true))
+ target->KillSelf();
+ _scheduler.Schedule(3s, [this](TaskContext /*context*/)
+ {
+ me->Delete();
+ });
+ }
+
+ void SetGUID(ObjectGuid const& guid, int32 id) override
+ {
+ if (id == DATA_GUID)
+ {
+ if (Unit* target = ObjectAccessor::GetUnit(*me, guid))
+ me->CastSpell(target, SPELL_EMPOWERED_BLOOD_3, true);
+ HandleObjectUse();
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
+
+private:
+ TaskScheduler _scheduler;
+};
+
+// 70227 - Empowered Blood
+class spell_icc_empowered_blood : public AuraScript
+{
+ PrepareAuraScript(spell_icc_empowered_blood);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_EMPOWERED_BLOOD_2 });
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_EMPOWERED_BLOOD_2, true);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(SPELL_EMPOWERED_BLOOD_2);
+ }
+
+ void Register() override
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_icc_empowered_blood::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_icc_empowered_blood::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ }
+};
+
+// 70304 - Empowered Blood
+class spell_icc_empowered_blood_3 : public AuraScript
+{
+ PrepareAuraScript(spell_icc_empowered_blood_3);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_EMPOWERED_BLOOD_4 });
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_EMPOWERED_BLOOD_4, true);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(SPELL_EMPOWERED_BLOOD_4);
+ }
+
+ void Register() override
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_icc_empowered_blood_3::OnApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_icc_empowered_blood_3::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ }
+};
+
+// 70299 - Siphon Essence
+class spell_icc_siphon_essence : public AuraScript
+{
+ PrepareAuraScript(spell_icc_siphon_essence);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTarget()->IsAIEnabled())
+ GetTarget()->GetAI()->DoAction(ACTION_SIPHON_INTERRUPTED);
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_icc_siphon_essence::OnRemove, EFFECT_1, SPELL_AURA_MOD_ROOT, AURA_EFFECT_HANDLE_REAL);
+ }
+};
+
+// 70450 - Blood Mirror
+class spell_darkfallen_blood_mirror : public SpellScript
+{
+ PrepareSpellScript(spell_darkfallen_blood_mirror);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_BLOOD_MIRROR_2, SPELL_BLOOD_MIRROR_DAMAGE_SHARE });
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.size() < 2)
+ return;
+
+ _targets = targets;
+ Trinity::Containers::RandomResize(_targets, 2);
+ }
+
+ void HandleMirror(SpellEffIndex /*effIndex*/)
+ {
+ if (_targets.empty())
+ return;
+
+ Unit* caster = GetCaster();
+ WorldObject* target = _targets.front();
+ WorldObject* mirror = _targets.back();
+
+ caster->CastSpell(target, SPELL_BLOOD_MIRROR_2, true);
+ target->CastSpell(mirror, SPELL_BLOOD_MIRROR_DAMAGE_SHARE, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_darkfallen_blood_mirror::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectLaunch += SpellEffectFn(spell_darkfallen_blood_mirror::HandleMirror, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+
+private:
+ std::list<WorldObject*> _targets;
+};
+
+// 72131 - Remove Empowered Blood
+// 70939 - Blood Queen Lana'thel - Clear all Status Ailments
+class spell_generic_remove_empowered_blood : public SpellScript
+{
+ PrepareSpellScript(spell_generic_remove_empowered_blood);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_EMPOWERED_BLOOD });
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetHitUnit()->RemoveAurasDueToSpell(SPELL_EMPOWERED_BLOOD);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_generic_remove_empowered_blood::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
class spell_icc_stoneform : public SpellScriptLoader
{
public:
@@ -2276,7 +2858,20 @@ void AddSC_icecrown_citadel()
new npc_frostwing_vrykul();
new npc_impaling_spear();
new npc_arthas_teleport_visual();
- RegisterCreatureAI(npc_entrance_faction_leader);
+ RegisterIcecrownCitadelCreatureAI(npc_entrance_faction_leader);
+ RegisterIcecrownCitadelCreatureAI(npc_icc_orb_controller);
+ RegisterIcecrownCitadelCreatureAI(npc_darkfallen_blood_knight);
+ RegisterIcecrownCitadelCreatureAI(npc_darkfallen_noble);
+ RegisterIcecrownCitadelCreatureAI(npc_vampiric_fiend);
+ RegisterIcecrownCitadelCreatureAI(npc_darkfallen_archmage);
+ RegisterIcecrownCitadelCreatureAI(npc_darkfallen_advisor);
+ RegisterIcecrownCitadelCreatureAI(npc_darkfallen_tactician);
+ RegisterGameObjectAI(go_empowering_blood_orb);
+ RegisterAuraScript(spell_icc_empowered_blood);
+ RegisterAuraScript(spell_icc_empowered_blood_3);
+ RegisterAuraScript(spell_icc_siphon_essence);
+ RegisterSpellScript(spell_darkfallen_blood_mirror);
+ RegisterSpellScript(spell_generic_remove_empowered_blood);
new spell_icc_stoneform();
new spell_icc_sprit_alarm();
new spell_frost_giant_death_plague();
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 8e74a5be48b..4707248ea68 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -61,6 +61,9 @@ enum ICSharedSpells
SPELL_UNSATED_CRAVING = 71168,
SPELL_SHADOWS_FATE = 71169,
+ // Empowering Blood Orb
+ SPELL_EMPOWERED_BLOOD = 70227,
+
// ICC Buffs
SPELL_HELLSCREAMS_WARSONG = 73822,
SPELL_STRENGHT_OF_WRYNN = 73828
@@ -261,6 +264,13 @@ enum ICCreaturesIds
NPC_KINETIC_BOMB = 38454,
NPC_SHOCK_VORTEX = 38422,
NPC_BLOOD_QUEEN_LANA_THEL_COUNCIL = 38004,
+ NPC_DARKFALLEN_BLOOD_KNIGHT = 37595,
+ NPC_DARKFALLEN_NOBLE = 37663,
+ NPC_DARKFALLEN_ARCHMAGE = 37664,
+ NPC_DARKFALLEN_ADVISOR = 37571,
+ NPC_DARKFALLEN_TACTICIAN = 37666,
+ NPC_VAMPIRIC_FIEND = 37901,
+ NPC_ORB_VISUAL_STALKER = 38463,
// Blood-Queen Lana'thel
NPC_BLOOD_QUEEN_LANA_THEL = 37955,
@@ -400,6 +410,7 @@ enum ICGameObjectsIds
GO_CRIMSON_HALL_DOOR = 201376,
GO_BLOOD_ELF_COUNCIL_DOOR = 201378,
GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT = 201377,
+ GO_EMPOWERING_BLOOD_ORB = 201741,
// Blood-Queen Lana'thel
GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01 = 201746,
@@ -554,4 +565,6 @@ inline AI* GetIcecrownCitadelAI(T* obj)
return GetInstanceAI<AI>(obj, ICCScriptName);
}
+#define RegisterIcecrownCitadelCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetIcecrownCitadelAI)
+
#endif // ICECROWN_CITADEL_H_