Scripts/BrC: implement Corla, Herald of Twilight encounter

This commit is contained in:
Ovahlord
2018-07-25 00:50:44 +02:00
parent 4589aef443
commit 1756f7f0bb
7 changed files with 586 additions and 232 deletions

View File

@@ -0,0 +1,53 @@
-- Template Updates
-- Corla, Herald of Twilight
UPDATE `creature_template` SET `ScriptName`= 'boss_corla_herald_of_twilight' WHERE `entry`= 39679;
-- Twilight Zealot
UPDATE `creature_template` SET `ScriptName`= 'npc_corla_twilight_zealot' WHERE `entry`= 50284;
UPDATE `creature_template` SET `mechanic_immune_mask`= 1 | 2 | 4 | 8 | 16 | 32 | 256 | 512 | 2048 | 4096 | 8192 | 65536 | 131072 | 8388608, `flags_extra`= 0x40000000 WHERE `entry` IN (50284, 50285, 39987, 39988);
UPDATE `creature_template` SET `DamageModifier`= 30, `BaseVariance`= 0.5 WHERE `entry`= 39987;
UPDATE `creature_template` SET `DamageModifier`= 60, `BaseVariance`= 0.5 WHERE `entry`= 39988;
-- Spells
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
('spell_corla_nether_dragon_essence',
'spell_nether_dragon_essence_1',
'spell_nether_dragon_essence_2',
'spell_corla_nether_dragon_essence_visual',
'spell_corla_nether_beam',
'spell_corla_evolution',
'spell_corla_grievous_whirl');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(75649, 'spell_corla_nether_dragon_essence'),
(75650, 'spell_corla_nether_dragon_essence_visual'),
(75653, 'spell_corla_nether_dragon_essence_visual'),
(75654, 'spell_corla_nether_dragon_essence_visual'),
(75676, 'spell_corla_nether_beam'),
(75697, 'spell_corla_evolution'),
(87378, 'spell_corla_evolution'),
(76524, 'spell_corla_grievous_whirl'),
(93658, 'spell_corla_grievous_whirl');
DELETE FROM `conditions` WHERE `SourceEntry`= 75677 AND `SourceTypeOrReferenceId`= 13;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES
(13, 1, 75677, 0, 0, 31, 0, 3, 39842, 0, 0, 0, '', 'Nether Beam - Target Invisible Stalker');
-- Addons
DELETE FROM `creature_template_addon` WHERE `entry`= 39842;
DELETE FROM `creature_addon` WHERE `guid`= 361693;
INSERT INTO `creature_addon` (`guid`, `auras`) VALUES
(361693, '75649');
-- Delete encounter related creatures
DELETE FROM `creature` WHERE `guid` IN (361875, 361876);
DELETE FROM `creature_addon` WHERE `guid` IN (361875, 361876);
DELETE FROM `spell_proc` WHERE `SpellId` IN (76524, 93658);
INSERT INTO `spell_proc` (`SpellId`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `Cooldown`, `Charges`, `Chance`) VALUES
(76524, 0, 0, 0, 0, 0x00008000| 0x00080000, 7, 0, 0, 0, 0, 0, 100),
(93658, 0, 0, 0, 0, 0x00008000| 0x00080000, 7, 0, 0, 0, 0, 0, 100);
-- Achievement
DELETE FROM `achievement_criteria_data` WHERE `criteria_id`= 15944;
INSERT INTO `achievement_criteria_data` (`criteria_id`, `type`, `value1`, `value2`, `ScriptName`) VALUES
(15944, 11, 0, 0, 'achievement_arrested_development');

View File

@@ -4620,6 +4620,7 @@ void SpellMgr::LoadSpellInfoCorrections()
{
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
});
// ENDOF BLACKROCK CAVERNS SPELLS
//

View File

@@ -667,99 +667,6 @@ class npc_raz_the_crazed : public CreatureScript
}
};
/*#####
# spell_nether_dragon_essence_1
#####*/
enum NetherDragonEssence
{
SPELL_NETHER_DRAGON_ESSENCE_1 = 75649,
SPELL_NETHER_DRAGON_ESSENCE_2 = 75650,
SPELL_NETHER_DRAGON_ESSENCE_3 = 75653,
SPELL_NETHER_DRAGON_ESSENCE_4 = 75654
};
class spell_nether_dragon_essence_1 : public SpellScriptLoader
{
public: spell_nether_dragon_essence_1() : SpellScriptLoader("spell_nether_dragon_essence_1") { }
class spell_nether_dragon_essence_1_AuraScript : public AuraScript
{
PrepareAuraScript(spell_nether_dragon_essence_1_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_NETHER_DRAGON_ESSENCE_2,
SPELL_NETHER_DRAGON_ESSENCE_3,
SPELL_NETHER_DRAGON_ESSENCE_4
});
}
void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
{
if (Unit* caster = GetCaster())
caster->CastSpell(caster, RAND(SPELL_NETHER_DRAGON_ESSENCE_2, SPELL_NETHER_DRAGON_ESSENCE_3, SPELL_NETHER_DRAGON_ESSENCE_4));
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_nether_dragon_essence_1_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_nether_dragon_essence_1_AuraScript();
}
};
/*#####
# spell_nether_dragon_essence_2
#####*/
class spell_nether_dragon_essence_2 : public SpellScriptLoader
{
public:
spell_nether_dragon_essence_2() : SpellScriptLoader("spell_nether_dragon_essence_2") { }
class spell_nether_dragon_essence_2_SpellScript : public SpellScript
{
PrepareSpellScript(spell_nether_dragon_essence_2_SpellScript);
void ModDestHeight(SpellDestination& dest)
{
Position offset = { frand(-35.0f, 35.0f), frand(-25.0f, 25.0f), 0.0f, 0.0f };
switch (GetSpellInfo()->Id)
{
case SPELL_NETHER_DRAGON_ESSENCE_2:
offset.m_positionZ = 25.0f;
break;
case SPELL_NETHER_DRAGON_ESSENCE_3:
offset.m_positionZ = 17.0f;
break;
case SPELL_NETHER_DRAGON_ESSENCE_4:
offset.m_positionZ = 33.0f;
break;
}
dest.RelocateOffset(offset);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_nether_dragon_essence_2_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_nether_dragon_essence_2_SpellScript();
}
};
void AddSC_blackrock_caverns()
{
// Creature Scripts
@@ -770,7 +677,4 @@ void AddSC_blackrock_caverns()
new npc_mad_prisoner();
new npc_crazed_mage();
new npc_raz_the_crazed();
// Spell Scripts
new spell_nether_dragon_essence_1();
new spell_nether_dragon_essence_2();
}

View File

@@ -29,7 +29,7 @@ enum BRCDataTypes
{
// Encounter States // Boss GUIDs
DATA_ROMOGG_BONECRUSHER = 0,
DATA_CORLA = 1,
DATA_CORLA_HERALD_OF_TWILIGHT = 1,
DATA_KARSH_STEELBENDER = 2,
DATA_BEAUTY = 3,
DATA_ASCENDANT_LORD_OBSIDIUS = 4,
@@ -42,15 +42,20 @@ enum BRCCreatureIds
{
// Bosses
BOSS_ROMOGG_BONECRUSHER = 39665,
BOSS_CORLA_HERALD_OF_TWILIGHT = 39679,
// Encounter Related
/*Rom'Ogg Bonecrusher*/
/*Rom'ogg Bonecrusher*/
NPC_CHAINS_OF_WOE = 40447,
NPC_ANGERED_EARTH = 50376,
NPC_QUAKE = 40401,
/*Corla, Herald of Twilight*/
NPC_TWILIGHT_ZEALOT = 50284,
NPC_EVOLVED_TWILIGHT_ZEALOT = 39987,
NPC_TWILIGHT_FLAME_CALLER = 39708,
NPC_RAZ_THE_CRAZED = 39670,
NPC_RAZ_THE_CRAZED = 39670
};
template <class AI, class T>

View File

@@ -1,129 +0,0 @@
/*
* 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 "blackrock_caverns.h"
#include "ScriptedCreature.h"
enum Text
{
YELL_AGGRO = 0,
YELL_KILL = 1,
YELL_EVOLVED_ZEALOT = 2,
YELL_DEATH = 3,
EMOTE_EVOLVED_ZEALOT = 4
};
enum Spells
{
SPELL_EVOLUTION = 75610,
SPELL_DRAIN_ESSENSE = 75645,
SPELL_SHADOW_POWER = 35322,
H_SPELL_SHADOW_POWER = 39193
};
enum Events
{
// Out of combat events
EVENT_DRAIN_ESSENSE = 1,
EVENT_STOP_DRAIN_ESSENSE = 2,
EVENT_EVOLUTION = 3
// Combat events
};
class boss_corla : public CreatureScript
{
public:
boss_corla(): CreatureScript("boss_corla") { }
struct boss_corlaAI : public BossAI
{
boss_corlaAI(Creature* creature) : BossAI(creature, DATA_CORLA) { }
void Reset() override
{
_Reset();
combatPhase = false;
events.ScheduleEvent(EVENT_DRAIN_ESSENSE, 2000);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(YELL_AGGRO);
events.Reset();
combatPhase = true;
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(YELL_KILL);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(YELL_DEATH);
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
if (!combatPhase)
{
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DRAIN_ESSENSE:
DoCast(me, SPELL_DRAIN_ESSENSE);
events.ScheduleEvent(EVENT_STOP_DRAIN_ESSENSE, 15000);
break;
case EVENT_STOP_DRAIN_ESSENSE:
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
events.ScheduleEvent(EVENT_EVOLUTION, 2000);
break;
case EVENT_EVOLUTION:
DoCast(me, SPELL_EVOLUTION);
events.ScheduleEvent(EVENT_DRAIN_ESSENSE, 2000);
break;
default:
break;
}
}
return;
}
DoMeleeAttackIfReady();
}
private:
bool combatPhase =false;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockCavernsAI<boss_corlaAI>(creature);
}
};
void AddSC_boss_corla()
{
new boss_corla();
}

View File

@@ -0,0 +1,519 @@
/*
* 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 "blackrock_caverns.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
enum Texts
{
// Corla
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_EVOLUTION_COMPLETE = 2,
YELL_DEATH = 3,
SAY_ANNOUNCE_ZEALOT_EVOLVED = 4
};
enum Spells
{
// Corla
SPELL_EVOLUTION = 75610,
SPELL_DRAIN_ESSENSE = 75645,
SPELL_AURA_OF_ACCELERATION = 87376,
SPELL_TWILIGHT_EVOLUTION = 75732,
// Twilight Zealot
SPELL_KNEELING_SUPPLICATION = 75608,
SPELL_NETHER_BEAM_PERIODIC = 75706,
SPELL_NETHER_BEAM_VISUAL = 75677,
SPELL_EVOLUTION_STACKS_N = 75697,
SPELL_EVOLUTION_STACKS_HC = 87378,
SPELL_GRIEVOUS_WHIRL = 76524,
SPELL_SHADOW_STRIKE = 82362,
SPELL_INVISIBILITY_AND_STEALTH_DETECTION = 18950,
SPELL_FORCE_BLAST = 76522,
SPELL_GRAVITY_STRIKE = 76561,
// Invisible Stalker
SPELL_NETHER_DRAGON_ESSENCE_VISUAL_1 = 75650,
SPELL_NETHER_DRAGON_ESSENCE_VISUAL_2 = 75653,
SPELL_NETHER_DRAGON_ESSENCE_VISUAL_3 = 75654
};
#define SPELL_DARK_COMMAND RAID_MODE<uint32>(75823, 93462)
enum Events
{
// Corla
EVENT_DRAIN_ESSENSE = 1,
EVENT_EVOLUTION,
EVENT_DARK_COMMAND,
// Twilight Zealot
EVENT_GRIEVOUS_WHIRL,
EVENT_SHADOW_STRIKE,
EVENT_INVISIBILITY_AND_STEALTH_DETECTION,
EVENT_GRAVITY_STRIKE,
EVENT_FORCE_BLAST
};
enum Phases
{
PHASE_OUT_OF_COMBAT = 1,
PHASE_IN_COMBAT = 2
};
enum Actions
{
// Twilight Zealot
ACTION_START_EVOLUTION = 0,
ACTION_EVOLVE
};
enum Data
{
DATA_ARRESTED_DEVELOPMENT = 0
};
Position const TwilightZealotSummonPositions[] =
{
{ 585.0278f, 982.8993f, 155.4369f, 1.500983f },
{ 561.9618f, 983.0191f, 155.4369f, 1.553343f },
{ 573.4844f, 978.5851f, 155.4369f, 1.570796f } // Heroic only
};
struct boss_corla_herald_of_twilight : public BossAI
{
boss_corla_herald_of_twilight(Creature* creature) : BossAI(creature, DATA_CORLA_HERALD_OF_TWILIGHT) { }
void Reset() override
{
_Reset();
_killedZealots = 0;
events.SetPhase(PHASE_OUT_OF_COMBAT);
events.ScheduleEvent(EVENT_DRAIN_ESSENSE, 1ms, 0, PHASE_OUT_OF_COMBAT);
for (uint8 i = 0; i < (IsHeroic() ? 3 : 2); i++)
DoSummon(NPC_TWILIGHT_ZEALOT, TwilightZealotSummonPositions[i], 0, TEMPSUMMON_MANUAL_DESPAWN);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
Talk(SAY_AGGRO);
me->CastStop();
DoCastSelf(SPELL_AURA_OF_ACCELERATION);
events.SetPhase(PHASE_IN_COMBAT);
events.ScheduleEvent(EVENT_DARK_COMMAND, 24s, 0, PHASE_IN_COMBAT);
for (ObjectGuid guid : summons)
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
if (zealot->IsAIEnabled)
zealot->AI()->DoAction(ACTION_START_EVOLUTION);
}
void KilledUnit(Unit* who) override
{
if (who->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void EnterEvadeMode(EvadeReason why) override
{
_EnterEvadeMode();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
summons.DespawnAll();
ClearAuras();
_DespawnAtEvade();
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(YELL_DEATH);
ClearAuras();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
}
void OnSpellCastInterrupt(SpellInfo const* spell) override
{
if (spell->Id == SPELL_DARK_COMMAND)
me->MakeInterruptable(false);
}
void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override
{
_killedZealots++;
}
void OnSuccessfulSpellCast(SpellInfo const* spell) override
{
if (spell->Id == SPELL_DARK_COMMAND)
me->MakeInterruptable(false);
}
uint32 GetData(uint32 type) const override
{
if (type == DATA_ARRESTED_DEVELOPMENT)
return _killedZealots == 3;
return 0;
}
void UpdateAI(uint32 diff) override
{
bool isInCombat = !events.IsInPhase(PHASE_OUT_OF_COMBAT);
if (!UpdateVictim() && isInCombat)
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) && isInCombat)
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DRAIN_ESSENSE:
DoCast(me, SPELL_DRAIN_ESSENSE);
events.Repeat(19s);
events.ScheduleEvent(EVENT_EVOLUTION, 17s, 0, PHASE_OUT_OF_COMBAT);
break;
case EVENT_EVOLUTION:
me->CastStop();
DoCast(me, SPELL_EVOLUTION);
break;
case EVENT_DARK_COMMAND:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
{
me->MakeInterruptable(true);
DoCast(target, SPELL_DARK_COMMAND);
}
events.Repeat(23s, 28s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
void ClearAuras()
{
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DARK_COMMAND);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_EVOLUTION_STACKS_N);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_EVOLUTION_STACKS_HC);
}
uint8 _killedZealots;
};
struct npc_corla_twilight_zealot : public ScriptedAI
{
npc_corla_twilight_zealot(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
me->SetReactState(REACT_PASSIVE);
}
void IsSummonedBy(Unit* /*summoner*/) override
{
DoCastSelf(SPELL_KNEELING_SUPPLICATION);
}
void DoAction(int32 action) override
{
switch (action)
{
case ACTION_START_EVOLUTION:
DoCastSelf(SPELL_NETHER_BEAM_PERIODIC);
break;
case ACTION_EVOLVE:
me->RemoveAllAuras();
me->SetReactState(REACT_AGGRESSIVE);
me->UpdateEntry(NPC_EVOLVED_TWILIGHT_ZEALOT);
DoZoneInCombat();
_events.ScheduleEvent(EVENT_GRIEVOUS_WHIRL, 1ms);
_events.ScheduleEvent(EVENT_SHADOW_STRIKE, 50ms);
_events.ScheduleEvent(EVENT_INVISIBILITY_AND_STEALTH_DETECTION, 2s);
_events.ScheduleEvent(EVENT_FORCE_BLAST, 2s);
_events.ScheduleEvent(EVENT_GRAVITY_STRIKE, 3s);
break;
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_GRIEVOUS_WHIRL:
DoCastAOE(SPELL_GRIEVOUS_WHIRL);
_events.Repeat(16s, 19s);
break;
case EVENT_SHADOW_STRIKE:
DoCastVictim(SPELL_SHADOW_STRIKE);
_events.Repeat(14s, 17s);
break;
case EVENT_INVISIBILITY_AND_STEALTH_DETECTION:
DoCastAOE(SPELL_INVISIBILITY_AND_STEALTH_DETECTION, true);
break;
case EVENT_FORCE_BLAST:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true, 0))
DoCast(target, SPELL_FORCE_BLAST);
_events.Repeat(14s, 17s);
break;
case EVENT_GRAVITY_STRIKE:
DoCastVictim(SPELL_GRAVITY_STRIKE);
_events.Repeat(10s, 11s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
class spell_corla_nether_dragon_essence : public AuraScript
{
PrepareAuraScript(spell_corla_nether_dragon_essence);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_NETHER_DRAGON_ESSENCE_VISUAL_1,
SPELL_NETHER_DRAGON_ESSENCE_VISUAL_2,
SPELL_NETHER_DRAGON_ESSENCE_VISUAL_3
});
}
void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
{
if (Unit* caster = GetCaster())
caster->CastSpell(caster, RAND(SPELL_NETHER_DRAGON_ESSENCE_VISUAL_1, SPELL_NETHER_DRAGON_ESSENCE_VISUAL_2, SPELL_NETHER_DRAGON_ESSENCE_VISUAL_3), true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_corla_nether_dragon_essence::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_corla_nether_dragon_essence_visual : public SpellScript
{
PrepareSpellScript(spell_corla_nether_dragon_essence_visual);
void ModDestHeight(SpellDestination& dest)
{
Position offset = { frand(-35.0f, 35.0f), frand(-25.0f, 25.0f), 0.0f, 0.0f };
switch (GetSpellInfo()->Id)
{
case SPELL_NETHER_DRAGON_ESSENCE_VISUAL_1:
offset.m_positionZ = 25.0f;
break;
case SPELL_NETHER_DRAGON_ESSENCE_VISUAL_2:
offset.m_positionZ = 17.0f;
break;
case SPELL_NETHER_DRAGON_ESSENCE_VISUAL_3:
offset.m_positionZ = 33.0f;
break;
default:
break;
}
dest.RelocateOffset(offset);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_corla_nether_dragon_essence_visual::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM);
}
};
class spell_corla_nether_beam : public SpellScript
{
PrepareSpellScript(spell_corla_nether_beam);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo(
{
SPELL_NETHER_BEAM_VISUAL,
SPELL_EVOLUTION_STACKS_N
});
}
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
{
if (Unit* caster = GetCaster())
{
caster->CastSpell(caster, SPELL_NETHER_BEAM_VISUAL, true);
caster->CastSpell(caster, SPELL_EVOLUTION_STACKS_N, true);
}
return;
}
if (targets.size() > 1)
{
if (Unit* caster = GetCaster())
{
targets.sort(Trinity::ObjectDistanceOrderPred(caster, true));
targets.resize(1);
}
}
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
Unit* target = GetHitUnit();
target->CastSpell(target, SPELL_NETHER_BEAM_VISUAL, true);
target->CastSpell(target, SPELL_EVOLUTION_STACKS_N, true);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_corla_nether_beam::FilterTargets, EFFECT_0, TARGET_UNIT_CONE_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_corla_nether_beam::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_corla_evolution : public SpellScript
{
PrepareSpellScript(spell_corla_evolution);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TWILIGHT_EVOLUTION });
}
void HandleEvolve()
{
Unit* target = GetHitUnit();
if (!target)
return;
Aura* aura = target->GetAura(GetSpellInfo()->Id);
if (!aura)
return;
if (aura->GetStackAmount() == GetSpellInfo()->StackAmount)
{
InstanceScript* instance = target->GetInstanceScript();
if (!instance)
return;
if (Creature* corla = instance->GetCreature(DATA_CORLA_HERALD_OF_TWILIGHT))
{
corla->AI()->Talk(SAY_EVOLUTION_COMPLETE);
if (Creature* creature = target->ToCreature())
{
if (creature->IsAIEnabled)
{
corla->AI()->Talk(SAY_ANNOUNCE_ZEALOT_EVOLVED);
creature->AI()->DoAction(ACTION_EVOLVE);
}
}
else if (target->GetTypeId() == TYPEID_PLAYER)
corla->CastSpell(target, SPELL_TWILIGHT_EVOLUTION, true);
}
aura->Remove();
}
}
void Register() override
{
AfterHit += SpellHitFn(spell_corla_evolution::HandleEvolve);
}
};
class spell_corla_grievous_whirl : public AuraScript
{
PrepareAuraScript(spell_corla_grievous_whirl);
void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
{
if (GetTarget()->GetHealth() == GetTarget()->GetMaxHealth())
Remove();
}
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_corla_grievous_whirl::HandleProc, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
}
};
class achievement_arrested_development : public AchievementCriteriaScript
{
public:
achievement_arrested_development() : AchievementCriteriaScript("achievement_arrested_development") { }
bool OnCheck(Player* /*source*/, Unit* target) override
{
if (!target)
return false;
if (target->IsAIEnabled)
return target->GetAI()->GetData(DATA_ARRESTED_DEVELOPMENT);
return false;
}
};
void AddSC_boss_corla()
{
RegisterBlackrockCavernsCreatureAI(boss_corla_herald_of_twilight);
RegisterBlackrockCavernsCreatureAI(npc_corla_twilight_zealot);
RegisterAuraScript(spell_corla_nether_dragon_essence);
RegisterSpellScript(spell_corla_nether_dragon_essence_visual);
RegisterSpellScript(spell_corla_nether_beam);
RegisterSpellScript(spell_corla_evolution);
RegisterAuraScript(spell_corla_grievous_whirl);
new achievement_arrested_development();
}

View File

@@ -22,9 +22,10 @@
ObjectData const creatureData[] =
{
{ BOSS_ROMOGG_BONECRUSHER, DATA_ROMOGG_BONECRUSHER },
{ NPC_RAZ_THE_CRAZED, DATA_RAZ_THE_CRAZED },
{ 0, 0 }
{ BOSS_ROMOGG_BONECRUSHER, DATA_ROMOGG_BONECRUSHER },
{ BOSS_CORLA_HERALD_OF_TWILIGHT, DATA_CORLA_HERALD_OF_TWILIGHT },
{ NPC_RAZ_THE_CRAZED, DATA_RAZ_THE_CRAZED },
{ 0, 0 }
};
class instance_blackrock_caverns : public InstanceMapScript
@@ -49,7 +50,7 @@ class instance_blackrock_caverns : public InstanceMapScript
switch (type)
{
case DATA_ROMOGG_BONECRUSHER:
case DATA_CORLA:
case DATA_CORLA_HERALD_OF_TWILIGHT:
case DATA_KARSH_STEELBENDER:
case DATA_BEAUTY:
case DATA_ASCENDANT_LORD_OBSIDIUS: