From 1756f7f0bbda7a0731878ec7f66842c970bd8b2b Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Wed, 25 Jul 2018 00:50:44 +0200 Subject: [PATCH] Scripts/BrC: implement Corla, Herald of Twilight encounter --- .../custom/custom_2018_07_25_00_world.sql | 53 ++ src/server/game/Spells/SpellMgr.cpp | 1 + .../BlackrockCaverns/blackrock_caverns.cpp | 96 ---- .../BlackrockCaverns/blackrock_caverns.h | 11 +- .../BlackrockCaverns/boss_corla.cpp | 129 ----- .../boss_corla_herald_of_twilight.cpp | 519 ++++++++++++++++++ .../instance_blackrock_caverns.cpp | 9 +- 7 files changed, 586 insertions(+), 232 deletions(-) create mode 100644 sql/updates/world/custom/custom_2018_07_25_00_world.sql delete mode 100644 src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp create mode 100644 src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla_herald_of_twilight.cpp diff --git a/sql/updates/world/custom/custom_2018_07_25_00_world.sql b/sql/updates/world/custom/custom_2018_07_25_00_world.sql new file mode 100644 index 00000000000..7c4406969b4 --- /dev/null +++ b/sql/updates/world/custom/custom_2018_07_25_00_world.sql @@ -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'); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 4ac78f8518e..522e66b0c4c 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4620,6 +4620,7 @@ void SpellMgr::LoadSpellInfoCorrections() { spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY); }); + // ENDOF BLACKROCK CAVERNS SPELLS // diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp index 321c2194673..bd580df7531 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp @@ -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(); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.h index a0e128f6949..39a81e48ed0 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.h @@ -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 diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp deleted file mode 100644 index 937cae76650..00000000000 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2008-2018 TrinityCore - * - * 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 . - */ - -#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(creature); - } -}; - -void AddSC_boss_corla() -{ - new boss_corla(); -} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla_herald_of_twilight.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla_herald_of_twilight.cpp new file mode 100644 index 00000000000..b101cb23801 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla_herald_of_twilight.cpp @@ -0,0 +1,519 @@ +/* + * Copyright (C) 2008-2018 TrinityCore + * + * 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 . + */ + +#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(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& 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(); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/instance_blackrock_caverns.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/instance_blackrock_caverns.cpp index 43f28cadc3f..5c8845bcda1 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/instance_blackrock_caverns.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/instance_blackrock_caverns.cpp @@ -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: