fix(Scripts/IcecrownCitadel): Fixed Blood Orb Game Object (#24340)

Co-authored-by: Lucas Nascimento <keader.android@gmail.com>
This commit is contained in:
EricksOliveira
2026-07-24 19:03:44 +00:00
committed by GitHub
parent f86772437c
commit ac6592ae3f
6 changed files with 727 additions and 6 deletions

View File

@@ -0,0 +1,31 @@
--
UPDATE `creature_template` SET `unit_flags`=33554432 WHERE `entry`=38463;
UPDATE `creature_template` SET `ScriptName`='npc_icc_orb_controller' WHERE `entry`=38463;
UPDATE `creature_template` SET `ScriptName`='npc_darkfallen_blood_knight' WHERE `entry`=37595;
UPDATE `creature_template` SET `ScriptName`='npc_darkfallen_noble' WHERE `entry`=37663;
UPDATE `creature_template` SET `ScriptName`='npc_vampiric_fiend' WHERE `entry`=37901;
UPDATE `creature_template` SET `ScriptName`='npc_darkfallen_archmage' WHERE `entry`=37664;
UPDATE `creature_template` SET `ScriptName`='npc_darkfallen_advisor' WHERE `entry`=37571;
UPDATE `creature_template` SET `ScriptName`='npc_darkfallen_tactician' WHERE `entry`=37666;
UPDATE `gameobject_template` SET `ScriptName`='go_empowering_blood_orb' WHERE `entry`=201741;
DELETE FROM `spell_script_names` WHERE `spell_id` IN (70227,70304,70299,70450,72131,70939);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(70227,'spell_icc_empowered_blood'),
(70304,'spell_icc_empowered_blood_3'),
(70299,'spell_icc_siphon_essence'),
(70450,'spell_darkfallen_blood_mirror'),
(72131,'spell_generic_remove_empowered_blood'),
(70939,'spell_generic_remove_empowered_blood');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (72099,70299,70293);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13,1,72099,0,0,31,0,3,36934,0,0,0,0,'','Effect_0 hits Empowering Orb Controller'),
(13,1,70299,0,0,31,0,3,36934,0,0,0,0,'','Effect_0 hits Empowering Orb Controller'),
(13,1,70293,0,0,31,0,3,38463,0,0,0,0,'','Effect_0 hits Empowering Orb Controller');
DELETE FROM `creature_template_movement` WHERE `CreatureId`=36934;
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`) VALUES
(36934,0,0,1,1,0,0);
DELETE FROM `creature` WHERE `guid` IN (201220,201473,201559) AND `id`=38463;

View File

@@ -3300,12 +3300,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].MiscValue = 100;
});
// Empowered Blood
ApplySpellFix({ 70227, 70232 }, [](SpellInfo* spellInfo)
{
spellInfo->AreaGroupId = 2452; // Whole icc instead of Crimson Halls only, remove when area calculation is fixed
});
ApplySpellFix({ 74509 }, [](SpellInfo* spellInfo)
{
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); // 20yd

View File

@@ -101,6 +101,8 @@ enum Spells
SPELL_KINETIC_BOMB = 72080,
SPELL_SHOCK_VORTEX = 72037,
SPELL_EMPOWERED_SHOCK_VORTEX = 72039,
SPELL_REMOVE_EMPOWERED_BLOOD = 72131,
SPELL_CLEAR_ALL_STATUS_AILMENTS = 70939,
// Kinetic Bomb
SPELL_UNSTABLE = 72059,
@@ -233,6 +235,7 @@ public:
_isEmpowered = false;
_evading = false;
me->SetHealth(me->GetMaxHealth());
me->CastSpell(me, SPELL_REMOVE_EMPOWERED_BLOOD, true);
me->SetReactState(REACT_AGGRESSIVE);
}
@@ -261,6 +264,7 @@ public:
me->SetLootRecipient(who);
me->LowerPlayerDamageReq(me->GetMaxHealth());
me->SetReactState(REACT_AGGRESSIVE);
DoCastSelf(SPELL_CLEAR_ALL_STATUS_AILMENTS, true);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_PRINCE_TALDARAM_GUID)))

View File

@@ -71,6 +71,7 @@ enum Spells
SPELL_INCITE_TERROR = 73070,
SPELL_BLOODBOLT_WHIRL = 71772,
SPELL_ANNIHILATE = 71322,
SPELL_CLEAR_ALL_STATUS_AILMENTS = 70939,
};
enum Shadowmourne
@@ -224,8 +225,11 @@ public:
me->setActive(true);
DoZoneInCombat();
Talk(SAY_AGGRO);
if (instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) != DONE)
instance->SetBossState(DATA_BLOOD_QUEEN_LANA_THEL, IN_PROGRESS);
DoCastSelf(SPELL_CLEAR_ALL_STATUS_AILMENTS, true);
_creditBloodQuickening = instance->GetData(DATA_BLOOD_QUICKENING_STATE) == IN_PROGRESS;
}

View File

@@ -21,6 +21,8 @@
#include "Cell.h"
#include "CellImpl.h"
#include "CreatureScript.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
@@ -160,6 +162,46 @@ enum Spells
// 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 = 70645,
// 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
@@ -258,6 +300,7 @@ enum EventTypes
enum DataTypesICC
{
DATA_DAMNED_KILLS = 1,
DATA_GUID
};
enum Actions
@@ -268,6 +311,9 @@ enum Actions
ACTION_RESURRECT_CAPTAINS = 3,
ACTION_CAPTAIN_DIES = 4,
ACTION_RESET_EVENT = 5,
ACTION_SIPHON_INTERRUPTED = 6,
ACTION_EVADE = 7,
ACTION_COMBAT = 8
};
enum EventIds
@@ -1940,6 +1986,624 @@ public:
}
};
class ICCOrbControllerMinionSearch
{
public:
ICCOrbControllerMinionSearch(Unit* owner, bool checkCasting) : _owner(owner), _checkCasting(checkCasting) {}
bool operator()(Creature* target) const
{
if (!target->IsAlive() || (_checkCasting && target->HasUnitState(UNIT_STATE_CASTING)) || target->GetWaypointPath() || _owner->GetDistance(target) > 10.0f)
return false;
switch (target->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
Unit* _owner;
bool _checkCasting;
};
std::vector<uint32> DarkFallensEmotes =
{
EMOTE_ONESHOT_TALK,
EMOTE_ONESHOT_EXCLAMATION,
EMOTE_ONESHOT_QUESTION,
EMOTE_ONESHOT_LAUGH,
EMOTE_ONESHOT_YES,
EMOTE_ONESHOT_NO
};
// 38463 - Empowering Orb Visual Stalker
struct npc_icc_orb_controller : public ScriptedAI
{
npc_icc_orb_controller(Creature* creature) : ScriptedAI(creature), _isInCombat(false), _isLongRepeat(false) {}
void Reset() override
{
_scheduler.Schedule(1s, [this](TaskContext /*initialize*/)
{
std::vector<Creature*> creatures;
ICCOrbControllerMinionSearch check(me, false);
Acore::CreatureListSearcher<ICCOrbControllerMinionSearch> searcher(me, creatures, check);
Cell::VisitObjects(me, searcher, 10.0f);
if (creatures.empty())
return;
for (Creature* creature : creatures)
{
creature->AI()->SetGUID(me->GetGUID(), DATA_GUID);
_minionGuids.push_back(creature->GetGUID());
}
ScheduleVisualChannel(false);
});
}
void ScheduleVisualChannel(bool evading)
{
_scheduler.Schedule(evading ? 5s : 1s, [this](TaskContext visual)
{
if (_minionGuids.empty())
return;
ObjectGuid mGuid = Acore::Containers::SelectRandomContainerElement(_minionGuids);
if (Unit* minion = ObjectAccessor::GetUnit(*me, mGuid))
minion->CastSpell(nullptr, SPELL_BLOOD_ORB_VISUAL);
visual.Repeat(_isLongRepeat ? 21s : 3s);
_isLongRepeat = !_isLongRepeat;
});
}
void UpdateValidGuids()
{
for (GuidVector::iterator itr = _minionGuids.begin(); itr != _minionGuids.end();)
{
if (Unit* minion = ObjectAccessor::GetUnit(*me, (*itr)))
{
if (!minion->IsAlive())
{
itr = _minionGuids.erase(itr);
continue;
}
++itr;
}
// Is not in world anymore
else
itr = _minionGuids.erase(itr);
}
}
void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_ORB_CONTROLLER_ACTIVE)
if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 5.0f))
orb->AI()->SetGUID(caster->GetGUID(), DATA_GUID);
}
void SetGUID(ObjectGuid const& guid, int32 id) override
{
if (id != ACTION_COMBAT || _isInCombat)
return;
Creature* darkfallen = ObjectAccessor::GetCreature(*me, guid);
if (!darkfallen)
return;
_isInCombat = true;
_scheduler.CancelAll();
if (_minionGuids.empty())
return;
for (ObjectGuid minionGuid : _minionGuids)
{
if (Creature* minion = ObjectAccessor::GetCreature(*me, minionGuid))
if (minion->IsAIEnabled && !minion->IsInCombat())
minion->AI()->DoZoneInCombat(darkfallen);
}
if (Unit* minion = ObjectAccessor::GetUnit(*me, Acore::Containers::SelectRandomContainerElement(_minionGuids)))
minion->CastSpell(nullptr, SPELL_SIPHON_ESSENCE);
}
void DoAction(int32 action) override
{
if (action == ACTION_EVADE && _isInCombat)
{
_isInCombat = false;
UpdateValidGuids();
ScheduleVisualChannel(true);
if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 5.0f))
orb->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
}
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
if (_isInCombat)
{
UpdateValidGuids();
if (_minionGuids.empty())
DoAction(ACTION_EVADE);
}
}
private:
TaskScheduler _scheduler;
GuidVector _minionGuids;
bool _isInCombat;
bool _isLongRepeat;
};
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;
ICCOrbControllerMinionSearch check(me, true);
Acore::CreatureListSearcher<ICCOrbControllerMinionSearch> searcher(me, creatures, check);
Cell::VisitObjects(me, searcher, 10.0f);
if (!creatures.empty())
{
Creature* friendly = Acore::Containers::SelectRandomContainerElement(creatures);
DoCast(friendly, SPELL_POLYMORPH_ALLY);
}
}
Scheduler.Schedule(1s, [this](TaskContext /*emote*/)
{
me->HandleEmoteCommand(Acore::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()->SetGUID(me->GetGUID(), ACTION_COMBAT);
}
void DoAction(int32 action) override
{
if (action == ACTION_SIPHON_INTERRUPTED)
if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 10.0f))
orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
}
void SetGUID(ObjectGuid const& guid, int32 id) override
{
if (id == DATA_GUID)
TriggerGuid = guid;
}
void EnterEvadeMode(EvadeReason why) override
{
ScriptedAI::EnterEvadeMode(why);
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(SelectTargetMethod::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;
};
// 37664 - Darkfallen Archmage
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(SelectTargetMethod::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(SelectTargetMethod::Random, 0, 0.0f, true, false, -SPELL_POLYMORPH))
DoCast(target, SPELL_POLYMORPH);
polymorph.Repeat(25s, 35s);
});
}
};
// 37571 - Darkfallen Advisor
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);
});
}
};
// 37666 - Darkfallen Tactician
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(SelectTargetMethod::Random, 0, 0.0f, true, false))
{
DoCast(target, SPELL_SHADOWSTEP);
DoCast(target, SPELL_BLOOD_SAP);
}
shadowStep.Repeat(20s);
});
}
};
// 201741 - Empowering Blood Orb
struct go_empowering_blood_orb : public GameObjectAI
{
go_empowering_blood_orb(GameObject* go) : GameObjectAI(go) {}
void Reset() override
{
if (Creature* trigger = ObjectAccessor::GetCreature(*me, _triggerGuid))
trigger->DespawnOrUnsummon();
if (Creature* trigger = me->SummonCreature(NPC_ORB_VISUAL_STALKER, me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN))
_triggerGuid = trigger->GetGUID();
else
_triggerGuid.Clear();
}
bool GossipHello(Player* player, bool /*reportUse*/) override
{
me->CastSpell(player, SPELL_EMPOWERED_BLOOD);
HandleObjectUse();
return true;
}
void HandleObjectUse()
{
me->SetGameObjectFlag(GO_FLAG_IN_USE);
me->SetGoAnimProgress(255);
me->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
if (Creature* trigger = ObjectAccessor::GetCreature(*me, _triggerGuid))
trigger->DespawnOrUnsummon();
_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);
HandleObjectUse();
}
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
ObjectGuid _triggerGuid;
};
// 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_CANCEL)
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)
{
targets.remove_if([](WorldObject* target)
{
return !target->IsPlayer();
});
if (targets.size() < 2)
{
targets.clear();
return;
}
Acore::Containers::RandomResize(targets, 2);
_targets = targets;
}
void HandleMirror(SpellEffIndex /*effIndex*/)
{
if (_targets.empty())
return;
Unit* caster = GetCaster();
Unit* target = _targets.front()->ToUnit();
Unit* mirror = _targets.back()->ToUnit();
if (!caster || !target || !mirror)
return;
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_aura : public AuraScript
{
PrepareAuraScript(spell_icc_stoneform_aura);
@@ -3693,6 +4357,19 @@ void AddSC_icecrown_citadel()
new npc_frostwing_vrykul();
new npc_impaling_spear();
new npc_arthas_teleport_visual();
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);
RegisterSpellScript(spell_icc_empowered_blood);
RegisterSpellScript(spell_icc_empowered_blood_3);
RegisterSpellScript(spell_icc_siphon_essence);
RegisterSpellScript(spell_darkfallen_blood_mirror);
RegisterSpellScript(spell_generic_remove_empowered_blood);
RegisterSpellScript(spell_icc_stoneform_aura);
RegisterSpellScript(spell_icc_sprit_alarm);
RegisterSpellScript(spell_icc_geist_alarm);

View File

@@ -62,6 +62,9 @@ enum SharedSpells
SPELL_UNSATED_CRAVING = 71168,
SPELL_SHADOWS_FATE = 71169,
// Empowering Blood Orb
SPELL_EMPOWERED_BLOOD = 70227,
// Misc
SPELL_WEB_BEAM = 69887,
SPELL_WEB_BEAM2 = 69986,
@@ -282,6 +285,13 @@ enum CreaturesIds
NPC_KINETIC_BOMB_TARGET = 38458,
NPC_KINETIC_BOMB = 38454,
NPC_SHOCK_VORTEX = 38422,
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,
@@ -434,6 +444,7 @@ enum GameObjectsIds
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,