mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 17:05:44 +01:00
Core/Scripts: Illidari Council Rewrite (#18546)
Thanks to Sirikfoll, Krudor and Offl for all help
(cherry picked from commit 5af1fa2273)
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
DELETE FROM `creature` WHERE `id` IN(22952,22950,22949,22951);
|
||||
DELETE FROM `creature_summon_groups` WHERE `summonerId`=23426; -- Illidari Council Trigger
|
||||
INSERT INTO `creature_summon_groups` (`summonerId`,`summonerType`,`groupId`,`entry`,`position_x`,`position_y`,`position_z`,`orientation`,`summonType`,`summonTime`) VALUES
|
||||
(23426,0,1,22952,697.495,310.651,277.527,3.1765 ,6,3600000), -- Veras Darkshadow
|
||||
(23426,0,1,22950,700.792,307.192,277.526,3.14159,6,3600000), -- High Nethermancer Zerevor
|
||||
(23426,0,1,22949,700.739,302.722,277.526,3.10669,6,3600000), -- Gathios the Shatterer
|
||||
(23426,0,1,22951,697.409,299.377,277.526,3.07178,6,3600000); -- Lady Malande
|
||||
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=41333; -- Empyreal Equivalency
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(13,1,41333,0,0,31,0,3,22950,0,0,0,0,'','Effect_0 hits High Nethermancer Zerevor'),
|
||||
(13,1,41333,0,1,31,0,3,22949,0,0,0,0,'','Effect_0 hits Gathios the Shatterer'),
|
||||
(13,1,41333,0,2,31,0,3,22951,0,0,0,0,'','Effect_0 hits Lady Malande'),
|
||||
(13,1,41333,0,3,31,0,3,22952,0,0,0,0,'','Effect_0 hits Veras Darkshadow');
|
||||
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=41499; -- Empyreal Balance
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(13,1,41499,0,0,31,0,3,22950,0,0,0,0,'','Effect_0 hits High Nethermancer Zerevor'),
|
||||
(13,1,41499,0,1,31,0,3,22949,0,0,0,0,'','Effect_0 hits Gathios the Shatterer'),
|
||||
(13,1,41499,0,2,31,0,3,22951,0,0,0,0,'','Effect_0 hits Lady Malande'),
|
||||
(13,1,41499,0,3,31,0,3,22952,0,0,0,0,'','Effect_0 hits Veras Darkshadow');
|
||||
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=41342; -- Shared Rule
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(13,1,41342,0,0,31,0,3,23426,0,0,0,0,'','Effect_0 hits The Illidari Council');
|
||||
|
||||
UPDATE `linked_respawn` SET `linkedGuid`=52479 WHERE `linkedGuid`=52762;
|
||||
|
||||
UPDATE `creature_template` SET `flags_extra`=`flags_extra`|128, `ScriptName`='npc_veras_vanish_effect' WHERE `entry`=23451;
|
||||
UPDATE `creature_template` SET `ScriptName`='boss_illidari_council' WHERE `entry`=23426;
|
||||
UPDATE `creature_template` SET `ScriptName`='' WHERE `entry`=23499;
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName` IN(
|
||||
'spell_illidari_council_empyreal_balance',
|
||||
'spell_illidari_council_empyreal_equivalency',
|
||||
'spell_illidari_council_balance_of_power',
|
||||
'spell_illidari_council_deadly_strike',
|
||||
'spell_illidari_council_deadly_poison',
|
||||
'spell_illidari_council_judgement',
|
||||
'spell_illidari_council_seal',
|
||||
'spell_boss_lady_malande_shield',
|
||||
'spell_illidari_council_reflective_shield',
|
||||
'spell_illidari_dampen_magic');
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(41499,'spell_illidari_council_empyreal_balance'),
|
||||
(41333,'spell_illidari_council_empyreal_equivalency'),
|
||||
(41341,'spell_illidari_council_balance_of_power'),
|
||||
(41480,'spell_illidari_council_deadly_strike'),
|
||||
(41485,'spell_illidari_council_deadly_poison'),
|
||||
(41467,'spell_illidari_council_judgement'),
|
||||
(41469,'spell_illidari_council_seal'),
|
||||
(41459,'spell_illidari_council_seal'),
|
||||
(41475,'spell_illidari_council_reflective_shield'),
|
||||
(41478,'spell_illidari_dampen_magic');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` IN(22951,22949,22950,22952) AND (`GroupID` IN(3,4,5,6) OR (`GroupID`=2 AND `ID`=1));
|
||||
INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`Comment`) VALUES
|
||||
(22949,2,1,'You are MINE!',14,0,100,0,0,11427,21739,0,'council gath SPECIAL2'),
|
||||
(22949,3,0,'Selama am\'oronor!',14,0,100,0,0,11423,21735,0,'council gath SLAY'),
|
||||
(22949,4,0,'Well done!',14,0,100,0,0,11424,21736,0,'council gath SLAY_COMT'),
|
||||
(22949,5,0,'Lord Illidan, I...',14,0,100,0,0,11425,21737,0,'council gath DEATH'),
|
||||
(22951,2,1,'I\'m full of surprises!',14,0,100,0,0,11487,21719,0,'council mala SPECIAL2'),
|
||||
(22951,3,0,'My work is done.',14,0,100,0,0,11483,21712,0,'council mala SLAY'),
|
||||
(22951,4,0,'As it should be.',14,0,100,0,0,11484,21713,0,'council mala SLAY_COMT'),
|
||||
(22951,5,0,'Destiny... awaits.',14,0,100,0,0,11485,21715,0,'council mala DEATH'),
|
||||
(22950,2,1,'Sha\'amoor ara mashal?',14,0,100,0,0,11445,21731,0,'council zere SPECIAL2'),
|
||||
(22950,3,0,'Shorel\'aran.',14,0,100,0,0,11441,21725,0,'council zere SLAY'),
|
||||
(22950,4,0,'Belesa menoor!',14,0,100,0,0,11442,21727,0,'council zere SLAY_COMT'),
|
||||
(22950,5,0,'Diel ma\'ahn... orindel\'o.',14,0,100,0,0,11443,21729,0,'council zere DEATH'),
|
||||
(22952,2,1,'Anar\'alah belore!',14,0,100,0,0,11529,21705,0,'council vera SPECIAL2'),
|
||||
(22952,3,0,'Valiant effort.',14,0,100,0,0,11525,21699,0,'council vera SLAY'),
|
||||
(22952,4,0,'A glorious kill!',14,0,100,0,0,11526,21701,0,'council vera SLAY_COMT'),
|
||||
(22952,5,0,'You got... lucky.',14,0,100,0,0,11527,21703,0,'council vera DEATH');
|
||||
@@ -2674,8 +2674,11 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(685904631, 1151048, 0, 0);
|
||||
});
|
||||
|
||||
// Death and Decay
|
||||
ApplySpellFix({ 52212 }, [](SpellInfo* spellInfo)
|
||||
ApplySpellFix({
|
||||
52212, // Death and Decay
|
||||
41485, // Deadly Poison - Black Temple
|
||||
41487 // Envenom - Black Temple
|
||||
}, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->AttributesEx6 |= SPELL_ATTR6_CAN_TARGET_INVISIBLE;
|
||||
});
|
||||
|
||||
959
src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp
Normal file
959
src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp
Normal file
@@ -0,0 +1,959 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "black_temple.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "InstanceScript.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_COUNCIL_AGRO = 0,
|
||||
SAY_COUNCIL_ENRAGE = 1,
|
||||
SAY_COUNCIL_SPECIAL = 2,
|
||||
SAY_COUNCIL_SLAY = 3,
|
||||
SAY_COUNCIL_COMNT = 4,
|
||||
SAY_COUNCIL_DEATH = 5
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Illidari Council (Trigger)
|
||||
SPELL_EMPYREAL_BALANCE = 41499,
|
||||
SPELL_EMPYREAL_EQUIVALENCY = 41333,
|
||||
|
||||
// Generic
|
||||
SPELL_SHARED_RULE = 41342,
|
||||
SPELL_BERSERK = 45078,
|
||||
SPELL_BALANCE_OF_POWER = 41341,
|
||||
SPELL_QUIET_SUICIDE = 3617, // Serverside spell
|
||||
|
||||
// High Nethermancer Zerevor's
|
||||
SPELL_FLAMESTRIKE = 41481,
|
||||
SPELL_BLIZZARD = 41482,
|
||||
SPELL_ARCANE_BOLT = 41483,
|
||||
SPELL_ARCANE_EXPLOSION = 41524,
|
||||
SPELL_DAMPEN_MAGIC = 41478,
|
||||
|
||||
// Lady Malande's
|
||||
SPELL_EMPOWERED_SMITE = 41471,
|
||||
SPELL_CIRCLE_OF_HEALING = 41455,
|
||||
SPELL_REFLECTIVE_SHIELD = 41475,
|
||||
SPELL_REFLECTIVE_SHIELD_DAMAGE = 33619,
|
||||
SPELL_DIVINE_WRATH = 41472,
|
||||
|
||||
// Gathios the Shatterer's
|
||||
SPELL_BLESS_PROTECTION = 41450,
|
||||
SPELL_BLESS_SPELL_WARDING = 41451,
|
||||
SPELL_CONSECRATION = 41541,
|
||||
SPELL_HAMMER_OF_JUSTICE = 41468,
|
||||
SPELL_SEAL_OF_COMMAND = 41469,
|
||||
SPELL_SEAL_OF_BLOOD = 41459,
|
||||
SPELL_CHROMATIC_AURA = 41453,
|
||||
SPELL_DEVOTION_AURA = 41452,
|
||||
SPELL_JUDGEMENT_PRIMER = 41473,
|
||||
SPELL_JUDGEMENT = 41467,
|
||||
SPELL_JUDGEMENT_OF_COMMAND = 41470,
|
||||
SPELL_JUDGEMENT_OF_BLOOD = 41461,
|
||||
|
||||
// Veras Darkshadow's
|
||||
SPELL_DEADLY_STRIKE = 41480,
|
||||
SPELL_DEADLY_POISON = 41485,
|
||||
SPELL_ENVENOM = 41487,
|
||||
SPELL_VANISH = 41476,
|
||||
|
||||
// Veras Vanish Effect
|
||||
SPELL_BIRTH = 40031,
|
||||
SPELL_ENVENOM_DUMMY = 41510
|
||||
};
|
||||
|
||||
enum IllidariEvents
|
||||
{
|
||||
EVENT_EMPYREAL_EQUIVALENCY = 1,
|
||||
EVENT_VANISH,
|
||||
EVENT_DEADLY_STRIKE,
|
||||
EVENT_FLAMESTRIKE,
|
||||
EVENT_BLIZZARD,
|
||||
EVENT_ARCANE_EXPLOSION,
|
||||
EVENT_ARCANE_EXPLOSION_CHECK,
|
||||
EVENT_DAMPEN_MAGIC,
|
||||
EVENT_BLESS,
|
||||
EVENT_CONSECRATION,
|
||||
EVENT_AURA,
|
||||
EVENT_JUDGEMENT,
|
||||
EVENT_HAMMER_OF_JUSTICE,
|
||||
EVENT_CIRCLE_OF_HEALING,
|
||||
EVENT_REFLECTIVE_SHIELD,
|
||||
EVENT_DIVINE_WRATH,
|
||||
EVENT_BERSERK
|
||||
};
|
||||
|
||||
enum IllidariMisc
|
||||
{
|
||||
SUMMON_COUNCIL_GROUP = 1,
|
||||
ACTION_REFRESH_DAMPEN
|
||||
};
|
||||
|
||||
uint32 const CouncilData[4] =
|
||||
{
|
||||
DATA_GATHIOS_THE_SHATTERER,
|
||||
DATA_HIGH_NETHERMANCER_ZEREVOR,
|
||||
DATA_LADY_MALANDE,
|
||||
DATA_VERAS_DARKSHADOW
|
||||
};
|
||||
|
||||
static uint32 GetRandomBossExcept(uint32 exception)
|
||||
{
|
||||
std::vector<uint32> bossData;
|
||||
for (uint32 data : CouncilData)
|
||||
if (data != exception)
|
||||
bossData.emplace_back(data);
|
||||
|
||||
return bossData[urand(0, 3)];
|
||||
}
|
||||
|
||||
class boss_illidari_council : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_illidari_council() : CreatureScript("boss_illidari_council") { }
|
||||
|
||||
struct boss_illidari_councilAI : public BossAI
|
||||
{
|
||||
boss_illidari_councilAI(Creature* creature) : BossAI(creature, DATA_ILLIDARI_COUNCIL), _inCombat(false) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
_inCombat = false;
|
||||
me->SummonCreatureGroup(SUMMON_COUNCIL_GROUP);
|
||||
DoCastSelf(SPELL_EMPYREAL_BALANCE, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
if (!_inCombat)
|
||||
{
|
||||
_inCombat = true;
|
||||
_EnterCombat();
|
||||
for (uint32 bossData : CouncilData)
|
||||
{
|
||||
if (Creature* council = instance->GetCreature(bossData))
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, council);
|
||||
DoZoneInCombat(council);
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_EMPYREAL_EQUIVALENCY, Seconds(2));
|
||||
events.ScheduleEvent(EVENT_BERSERK, Minutes(15));
|
||||
if (Creature* council = instance->GetCreature(CouncilData[urand(0, 3)]))
|
||||
council->AI()->Talk(SAY_COUNCIL_AGRO);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
if (!me->IsInEvadeMode())
|
||||
{
|
||||
_inCombat = false;
|
||||
for (uint32 bossData : CouncilData)
|
||||
if (Creature* council = instance->GetCreature(bossData))
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council);
|
||||
|
||||
summons.DespawnAll();
|
||||
_DespawnAtEvade();
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_inCombat = false;
|
||||
events.Reset();
|
||||
instance->SetBossState(DATA_ILLIDARI_COUNCIL, DONE);
|
||||
|
||||
for (uint32 bossData : CouncilData)
|
||||
{
|
||||
if (Creature* council = instance->GetCreature(bossData))
|
||||
{
|
||||
// Allow loot
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, council);
|
||||
council->LowerPlayerDamageReq(council->GetMaxHealth());
|
||||
council->CastSpell(council, SPELL_QUIET_SUICIDE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_EMPYREAL_EQUIVALENCY:
|
||||
DoCastSelf(SPELL_EMPYREAL_EQUIVALENCY, true);
|
||||
events.Repeat(Seconds(2));
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
for (uint32 bossData : CouncilData)
|
||||
{
|
||||
if (Creature* council = instance->GetCreature(bossData))
|
||||
{
|
||||
council->CastSpell(council, SPELL_BERSERK, true);
|
||||
council->AI()->Talk(SAY_COUNCIL_ENRAGE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool _inCombat;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_illidari_councilAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
struct IllidariCouncilBossAI : public BossAI
|
||||
{
|
||||
IllidariCouncilBossAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId), _bossId(bossId)
|
||||
{
|
||||
SetBoundary(instance->GetBossBoundary(DATA_ILLIDARI_COUNCIL));
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetCombatPulseDelay(0);
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
me->SetCombatPulseDelay(5);
|
||||
me->setActive(true);
|
||||
if (Creature* illidari = instance->GetCreature(DATA_ILLIDARI_COUNCIL))
|
||||
DoZoneInCombat(illidari);
|
||||
ScheduleTasks();
|
||||
}
|
||||
|
||||
virtual void ScheduleTasks() = 0;
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_COUNCIL_DEATH);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
if (Creature* illidari = instance->GetCreature(DATA_ILLIDARI_COUNCIL))
|
||||
illidari->AI()->EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32 &damage) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID())
|
||||
damage = me->GetHealth() - 1;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_COUNCIL_SLAY);
|
||||
|
||||
if (roll_chance_i(30))
|
||||
if (Creature* boss = instance->GetCreature(GetRandomBossExcept(_bossId)))
|
||||
boss->AI()->Talk(SAY_COUNCIL_COMNT);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _bossId;
|
||||
};
|
||||
|
||||
class HammerTargetSelector : public std::unary_function<Unit*, bool>
|
||||
{
|
||||
public:
|
||||
HammerTargetSelector(Unit const* unit) : _me(unit) { }
|
||||
|
||||
bool operator()(Unit* unit) const
|
||||
{
|
||||
return _me->IsInRange(unit, 10.0f, 40.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
Unit const* _me;
|
||||
};
|
||||
|
||||
class boss_gathios_the_shatterer : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_gathios_the_shatterer() : CreatureScript("boss_gathios_the_shatterer") { }
|
||||
|
||||
struct boss_gathios_the_shattererAI : public IllidariCouncilBossAI
|
||||
{
|
||||
boss_gathios_the_shattererAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_GATHIOS_THE_SHATTERER) { }
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
DoCastSelf(SPELL_SEAL_OF_BLOOD);
|
||||
events.ScheduleEvent(EVENT_BLESS, Seconds(20));
|
||||
events.ScheduleEvent(EVENT_CONSECRATION, Seconds(10));
|
||||
events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, Seconds(10));
|
||||
events.ScheduleEvent(EVENT_JUDGEMENT, Seconds(15));
|
||||
events.ScheduleEvent(EVENT_AURA, Seconds(6));
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BLESS:
|
||||
{
|
||||
std::list<Unit*> TargetList;
|
||||
Trinity::AnyFriendlyUnitInObjectRangeCheck checker(me, me, 100.0f);
|
||||
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(me, TargetList, checker);
|
||||
Cell::VisitAllObjects(me, searcher, 100.0f);
|
||||
|
||||
if (!TargetList.empty())
|
||||
{
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(TargetList);
|
||||
DoCast(target, RAND(SPELL_BLESS_PROTECTION, SPELL_BLESS_SPELL_WARDING));
|
||||
}
|
||||
events.Repeat(Seconds(30), Seconds(45));
|
||||
break;
|
||||
}
|
||||
case EVENT_AURA:
|
||||
DoCastSelf(RAND(SPELL_CHROMATIC_AURA, SPELL_DEVOTION_AURA));
|
||||
events.Repeat(Seconds(30));
|
||||
break;
|
||||
case EVENT_HAMMER_OF_JUSTICE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, HammerTargetSelector(me)))
|
||||
DoCast(target, SPELL_HAMMER_OF_JUSTICE);
|
||||
events.Repeat(Seconds(20));
|
||||
break;
|
||||
case EVENT_JUDGEMENT:
|
||||
DoCastVictim(SPELL_JUDGEMENT);
|
||||
events.Repeat(Seconds(15));
|
||||
break;
|
||||
case EVENT_CONSECRATION:
|
||||
DoCastSelf(SPELL_CONSECRATION);
|
||||
events.Repeat(Seconds(30), Seconds(35));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_gathios_the_shattererAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class boss_high_nethermancer_zerevor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_high_nethermancer_zerevor() : CreatureScript("boss_high_nethermancer_zerevor") { }
|
||||
|
||||
struct boss_high_nethermancer_zerevorAI : public IllidariCouncilBossAI
|
||||
{
|
||||
boss_high_nethermancer_zerevorAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_HIGH_NETHERMANCER_ZEREVOR), _canUseArcaneExplosion(true) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
IllidariCouncilBossAI::Reset();
|
||||
_canUseArcaneExplosion = true;
|
||||
DoCastSelf(SPELL_DAMPEN_MAGIC);
|
||||
}
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_FLAMESTRIKE, Seconds(8));
|
||||
events.ScheduleEvent(EVENT_BLIZZARD, Seconds(25));
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, Seconds(5));
|
||||
DoCastSelf(SPELL_DAMPEN_MAGIC);
|
||||
}
|
||||
|
||||
void DoAction(int32 actionId) override
|
||||
{
|
||||
if (actionId == ACTION_REFRESH_DAMPEN)
|
||||
events.ScheduleEvent(EVENT_DAMPEN_MAGIC, Seconds(50));
|
||||
}
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FLAMESTRIKE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_FLAMESTRIKE);
|
||||
Talk(SAY_COUNCIL_SPECIAL);
|
||||
events.Repeat(Seconds(40));
|
||||
break;
|
||||
case EVENT_BLIZZARD:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_BLIZZARD);
|
||||
events.Repeat(Seconds(15), Seconds(40));
|
||||
break;
|
||||
case EVENT_ARCANE_EXPLOSION_CHECK:
|
||||
_canUseArcaneExplosion = true;
|
||||
break;
|
||||
case EVENT_ARCANE_EXPLOSION:
|
||||
if (_canUseArcaneExplosion && SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f))
|
||||
{
|
||||
DoCastSelf(SPELL_ARCANE_EXPLOSION);
|
||||
_canUseArcaneExplosion = false;
|
||||
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_CHECK, Seconds(5));
|
||||
}
|
||||
events.Repeat(Seconds(1));
|
||||
break;
|
||||
case EVENT_DAMPEN_MAGIC:
|
||||
DoCastSelf(SPELL_DAMPEN_MAGIC);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
ExecuteEvent(eventId);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoSpellAttackIfReady(SPELL_ARCANE_BOLT);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _canUseArcaneExplosion;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_high_nethermancer_zerevorAI>(creature);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class boss_lady_malande : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_lady_malande() : CreatureScript("boss_lady_malande") { }
|
||||
|
||||
struct boss_lady_malandeAI : public IllidariCouncilBossAI
|
||||
{
|
||||
boss_lady_malandeAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_LADY_MALANDE) { }
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CIRCLE_OF_HEALING, Seconds(20));
|
||||
events.ScheduleEvent(EVENT_REFLECTIVE_SHIELD, Seconds(25));
|
||||
events.ScheduleEvent(EVENT_DIVINE_WRATH, Seconds(32));
|
||||
}
|
||||
|
||||
void HealReceived(Unit* /*who*/, uint32& addhealth) override
|
||||
{
|
||||
// Need be negative to heal trigger
|
||||
int32 bp = addhealth * (-1);
|
||||
me->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true);
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CIRCLE_OF_HEALING:
|
||||
DoCastSelf(SPELL_CIRCLE_OF_HEALING);
|
||||
events.Repeat(Seconds(20), Seconds(35));
|
||||
break;
|
||||
case EVENT_REFLECTIVE_SHIELD:
|
||||
DoCastSelf(SPELL_REFLECTIVE_SHIELD);
|
||||
Talk(SAY_COUNCIL_SPECIAL);
|
||||
events.Repeat(Seconds(40));
|
||||
break;
|
||||
case EVENT_DIVINE_WRATH:
|
||||
DoCastVictim(SPELL_DIVINE_WRATH);
|
||||
events.Repeat(Seconds(20));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
ExecuteEvent(eventId);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoSpellAttackIfReady(SPELL_EMPOWERED_SMITE);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_lady_malandeAI>(creature);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class boss_veras_darkshadow : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_veras_darkshadow() : CreatureScript("boss_veras_darkshadow") { }
|
||||
|
||||
struct boss_veras_darkshadowAI : public IllidariCouncilBossAI
|
||||
{
|
||||
boss_veras_darkshadowAI(Creature* creature) : IllidariCouncilBossAI(creature, DATA_VERAS_DARKSHADOW)
|
||||
{
|
||||
me->SetMaxHealth(1327900);
|
||||
me->SetFullHealth();
|
||||
}
|
||||
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_DEADLY_STRIKE, Seconds(18));
|
||||
events.ScheduleEvent(EVENT_VANISH, Seconds(18));
|
||||
}
|
||||
|
||||
void ExecuteEvent(uint32 eventId) override
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DEADLY_STRIKE:
|
||||
DoCastSelf(SPELL_DEADLY_STRIKE);
|
||||
events.Repeat(Seconds(60));
|
||||
break;
|
||||
case EVENT_VANISH:
|
||||
DoCastSelf(SPELL_VANISH);
|
||||
Talk(SAY_COUNCIL_SPECIAL);
|
||||
events.Repeat(Seconds(60));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_veras_darkshadowAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_veras_vanish_effect : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_veras_vanish_effect() : CreatureScript("npc_veras_vanish_effect") { }
|
||||
|
||||
struct npc_veras_vanish_effectAI : public PassiveAI
|
||||
{
|
||||
npc_veras_vanish_effectAI(Creature* creature) : PassiveAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
DoCastSelf(SPELL_BIRTH, true);
|
||||
DoCastSelf(SPELL_ENVENOM_DUMMY, true);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<npc_veras_vanish_effectAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// 41499 - Empyreal Balance
|
||||
class spell_illidari_council_empyreal_balance : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_empyreal_balance() : SpellScriptLoader("spell_illidari_council_empyreal_balance") { }
|
||||
|
||||
class spell_illidari_council_empyreal_balance_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_illidari_council_empyreal_balance_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_BALANCE_OF_POWER });
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* target = GetHitUnit();
|
||||
target->CastSpell(target, SPELL_BALANCE_OF_POWER, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_balance_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_illidari_council_empyreal_balance_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41333 - Empyreal Equivalency
|
||||
class spell_illidari_council_empyreal_equivalency : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_empyreal_equivalency() : SpellScriptLoader("spell_illidari_council_empyreal_equivalency") { }
|
||||
|
||||
class spell_illidari_council_empyreal_equivalency_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_illidari_council_empyreal_equivalency_SpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* target = GetHitUnit();
|
||||
int32 casterHpPct = (int32) GetCaster()->GetHealthPct();
|
||||
uint32 newHp = target->CountPctFromMaxHealth(casterHpPct);
|
||||
if (newHp <= 0)
|
||||
newHp = target->GetMaxHealth() - 1;
|
||||
target->SetHealth(newHp);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_illidari_council_empyreal_equivalency_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_illidari_council_empyreal_equivalency_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41341 - Balance of Power
|
||||
class spell_illidari_council_balance_of_power : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_balance_of_power() : SpellScriptLoader("spell_illidari_council_balance_of_power") { }
|
||||
|
||||
class spell_illidari_council_balance_of_power_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_illidari_council_balance_of_power_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_SHARED_RULE });
|
||||
}
|
||||
|
||||
void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& /*absorbAmount*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
int32 bp = dmgInfo.GetDamage();
|
||||
GetTarget()->CastCustomSpell(SPELL_SHARED_RULE, SPELLVALUE_BASE_POINT0, bp, (Unit*) nullptr, true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_balance_of_power_AuraScript::Absorb, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_illidari_council_balance_of_power_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41480 - Deadly Strike
|
||||
class spell_illidari_council_deadly_strike : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_deadly_strike() : SpellScriptLoader("spell_illidari_council_deadly_strike") { }
|
||||
|
||||
class spell_illidari_council_deadly_strike_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_illidari_council_deadly_strike_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_DEADLY_POISON });
|
||||
}
|
||||
|
||||
void OnTrigger(AuraEffect const* aurEff)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
if (Unit* victim = GetTarget()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
GetTarget()->CastSpell(victim, SPELL_DEADLY_POISON, true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidari_council_deadly_strike_AuraScript::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_illidari_council_deadly_strike_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41485 - Deadly Poison
|
||||
class spell_illidari_council_deadly_poison : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_deadly_poison() : SpellScriptLoader("spell_illidari_council_deadly_poison") { }
|
||||
|
||||
class spell_illidari_council_deadly_poison_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_illidari_council_deadly_poison_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_ENVENOM });
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastSpell(GetTarget(), SPELL_ENVENOM, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_deadly_poison_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_illidari_council_deadly_poison_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41475 - Reflective Shield
|
||||
class spell_illidari_council_reflective_shield : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_reflective_shield() : SpellScriptLoader("spell_illidari_council_reflective_shield") { }
|
||||
|
||||
class spell_illidari_council_reflective_shield_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_illidari_council_reflective_shield_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_DAMAGE });
|
||||
}
|
||||
|
||||
void OnAbsorb(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (dmgInfo.GetAttacker() == target)
|
||||
return;
|
||||
|
||||
int32 bp = absorbAmount / 2;
|
||||
target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_DAMAGE, &bp, nullptr, nullptr, true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectAbsorb += AuraEffectAbsorbFn(spell_illidari_council_reflective_shield_AuraScript::OnAbsorb, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_illidari_council_reflective_shield_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41467 - Judgement
|
||||
class spell_illidari_council_judgement : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_judgement() : SpellScriptLoader("spell_illidari_council_judgement") { }
|
||||
|
||||
class spell_illidari_council_judgement_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_illidari_council_judgement_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo(
|
||||
{
|
||||
SPELL_JUDGEMENT_OF_BLOOD,
|
||||
SPELL_JUDGEMENT_OF_COMMAND,
|
||||
SPELL_JUDGEMENT_PRIMER
|
||||
});
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetHitUnit();
|
||||
uint32 judgementId = caster->HasAura(SPELL_SEAL_OF_BLOOD) ? SPELL_JUDGEMENT_OF_BLOOD : SPELL_JUDGEMENT_OF_COMMAND;
|
||||
caster->CastSpell(target, SPELL_JUDGEMENT_PRIMER, true);
|
||||
caster->CastSpell(target, judgementId, true);
|
||||
}
|
||||
|
||||
void OnFinishCast()
|
||||
{
|
||||
if (Creature* caster = GetCaster()->ToCreature())
|
||||
caster->AI()->Talk(SAY_COUNCIL_SPECIAL);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_illidari_council_judgement_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
AfterCast += SpellCastFn(spell_illidari_council_judgement_SpellScript::OnFinishCast);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_illidari_council_judgement_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
/* 41469 - Seal of Command
|
||||
41459 - Seal of Blood */
|
||||
class spell_illidari_council_seal : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_council_seal() : SpellScriptLoader("spell_illidari_council_seal") { }
|
||||
|
||||
class spell_illidari_council_seal_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_illidari_council_seal_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_SEAL_OF_COMMAND, SPELL_SEAL_OF_BLOOD });
|
||||
}
|
||||
|
||||
void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (target->IsInWorld() && target->IsAlive())
|
||||
{
|
||||
uint32 spellId = aurEff->GetId() == SPELL_SEAL_OF_COMMAND ? SPELL_SEAL_OF_BLOOD : SPELL_SEAL_OF_COMMAND;
|
||||
target->CastSpell(target, spellId, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_illidari_council_seal_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_illidari_council_seal_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
// 41478 - Dampen Magic
|
||||
class spell_illidari_dampen_magic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_illidari_dampen_magic() : SpellScriptLoader("spell_illidari_dampen_magic") { }
|
||||
|
||||
class spell_illidari_dampen_magic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_illidari_dampen_magic_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Creature* target = GetTarget()->ToCreature())
|
||||
{
|
||||
AuraRemoveMode mode = GetTargetApplication()->GetRemoveMode();
|
||||
if (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE)
|
||||
target->AI()->DoAction(ACTION_REFRESH_DAMPEN);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_illidari_dampen_magic_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_illidari_dampen_magic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_illidari_council()
|
||||
{
|
||||
new boss_illidari_council();
|
||||
new boss_gathios_the_shatterer();
|
||||
new boss_lady_malande();
|
||||
new boss_veras_darkshadow();
|
||||
new boss_high_nethermancer_zerevor();
|
||||
new npc_veras_vanish_effect();
|
||||
new spell_illidari_council_empyreal_balance();
|
||||
new spell_illidari_council_empyreal_equivalency();
|
||||
new spell_illidari_council_balance_of_power();
|
||||
new spell_illidari_council_deadly_strike();
|
||||
new spell_illidari_council_deadly_poison();
|
||||
new spell_illidari_council_reflective_shield();
|
||||
new spell_illidari_council_judgement();
|
||||
new spell_illidari_council_seal();
|
||||
new spell_illidari_dampen_magic();
|
||||
}
|
||||
@@ -1,950 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Illidari_Council
|
||||
SD%Complete: 95
|
||||
SDComment: Circle of Healing not working properly.
|
||||
SDCategory: Black Temple
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "black_temple.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "MotionMaster.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum IllidariCouncil
|
||||
{
|
||||
//Speech'n'Sounds
|
||||
SAY_GATH_SPECIAL1 = 2,
|
||||
SAY_GATH_SPECIAL2 = 3,
|
||||
SAY_GATH_SLAY = 4,
|
||||
SAY_GATH_COMNT = 5,
|
||||
SAY_GATH_DEATH = 6,
|
||||
|
||||
SAY_MALA_SPECIAL1 = 2,
|
||||
SAY_MALA_SPECIAL2 = 3,
|
||||
SAY_MALA_SLAY = 4,
|
||||
SAY_MALA_COMNT = 5,
|
||||
SAY_MALA_DEATH = 6,
|
||||
|
||||
SAY_ZERE_SPECIAL1 = 2,
|
||||
SAY_ZERE_SPECIAL2 = 3,
|
||||
SAY_ZERE_SLAY = 4,
|
||||
SAY_ZERE_COMNT = 5,
|
||||
SAY_ZERE_DEATH = 6,
|
||||
|
||||
SAY_VERA_SPECIAL1 = 2,
|
||||
SAY_VERA_SPECIAL2 = 3,
|
||||
SAY_VERA_SLAY = 4,
|
||||
SAY_VERA_COMNT = 5,
|
||||
SAY_VERA_DEATH = 6,
|
||||
|
||||
AKAMAID = 23089,
|
||||
|
||||
// High Nethermancer Zerevor's spells
|
||||
SPELL_FLAMESTRIKE = 41481,
|
||||
SPELL_BLIZZARD = 41482,
|
||||
SPELL_ARCANE_BOLT = 41483,
|
||||
SPELL_ARCANE_EXPLOSION = 41524,
|
||||
SPELL_DAMPEN_MAGIC = 41478,
|
||||
|
||||
// Lady Malande's spells
|
||||
SPELL_EMPOWERED_SMITE = 41471,
|
||||
SPELL_CIRCLE_OF_HEALING = 41455,
|
||||
SPELL_REFLECTIVE_SHIELD = 41475,
|
||||
SPELL_REFLECTIVE_SHIELD_T = 33619,
|
||||
SPELL_DIVINE_WRATH = 41472,
|
||||
SPELL_HEAL_VISUAL = 24171,
|
||||
|
||||
// Gathios the Shatterer's spells
|
||||
SPELL_BLESS_PROTECTION = 41450,
|
||||
SPELL_BLESS_SPELLWARD = 41451,
|
||||
SPELL_CONSECRATION = 41541,
|
||||
SPELL_HAMMER_OF_JUSTICE = 41468,
|
||||
SPELL_SEAL_OF_COMMAND = 41469,
|
||||
SPELL_SEAL_OF_BLOOD = 41459,
|
||||
SPELL_CHROMATIC_AURA = 41453,
|
||||
SPELL_DEVOTION_AURA = 41452,
|
||||
|
||||
// Veras Darkshadow's spells
|
||||
SPELL_DEADLY_POISON = 41485,
|
||||
SPELL_ENVENOM = 41487,
|
||||
SPELL_VANISH = 41479,
|
||||
SPELL_BERSERK = 45078
|
||||
};
|
||||
|
||||
struct CouncilYells
|
||||
{
|
||||
int32 entry;
|
||||
uint32 timer;
|
||||
};
|
||||
|
||||
static CouncilYells CouncilAggro[]=
|
||||
{
|
||||
{0, 5000}, // Gathios
|
||||
{0, 5500}, // Veras
|
||||
{0, 5000}, // Malande
|
||||
{0, 0}, // Zerevor
|
||||
};
|
||||
|
||||
// Need to get proper timers for this later
|
||||
static CouncilYells CouncilEnrage[]=
|
||||
{
|
||||
{1, 2000}, // Gathios
|
||||
{1, 6000}, // Veras
|
||||
{1, 5000}, // Malande
|
||||
{1, 0}, // Zerevor
|
||||
};
|
||||
|
||||
class npc_blood_elf_council_voice_trigger : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_blood_elf_council_voice_trigger() : CreatureScript("npc_blood_elf_council_voice_trigger") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* c) const override
|
||||
{
|
||||
return GetBlackTempleAI<npc_blood_elf_council_voice_triggerAI>(c);
|
||||
}
|
||||
|
||||
struct npc_blood_elf_council_voice_triggerAI : public ScriptedAI
|
||||
{
|
||||
npc_blood_elf_council_voice_triggerAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
EnrageTimer = 900000; // 15 minutes
|
||||
AggroYellTimer = 500;
|
||||
|
||||
YellCounter = 0;
|
||||
|
||||
EventStarted = false;
|
||||
}
|
||||
|
||||
ObjectGuid Council[4];
|
||||
|
||||
uint32 EnrageTimer;
|
||||
uint32 AggroYellTimer;
|
||||
|
||||
uint8 YellCounter; // Serves as the counter for both the aggro and enrage yells
|
||||
|
||||
bool EventStarted;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
// finds and stores the GUIDs for each Council member using instance data system.
|
||||
void LoadCouncilGUIDs()
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
{
|
||||
Council[0] = instance->GetGuidData(DATA_GATHIOS_THE_SHATTERER);
|
||||
Council[1] = instance->GetGuidData(DATA_VERAS_DARKSHADOW);
|
||||
Council[2] = instance->GetGuidData(DATA_LADY_MALANDE);
|
||||
Council[3] = instance->GetGuidData(DATA_HIGH_NETHERMANCER_ZEREVOR);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
|
||||
void AttackStart(Unit* /*who*/) override { }
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!EventStarted)
|
||||
return;
|
||||
|
||||
if (YellCounter > 3)
|
||||
return;
|
||||
|
||||
if (AggroYellTimer)
|
||||
{
|
||||
if (AggroYellTimer <= diff)
|
||||
{
|
||||
if (Creature* pMember = ObjectAccessor::GetCreature(*me, Council[YellCounter]))
|
||||
{
|
||||
pMember->AI()->Talk(CouncilAggro[YellCounter].entry);
|
||||
AggroYellTimer = CouncilAggro[YellCounter].timer;
|
||||
}
|
||||
++YellCounter;
|
||||
if (YellCounter > 3)
|
||||
YellCounter = 0; // Reuse for Enrage Yells
|
||||
} else AggroYellTimer -= diff;
|
||||
}
|
||||
|
||||
if (EnrageTimer)
|
||||
{
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
if (Creature* pMember = ObjectAccessor::GetCreature(*me, Council[YellCounter]))
|
||||
{
|
||||
pMember->CastSpell(pMember, SPELL_BERSERK, true);
|
||||
pMember->AI()->Talk(CouncilEnrage[YellCounter].entry);
|
||||
EnrageTimer = CouncilEnrage[YellCounter].timer;
|
||||
}
|
||||
++YellCounter;
|
||||
} else EnrageTimer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_illidari_council : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_illidari_council() : CreatureScript("npc_illidari_council") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<npc_illidari_councilAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_illidari_councilAI : public ScriptedAI
|
||||
{
|
||||
npc_illidari_councilAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
SetBoundary(instance->GetBossBoundary(DATA_ILLIDARI_COUNCIL));
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
CheckTimer = 2000;
|
||||
EndEventTimer = 0;
|
||||
|
||||
DeathCount = 0;
|
||||
EventBegun = false;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
ObjectGuid Council[4];
|
||||
|
||||
uint32 CheckTimer;
|
||||
uint32 EndEventTimer;
|
||||
|
||||
uint8 DeathCount;
|
||||
|
||||
bool EventBegun;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
|
||||
Creature* pMember = nullptr;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
pMember = ObjectAccessor::GetCreature((*me), Council[i]);
|
||||
if (!pMember)
|
||||
continue;
|
||||
|
||||
if (!pMember->IsAlive())
|
||||
{
|
||||
pMember->RemoveCorpse();
|
||||
pMember->Respawn();
|
||||
}
|
||||
pMember->AI()->EnterEvadeMode();
|
||||
}
|
||||
|
||||
instance->SetBossState(DATA_ILLIDARI_COUNCIL, NOT_STARTED);
|
||||
if (Creature* VoiceTrigger = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_ELF_COUNCIL_VOICE)))
|
||||
VoiceTrigger->AI()->EnterEvadeMode();
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetDisplayId(11686);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
void AttackStart(Unit* /*who*/) override { }
|
||||
void MoveInLineOfSight(Unit* /*who*/) override { }
|
||||
|
||||
|
||||
void StartEvent(Unit* target)
|
||||
{
|
||||
if (target && target->IsAlive())
|
||||
{
|
||||
Council[0] = instance->GetGuidData(DATA_GATHIOS_THE_SHATTERER);
|
||||
Council[1] = instance->GetGuidData(DATA_HIGH_NETHERMANCER_ZEREVOR);
|
||||
Council[2] = instance->GetGuidData(DATA_LADY_MALANDE);
|
||||
Council[3] = instance->GetGuidData(DATA_VERAS_DARKSHADOW);
|
||||
|
||||
// Start the event for the Voice Trigger
|
||||
if (Creature* VoiceTrigger = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_ELF_COUNCIL_VOICE)))
|
||||
{
|
||||
ENSURE_AI(npc_blood_elf_council_voice_trigger::npc_blood_elf_council_voice_triggerAI, VoiceTrigger->AI())->LoadCouncilGUIDs();
|
||||
ENSURE_AI(npc_blood_elf_council_voice_trigger::npc_blood_elf_council_voice_triggerAI, VoiceTrigger->AI())->EventStarted = true;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (!Council[i].IsEmpty())
|
||||
{
|
||||
if (Creature* member = ObjectAccessor::GetCreature(*me, Council[i]))
|
||||
if (member->IsAlive())
|
||||
member->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
instance->SetBossState(DATA_ILLIDARI_COUNCIL, IN_PROGRESS);
|
||||
|
||||
EventBegun = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!EventBegun)
|
||||
return;
|
||||
|
||||
if (EndEventTimer)
|
||||
{
|
||||
if (EndEventTimer <= diff)
|
||||
{
|
||||
if (DeathCount > 3)
|
||||
{
|
||||
if (Creature* VoiceTrigger = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BLOOD_ELF_COUNCIL_VOICE)))
|
||||
VoiceTrigger->DealDamage(VoiceTrigger, VoiceTrigger->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
|
||||
instance->SetBossState(DATA_ILLIDARI_COUNCIL, DONE);
|
||||
//me->SummonCreature(AKAMAID, 746.466980f, 304.394989f, 311.90208f, 6.272870f, TEMPSUMMON_DEAD_DESPAWN, 0);
|
||||
me->DealDamage(me, me->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
|
||||
return;
|
||||
}
|
||||
|
||||
Creature* pMember = (ObjectAccessor::GetCreature(*me, Council[DeathCount]));
|
||||
if (pMember && pMember->IsAlive())
|
||||
pMember->DealDamage(pMember, pMember->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);
|
||||
++DeathCount;
|
||||
EndEventTimer = 1500;
|
||||
} else EndEventTimer -= diff;
|
||||
}
|
||||
|
||||
if (CheckTimer)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
uint8 EvadeCheck = 0;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (!Council[i].IsEmpty())
|
||||
{
|
||||
if (Creature* Member = (ObjectAccessor::GetCreature((*me), Council[i])))
|
||||
{
|
||||
// This is the evade/death check.
|
||||
if (Member->IsAlive() && !Member->GetVictim())
|
||||
++EvadeCheck; //If all members evade, we reset so that players can properly reset the event
|
||||
else if (!Member->IsAlive()) // If even one member dies, kill the rest, set instance data, and kill self.
|
||||
{
|
||||
EndEventTimer = 1000;
|
||||
CheckTimer = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (EvadeCheck > 3)
|
||||
Reset();
|
||||
|
||||
CheckTimer = 2000;
|
||||
} else CheckTimer -= diff;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
struct boss_illidari_councilAI : public ScriptedAI
|
||||
{
|
||||
boss_illidari_councilAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
LoadedGUIDs = false;
|
||||
}
|
||||
|
||||
ObjectGuid Council[4];
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
bool LoadedGUIDs;
|
||||
|
||||
void EnterCombat(Unit* who) override
|
||||
{
|
||||
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ILLIDARI_COUNCIL)))
|
||||
ENSURE_AI(npc_illidari_council::npc_illidari_councilAI, controller->AI())->StartEvent(who);
|
||||
DoZoneInCombat();
|
||||
// Load GUIDs on first aggro because the Creature guids are only set as the creatures are created in world-
|
||||
// this means that for each creature, it will attempt to LoadGUIDs even though some of the other creatures are
|
||||
// not in world, and thus have no GUID set in the instance data system. Putting it in aggro ensures that all the creatures
|
||||
// have been loaded and have their GUIDs set in the instance data system.
|
||||
if (!LoadedGUIDs)
|
||||
LoadGUIDs();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (Unit* unit = ObjectAccessor::GetUnit(*me, Council[i]))
|
||||
if (unit != me && unit->GetVictim())
|
||||
{
|
||||
AttackStart(unit->GetVictim());
|
||||
return;
|
||||
}
|
||||
}
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* done_by, uint32 &damage) override
|
||||
{
|
||||
if (done_by == me)
|
||||
return;
|
||||
|
||||
damage /= 4;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
if (Creature* unit = ObjectAccessor::GetCreature(*me, Council[i]))
|
||||
if (unit != me && damage < unit->GetHealth())
|
||||
{
|
||||
unit->ModifyHealth(-int32(damage));
|
||||
unit->LowerPlayerDamageReq(damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadGUIDs()
|
||||
{
|
||||
Council[0] = instance->GetGuidData(DATA_LADY_MALANDE);
|
||||
Council[1] = instance->GetGuidData(DATA_HIGH_NETHERMANCER_ZEREVOR);
|
||||
Council[2] = instance->GetGuidData(DATA_GATHIOS_THE_SHATTERER);
|
||||
Council[3] = instance->GetGuidData(DATA_VERAS_DARKSHADOW);
|
||||
|
||||
LoadedGUIDs = true;
|
||||
}
|
||||
};
|
||||
|
||||
class boss_gathios_the_shatterer : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_gathios_the_shatterer() : CreatureScript("boss_gathios_the_shatterer") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_gathios_the_shattererAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_gathios_the_shattererAI : public boss_illidari_councilAI
|
||||
{
|
||||
boss_gathios_the_shattererAI(Creature* creature) : boss_illidari_councilAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
ConsecrationTimer = 40000;
|
||||
HammerOfJusticeTimer = 10000;
|
||||
SealTimer = 40000;
|
||||
AuraTimer = 90000;
|
||||
BlessingTimer = 60000;
|
||||
}
|
||||
|
||||
uint32 ConsecrationTimer;
|
||||
uint32 HammerOfJusticeTimer;
|
||||
uint32 SealTimer;
|
||||
uint32 AuraTimer;
|
||||
uint32 BlessingTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_GATH_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_GATH_DEATH);
|
||||
}
|
||||
|
||||
Unit* SelectCouncilMember()
|
||||
{
|
||||
Unit* unit = me;
|
||||
uint32 member = 0; // He chooses Lady Malande most often
|
||||
|
||||
if (rand32() % 10 == 0) // But there is a chance he picks someone else.
|
||||
member = urand(1, 3);
|
||||
|
||||
if (member != 2) // No need to create another pointer to us using Unit::GetUnit
|
||||
unit = ObjectAccessor::GetUnit(*me, Council[member]);
|
||||
return unit;
|
||||
}
|
||||
|
||||
void CastAuraOnCouncil()
|
||||
{
|
||||
uint32 spellid = 0;
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0: spellid = SPELL_DEVOTION_AURA; break;
|
||||
case 1: spellid = SPELL_CHROMATIC_AURA; break;
|
||||
}
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
Unit* unit = ObjectAccessor::GetUnit(*me, Council[i]);
|
||||
if (unit)
|
||||
unit->CastSpell(unit, spellid, true, 0, 0, me->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (BlessingTimer <= diff)
|
||||
{
|
||||
if (Unit* unit = SelectCouncilMember())
|
||||
{
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0:
|
||||
DoCast(unit, SPELL_BLESS_SPELLWARD);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DoCast(unit, SPELL_BLESS_PROTECTION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BlessingTimer = 60000;
|
||||
} else BlessingTimer -= diff;
|
||||
|
||||
if (ConsecrationTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_CONSECRATION);
|
||||
ConsecrationTimer = 40000;
|
||||
} else ConsecrationTimer -= diff;
|
||||
|
||||
if (HammerOfJusticeTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
// is in ~10-40 yd range
|
||||
if (me->IsInRange(target, 10.0f, 40.0f, false))
|
||||
{
|
||||
DoCast(target, SPELL_HAMMER_OF_JUSTICE);
|
||||
HammerOfJusticeTimer = 20000;
|
||||
}
|
||||
}
|
||||
} else HammerOfJusticeTimer -= diff;
|
||||
|
||||
if (SealTimer <= diff)
|
||||
{
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0: DoCast(me, SPELL_SEAL_OF_COMMAND); break;
|
||||
case 1: DoCast(me, SPELL_SEAL_OF_BLOOD); break;
|
||||
}
|
||||
SealTimer = 40000;
|
||||
} else SealTimer -= diff;
|
||||
|
||||
if (AuraTimer <= diff)
|
||||
{
|
||||
CastAuraOnCouncil();
|
||||
AuraTimer = 90000;
|
||||
} else AuraTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_high_nethermancer_zerevor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_high_nethermancer_zerevor() : CreatureScript("boss_high_nethermancer_zerevor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_high_nethermancer_zerevorAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_high_nethermancer_zerevorAI : public boss_illidari_councilAI
|
||||
{
|
||||
boss_high_nethermancer_zerevorAI(Creature* creature) : boss_illidari_councilAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
BlizzardTimer = urand(30, 91) * 1000;
|
||||
FlamestrikeTimer = urand(30, 91) * 1000;
|
||||
ArcaneBoltTimer = 10000;
|
||||
DampenMagicTimer = 2000;
|
||||
ArcaneExplosionTimer = 14000;
|
||||
Cooldown = 0;
|
||||
}
|
||||
|
||||
uint32 BlizzardTimer;
|
||||
uint32 FlamestrikeTimer;
|
||||
uint32 ArcaneBoltTimer;
|
||||
uint32 DampenMagicTimer;
|
||||
uint32 Cooldown;
|
||||
uint32 ArcaneExplosionTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_ZERE_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_ZERE_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Cooldown)
|
||||
{
|
||||
if (Cooldown <= diff) Cooldown = 0;
|
||||
else
|
||||
{
|
||||
Cooldown -= diff;
|
||||
return; // Don't cast any other spells if global cooldown is still ticking
|
||||
}
|
||||
}
|
||||
|
||||
if (DampenMagicTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_DAMPEN_MAGIC);
|
||||
Cooldown = 1000;
|
||||
DampenMagicTimer = 67200; // almost 1, 12 minutes
|
||||
ArcaneBoltTimer += 1000; // Give the Mage some time to spellsteal Dampen.
|
||||
} else DampenMagicTimer -= diff;
|
||||
|
||||
if (ArcaneExplosionTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_ARCANE_EXPLOSION);
|
||||
Cooldown = 1000;
|
||||
ArcaneExplosionTimer = 14000;
|
||||
} else ArcaneExplosionTimer -= diff;
|
||||
|
||||
if (ArcaneBoltTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_ARCANE_BOLT);
|
||||
ArcaneBoltTimer = 3000;
|
||||
Cooldown = 2000;
|
||||
} else ArcaneBoltTimer -= diff;
|
||||
|
||||
if (BlizzardTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_BLIZZARD);
|
||||
BlizzardTimer = urand(45, 91) * 1000;
|
||||
FlamestrikeTimer += 10000;
|
||||
Cooldown = 1000;
|
||||
}
|
||||
} else BlizzardTimer -= diff;
|
||||
|
||||
if (FlamestrikeTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_FLAMESTRIKE);
|
||||
FlamestrikeTimer = urand(55, 101) * 1000;
|
||||
BlizzardTimer += 10000;
|
||||
Cooldown = 2000;
|
||||
}
|
||||
} else FlamestrikeTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_lady_malande : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_lady_malande() : CreatureScript("boss_lady_malande") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_lady_malandeAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_lady_malandeAI : public boss_illidari_councilAI
|
||||
{
|
||||
boss_lady_malandeAI(Creature* creature) : boss_illidari_councilAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
EmpoweredSmiteTimer = 38000;
|
||||
CircleOfHealingTimer = 20000;
|
||||
DivineWrathTimer = 40000;
|
||||
ReflectiveShieldTimer = 0;
|
||||
}
|
||||
|
||||
uint32 EmpoweredSmiteTimer;
|
||||
uint32 CircleOfHealingTimer;
|
||||
uint32 DivineWrathTimer;
|
||||
uint32 ReflectiveShieldTimer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_MALA_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_MALA_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (EmpoweredSmiteTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_EMPOWERED_SMITE);
|
||||
EmpoweredSmiteTimer = 38000;
|
||||
}
|
||||
} else EmpoweredSmiteTimer -= diff;
|
||||
|
||||
if (CircleOfHealingTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_CIRCLE_OF_HEALING);
|
||||
CircleOfHealingTimer = 60000;
|
||||
} else CircleOfHealingTimer -= diff;
|
||||
|
||||
if (DivineWrathTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_DIVINE_WRATH);
|
||||
DivineWrathTimer = urand(40, 81) * 1000;
|
||||
}
|
||||
} else DivineWrathTimer -= diff;
|
||||
|
||||
if (ReflectiveShieldTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_REFLECTIVE_SHIELD);
|
||||
ReflectiveShieldTimer = 65000;
|
||||
} else ReflectiveShieldTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class boss_veras_darkshadow : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_veras_darkshadow() : CreatureScript("boss_veras_darkshadow") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetBlackTempleAI<boss_veras_darkshadowAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_veras_darkshadowAI : public boss_illidari_councilAI
|
||||
{
|
||||
boss_veras_darkshadowAI(Creature* creature) : boss_illidari_councilAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
DeadlyPoisonTimer = 20000;
|
||||
VanishTimer = urand(60, 121) * 1000;
|
||||
AppearEnvenomTimer = 150000;
|
||||
|
||||
HasVanished = false;
|
||||
}
|
||||
|
||||
uint32 DeadlyPoisonTimer;
|
||||
uint32 VanishTimer;
|
||||
uint32 AppearEnvenomTimer;
|
||||
|
||||
bool HasVanished;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
me->SetVisible(true);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_VERA_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_VERA_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (!HasVanished)
|
||||
{
|
||||
if (DeadlyPoisonTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DEADLY_POISON);
|
||||
DeadlyPoisonTimer = urand(15, 46) * 1000;
|
||||
} else DeadlyPoisonTimer -= diff;
|
||||
|
||||
if (AppearEnvenomTimer <= diff) // Cast Envenom. This is cast 4 seconds after Vanish is over
|
||||
{
|
||||
DoCastVictim(SPELL_ENVENOM);
|
||||
AppearEnvenomTimer = 90000;
|
||||
} else AppearEnvenomTimer -= diff;
|
||||
|
||||
if (VanishTimer <= diff) // Disappear and stop attacking, but follow a random unit
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
VanishTimer = 30000;
|
||||
AppearEnvenomTimer= 28000;
|
||||
HasVanished = true;
|
||||
me->SetVisible(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoResetThreat();
|
||||
// Chase a unit. Check before DoMeleeAttackIfReady prevents from attacking
|
||||
me->AddThreat(target, 500000.0f);
|
||||
me->GetMotionMaster()->MoveChase(target);
|
||||
}
|
||||
} else VanishTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (VanishTimer <= diff) // Become attackable and poison current target
|
||||
{
|
||||
Unit* target = me->GetVictim();
|
||||
DoCast(target, SPELL_DEADLY_POISON);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoResetThreat();
|
||||
me->AddThreat(target, 3000.0f); // Make Veras attack his target for a while, he will cast Envenom 4 seconds after.
|
||||
DeadlyPoisonTimer += 6000;
|
||||
VanishTimer = 90000;
|
||||
AppearEnvenomTimer = 4000;
|
||||
HasVanished = false;
|
||||
} else VanishTimer -= diff;
|
||||
|
||||
if (AppearEnvenomTimer <= diff) // Appear 2 seconds before becoming attackable (Shifting out of vanish)
|
||||
{
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
me->SetVisible(true);
|
||||
AppearEnvenomTimer = 6000;
|
||||
} else AppearEnvenomTimer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// SPELL_REFLECTIVE_SHIELD
|
||||
class spell_boss_lady_malande_shield : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_boss_lady_malande_shield() : SpellScriptLoader("spell_boss_lady_malande_shield") { }
|
||||
|
||||
class spell_boss_lady_malande_shield_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_boss_lady_malande_shield_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_REFLECTIVE_SHIELD_T });
|
||||
}
|
||||
|
||||
void Trigger(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
if (dmgInfo.GetAttacker() == target)
|
||||
return;
|
||||
int32 bp = absorbAmount / 2;
|
||||
target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_T, &bp, nullptr, nullptr, true, nullptr, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectAbsorb += AuraEffectAbsorbFn(spell_boss_lady_malande_shield_AuraScript::Trigger, EFFECT_0);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_boss_lady_malande_shield_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_illidari_council()
|
||||
{
|
||||
new npc_illidari_council();
|
||||
new npc_blood_elf_council_voice_trigger();
|
||||
new boss_gathios_the_shatterer();
|
||||
new boss_lady_malande();
|
||||
new boss_veras_darkshadow();
|
||||
new boss_high_nethermancer_zerevor();
|
||||
new spell_boss_lady_malande_shield();
|
||||
}
|
||||
@@ -75,7 +75,7 @@ ObjectData const creatureData[] =
|
||||
{ NPC_VERAS_DARKSHADOW, DATA_VERAS_DARKSHADOW },
|
||||
{ NPC_BLOOD_ELF_COUNCIL_VOICE, DATA_BLOOD_ELF_COUNCIL_VOICE },
|
||||
{ NPC_BLACK_TEMPLE_TRIGGER, DATA_BLACK_TEMPLE_TRIGGER },
|
||||
{ 0, 0 } // end
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
ObjectData const gameObjectData[] =
|
||||
|
||||
Reference in New Issue
Block a user