diff options
author | Naddley <64811442+Naddley@users.noreply.github.com> | 2023-03-02 23:52:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-02 23:52:05 +0100 |
commit | 1baa2f4f3993e7269f72fd143bea36d1a7ffd9f8 (patch) | |
tree | 6ea499cfda939c12c5177279fce493bd9e4c4452 | |
parent | 0026706e8333c79f8baae341b94e65e1eac484ca (diff) |
Scripts/AzureVault: Implement Leymor encounter (#28810)
6 files changed, 822 insertions, 0 deletions
diff --git a/sql/updates/world/master/2023_03_02_03_world.sql b/sql/updates/world/master/2023_03_02_03_world.sql new file mode 100644 index 00000000000..fb96b09521e --- /dev/null +++ b/sql/updates/world/master/2023_03_02_03_world.sql @@ -0,0 +1,56 @@ +-- Leymor +DELETE FROM `creature_text` WHERE `CreatureID` = 186644; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(186644, 0, 0, 'Leymor awakens as the stasis ritual is interrupted.', 41, 0, 100, 0, 0, 0, 0, 0, 'Leymor to Player'); + +UPDATE `creature_template` SET `unit_flags` = `unit_flags` & ~ (0x100 | 0x200), `AIName` = '', `ScriptName` = 'boss_leymor' WHERE `entry` = 186644; +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_arcane_tender' WHERE `entry` = 191164; +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_volatile_sapling' WHERE `entry` = 196559; +UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_ley_line_sprouts', `flags_extra` = 128 WHERE `entry` = 190509; + +UPDATE `creature_template_addon` SET `auras` = '' WHERE `entry` = 186644; + +DELETE FROM `instance_template` WHERE `map` = 2515; +INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES +(2515, 0, 'instance_azure_vault'); + +DELETE FROM `creature_template_addon` WHERE `entry` = 190509; + +DELETE FROM `areatrigger_template` WHERE (`IsServerSide`=0 AND `Id` IN (29766, 29888, 29793)); +INSERT INTO `areatrigger_template` (`Id`, `IsServerSide`, `Type`, `Flags`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `VerifiedBuild`) VALUES +(29766, 0, 0, 6, 5, 5, 0, 0, 0, 0, 0, 0, 47213), +(29888, 0, 0, 2, 4, 4, 0, 0, 0, 0, 0, 0, 47213), +(29793, 0, 0, 0, 100, 100, 0, 0, 0, 0, 0, 0, 47213); + +DELETE FROM `areatrigger_create_properties` WHERE `Id` IN (25356, 25515, 25390); +INSERT INTO `areatrigger_create_properties` (`Id`, `AreaTriggerId`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `VerifiedBuild`) VALUES +(25356, 29766, 0, 33927, 0, 0, -1, 0, 352, 0, 300000, 0, 5, 5, 0, 0, 0, 0, 0, 0, 47213), -- SpellId : 374161 +(25515, 29888, 0, 34322, 0, 0, -1, 0, 352, 0, 15000, 0, 4, 4, 0, 0, 0, 0, 0, 0, 47213), -- SpellId : 375647 +(25390, 29793, 0, 0, 0, 0, -1, 0, 0, 0, 750, 0, 100, 100, 0, 0, 0, 0, 0, 0, 47213); -- SpellId : 375749 + +UPDATE `areatrigger_create_properties` SET `ScriptName` = 'at_leymor_arcane_eruption' WHERE `Id` = 25390; + +DELETE FROM `areatrigger_template_actions` WHERE `AreaTriggerId` IN (29766, 29888) AND `IsServerSide` = 0; +INSERT INTO `areatrigger_template_actions` (`AreaTriggerId`, `IsServerSide`, `ActionType`, `ActionParam`, `TargetType`) VALUES +(29766, 0, 0, 374523, 2), +(29888, 0, 0, 375649, 2); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (374364, 375652, 375732, 374567, 374720, 375591, 386660); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(374364, 'spell_ley_line_sprouts'), +(375652, 'spell_wild_eruption'), +(375732, 'spell_stasis_ritual'), +(374567, 'spell_explosive_brand'), +(374720, 'spell_consuming_stomp'), +(375591, 'spell_sappy_burst'), +(386660, 'spell_erupting_fissure'); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` = 375738) OR (`SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` = 375732) OR (`SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` = 375652) OR (`SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 2 AND `SourceEntry` = 374570) OR (`SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` = 374720) OR (`SourceTypeOrReferenceId` = 13 AND `SourceGroup` = 1 AND `SourceEntry` = 394154); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 375738, 0, 0, 31, 0, 3, 186644, 0, 0, 0, 0, '', 'Spell 375738 can only hit Leymor'), +(13, 1, 375732, 0, 0, 31, 0, 3, 186644, 0, 0, 0, 0, '', 'Spell 375732 can only hit Leymor'), +(13, 1, 375652, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Spell 375652 can only hit Player'), +(13, 2, 374570, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Spell 374570 can only hit Player'), +(13, 2, 374570, 0, 1, 31, 0, 3, 190509, 0, 0, 0, 0, '', 'Spell 374570 can only hit Ley-Line Sprouts'), +(13, 1, 374720, 0, 0, 31, 0, 3, 190509, 0, 0, 0, 0, '', 'Spell 374720 can only hit Ley-Line Sprouts'), +(13, 1, 394154, 0, 0, 31, 0, 3, 190509, 0, 0, 0, 0, '', 'Spell 394154 can only hit Ley-Line Sprouts'); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index a0736be6576..4d93cf5fefa 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4610,6 +4610,18 @@ void SpellMgr::LoadSpellInfoCorrections() // ENDOF ANTORUS THE BURNING THRONE SPELLS + // + // THE AZURE VAULT SPELLS + // + + // Stinging Sap + ApplySpellFix({ 374523 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesEx8 |= SPELL_ATTR8_ATTACK_IGNORE_IMMUNE_TO_PC_FLAG; + }); + + // ENDOF THE AZURE VAULT SPELLS + // // Summon Master Li Fei ApplySpellFix({ 102445 }, [](SpellInfo* spellInfo) { diff --git a/src/server/scripts/DragonIsles/AzureVault/azure_vault.h b/src/server/scripts/DragonIsles/AzureVault/azure_vault.h new file mode 100644 index 00000000000..8f812053155 --- /dev/null +++ b/src/server/scripts/DragonIsles/AzureVault/azure_vault.h @@ -0,0 +1,65 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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/>. + */ + +#ifndef DEF_AZURE_VAULT_H_ +#define DEF_AZURE_VAULT_H_ + +#include "CreatureAIImpl.h" + +#define DataHeader "AzureVault" +#define AVScriptName "instance_azure_vault" + +uint32 const EncounterCount = 4; + +enum AVDataTypes +{ + // Encounters + DATA_LEYMOR = 0, + DATA_AZUREBLADE, + DATA_TELASH_GREYWING, + DATA_UMBRELSKUL, + + DATA_LEYMOR_INTRO_DONE +}; + +enum AVCreatureIds +{ + // Bosses + BOSS_LEYMOR = 186644, + BOSS_AZUREBLADE = 186739, + BOSS_TELASH_GREYWING = 199614, + BOSS_UMBRELSKUL = 186738, + + // Leymor + NPC_ARCANE_TENDER = 191164, +}; + +enum AVGameObjectIds +{ + GO_ARCANE_VAULTS_DOOR_LEYMOR_ENTRANCE = 380536, + GO_ARCANE_VAULTS_DOOR_LEYMOR_EXIT = 377951 +}; + +template <class AI, class T> +inline AI* GetAzureVaultAI(T* obj) +{ + return GetInstanceAI<AI>(obj, AVScriptName); +} + +#define RegisterAzureVaultCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetAzureVaultAI) + +#endif diff --git a/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp b/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp new file mode 100644 index 00000000000..f8e6bd485db --- /dev/null +++ b/src/server/scripts/DragonIsles/AzureVault/boss_leymor.cpp @@ -0,0 +1,573 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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 "AreaTrigger.h" +#include "AreaTriggerAI.h" +#include "CreatureAI.h" +#include "CreatureAIImpl.h" +#include "InstanceScript.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuras.h" +#include "SharedDefines.h" +#include "TemporarySummon.h" +#include "azure_vault.h" + +enum LeymorSpells +{ + // Leymor + SPELL_STASIS = 375729, + SPELL_ARCANE_ERUPTION = 375749, + SPELL_LEY_LINE_SPROUTS = 374364, + SPELL_LEY_LINE_SPROUTS_MISSILE = 374362, + SPELL_CONSUMING_STOMP = 374720, + SPELL_CONSUMING_STOMP_DAMAGE = 374731, + SPELL_ERUPTING_FISSURE = 386660, + SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR = 394154, + SPELL_EXPLOSIVE_BRAND = 374567, + SPELL_EXPLOSIVE_BRAND_DAMAGE = 374570, + SPELL_EXPLOSIVE_BRAND_KNOCKBACK = 374582, + SPELL_INFUSED_STRIKE = 374789, + + // Ley-Line Sprout + SPELL_VOLATILE_SAPLING = 388654, + SPELL_LEY_LINE_SPROUT_AT = 374161, + SPELL_ARCANE_POWER = 374736, + + // Volatile Sapling + SPELL_SAPPY_BURST = 375591, + + // Arcane Tender + SPELL_STASIS_RITUAL = 375732, + SPELL_STASIS_RITUAL_MISSILE = 375738, + SPELL_ERRATIC_GROWTH_CHANNEL = 375596, + SPELL_WILD_ERUPTION = 375652, + SPELL_WILD_ERUPTION_MISSILE = 375650 +}; + +enum LeymorEvents +{ + // Leymor + EVENT_LEYMOR_AWAKE = 1, + EVENT_LEY_LINE_SPROUTS, + EVENT_CONSUMING_STOMP, + EVENT_ERUPTING_FISSURE, + EVENT_EXPLOSIVE_BRAND, + EVENT_INFUSED_STRIKE, + + // Arcane Tender + EVENT_ERRATIC_GROWTH = 1, + EVENT_WILD_ERUPTION, + EVENT_INFUSED_GROUND, +}; + +enum LeymorTexts +{ + SAY_ANNOUNCE_AWAKEN = 0 +}; + +enum LeymorVisuals +{ + SPELL_VISUAL_KIT_SPROUT_DEATH = 159239 +}; + +enum LeymorNpcs +{ + NPC_LEYLINE_SPROUTS = 190509 +}; + +enum LeymorActions +{ + ACTION_ARCANE_TENDER_DEATH = 1 +}; + +// 186644 - Leymor +struct boss_leymor : public BossAI +{ + boss_leymor(Creature* creature) : BossAI(creature, DATA_LEYMOR), _killedArcaneTender(0) { } + + void JustAppeared() override + { + if (instance->GetData(DATA_LEYMOR_INTRO_DONE)) + return; + + me->SetUnitFlag(UnitFlags(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC)); + DoCastSelf(SPELL_STASIS); + } + + void DoAction(int32 action) override + { + if (action == ACTION_ARCANE_TENDER_DEATH) + { + _killedArcaneTender++; + if (_killedArcaneTender >= 3) + { + instance->SetData(DATA_LEYMOR_INTRO_DONE, 1); + + scheduler.Schedule(1s, [this](TaskContext /*context*/) + { + me->RemoveAurasDueToSpell(SPELL_STASIS); + me->RemoveUnitFlag(UnitFlags(UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC)); + DoCastSelf(SPELL_ARCANE_ERUPTION); + Talk(SAY_ANNOUNCE_AWAKEN); + }); + } + } + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + + summons.DespawnAll(); + _EnterEvadeMode(); + _DespawnAtEvade(); + } + + void OnChannelFinished(SpellInfo const* spell) override + { + if (spell->Id == SPELL_CONSUMING_STOMP) + DoCastAOE(SPELL_CONSUMING_STOMP_DAMAGE, true); + }; + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + events.ScheduleEvent(EVENT_LEY_LINE_SPROUTS, 3s); + events.ScheduleEvent(EVENT_CONSUMING_STOMP, 45s); + events.ScheduleEvent(EVENT_ERUPTING_FISSURE, 20s); + events.ScheduleEvent(EVENT_EXPLOSIVE_BRAND, 31s); + events.ScheduleEvent(EVENT_INFUSED_STRIKE, 10s); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_LEY_LINE_SPROUTS: + DoCastSelf(SPELL_LEY_LINE_SPROUTS); + events.ScheduleEvent(EVENT_LEY_LINE_SPROUTS, 48s); + break; + case EVENT_CONSUMING_STOMP: + DoCastSelf(SPELL_CONSUMING_STOMP); + events.ScheduleEvent(EVENT_CONSUMING_STOMP, 48s); + break; + case EVENT_ERUPTING_FISSURE: + DoCastVictim(SPELL_ERUPTING_FISSURE); + events.ScheduleEvent(EVENT_ERUPTING_FISSURE, 48s); + break; + case EVENT_EXPLOSIVE_BRAND: + DoCastSelf(SPELL_EXPLOSIVE_BRAND); + events.ScheduleEvent(EVENT_EXPLOSIVE_BRAND, 48s); + break; + case EVENT_INFUSED_STRIKE: + DoCastVictim(SPELL_INFUSED_STRIKE); + events.ScheduleEvent(EVENT_INFUSED_STRIKE, 48s); + break; + default: + break; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + DoMeleeAttackIfReady(); + } + +private: + int32 _killedArcaneTender; +}; + +// 191164 - Arcane Tender +struct npc_arcane_tender : public ScriptedAI +{ + npc_arcane_tender(Creature* creature) : ScriptedAI(creature) { } + + void JustDied(Unit* /*killer*/) override + { + Creature* leymor = me->GetInstanceScript()->GetCreature(DATA_LEYMOR); + if (!leymor) + return; + + if (!leymor->IsAIEnabled()) + return; + + leymor->AI()->DoAction(ACTION_ARCANE_TENDER_DEATH); + } + + void JustAppeared() override + { + Creature* leymor = me->GetInstanceScript()->GetCreature(DATA_LEYMOR); + if (!leymor) + return; + + DoCast(leymor, SPELL_STASIS_RITUAL); + } + + void JustReachedHome() override + { + JustAppeared(); + } + + void Reset() override + { + _events.Reset(); + } + + void JustEngagedWith(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_ERRATIC_GROWTH, 22s); + _events.ScheduleEvent(EVENT_WILD_ERUPTION, 12s); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ERRATIC_GROWTH: + DoCastAOE(SPELL_ERRATIC_GROWTH_CHANNEL); + _events.ScheduleEvent(EVENT_ERRATIC_GROWTH, 22s); + break; + case EVENT_WILD_ERUPTION: + DoCastAOE(SPELL_WILD_ERUPTION); + _events.ScheduleEvent(EVENT_WILD_ERUPTION, 12s); + break; + default: + break; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + DoMeleeAttackIfReady(); + } +private: + EventMap _events; +}; + +// 190509 - Ley-Line Sprout +struct npc_ley_line_sprouts : public ScriptedAI +{ + npc_ley_line_sprouts(Creature* creature) : ScriptedAI(creature) { } + + void JustAppeared() override + { + DoCastSelf(SPELL_LEY_LINE_SPROUT_AT); + + DoCastAOE(SPELL_ARCANE_POWER, true); + } + + void JustDied(Unit* /*killer*/) override + { + if (GetDifficulty() == DIFFICULTY_MYTHIC || GetDifficulty() == DIFFICULTY_MYTHIC_KEYSTONE) + DoCastAOE(SPELL_VOLATILE_SAPLING, true); + + if (TempSummon* tempSummon = me->ToTempSummon()) + { + if (Unit* summoner = tempSummon->GetSummonerUnit()) + { + if (Aura* aura = summoner->GetAura(SPELL_ARCANE_POWER)) + aura->ModStackAmount(-1); + } + } + } + + void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override + { + if (spellInfo->Id != SPELL_EXPLOSIVE_BRAND_DAMAGE && spellInfo->Id != SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR) + return; + + me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_SPROUT_DEATH, 0, 0); + me->KillSelf(); + } +}; + +// 196559 - Volatile Sapling +struct npc_volatile_sapling : public ScriptedAI +{ + npc_volatile_sapling(Creature* creature) : ScriptedAI(creature), _isSappyBurstCast(false) { } + + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) + { + if (me->GetHealth() <= damage) + { + damage = me->GetHealth() - 1; + + if (!_isSappyBurstCast) + { + me->CastSpell(nullptr, SPELL_SAPPY_BURST, false); + _isSappyBurstCast = true; + } + } + } + +private: + bool _isSappyBurstCast; +}; + +static Position const LeyLineSproutGroupOrigin[] = +{ + { -5129.39f, 1253.30f, 555.58f }, + { -5101.68f, 1253.71f, 555.90f }, + { -5114.70f, 1230.28f, 555.89f }, + { -5141.62f, 1230.33f, 555.83f }, + { -5155.62f, 1253.60f, 555.87f }, + { -5141.42f, 1276.70f, 555.89f }, + { -5114.78f, 1277.42f, 555.87f } +}; + +// 374364 - Ley-Line Sprouts +class spell_ley_line_sprouts : public SpellScript +{ + PrepareSpellScript(spell_ley_line_sprouts); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_LEY_LINE_SPROUTS_MISSILE }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + for (Position const& pos : LeyLineSproutGroupOrigin) + { + for (int8 i = 0; i < 2; i++) + GetCaster()->CastSpell(pos, SPELL_LEY_LINE_SPROUTS_MISSILE, true); + } + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_ley_line_sprouts::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 375732 - Stasis Ritual +class spell_stasis_ritual : public AuraScript +{ + PrepareAuraScript(spell_stasis_ritual); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_STASIS_RITUAL_MISSILE }); + } + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(nullptr, SPELL_STASIS_RITUAL_MISSILE, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_stasis_ritual::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// 375652 - Wild Eruption +class spell_wild_eruption : public SpellScript +{ + PrepareSpellScript(spell_wild_eruption); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WILD_ERUPTION_MISSILE }); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(*GetHitDest(), SPELL_WILD_ERUPTION_MISSILE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_wild_eruption::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 375749 - Arcane Eruption +struct at_leymor_arcane_eruption : AreaTriggerAI +{ + at_leymor_arcane_eruption(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + void OnUnitEnter(Unit* unit) override + { + if (!unit->IsPlayer()) + return; + + unit->ApplyMovementForce(at->GetGUID(), at->GetPosition(), -20.0f, MovementForceType::Gravity); + } + + void OnUnitExit(Unit* unit) override + { + if (!unit->IsPlayer()) + return; + + unit->RemoveMovementForce(at->GetGUID()); + } +}; + +// 374567 - Explosive Brand +class spell_explosive_brand : public SpellScript +{ + PrepareSpellScript(spell_explosive_brand); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_EXPLOSIVE_BRAND_KNOCKBACK }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(nullptr, SPELL_EXPLOSIVE_BRAND_KNOCKBACK, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_explosive_brand::HandleHit, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } +}; + +// 374567 - Explosive Brand +class spell_explosive_brand_AuraScript : public AuraScript +{ + PrepareAuraScript(spell_explosive_brand_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_EXPLOSIVE_BRAND_DAMAGE }); + } + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), SPELL_EXPLOSIVE_BRAND_DAMAGE, true); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_explosive_brand_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 374720 - Consuming Stomp +class spell_consuming_stomp : public AuraScript +{ + PrepareAuraScript(spell_consuming_stomp); + + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->KillSelf(); + } + + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_consuming_stomp::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 386660 - Erupting Fissure +class spell_erupting_fissure : public SpellScript +{ + PrepareSpellScript(spell_erupting_fissure); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(*GetHitDest(), SPELL_ERUPTING_FISSURE_SPROUT_SELECTOR, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_erupting_fissure::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + +// 375591 - Sappy Burst +class spell_sappy_burst : public SpellScript +{ + PrepareSpellScript(spell_sappy_burst); + + void HandleHitTarget(SpellEffIndex /*effIndex*/) + { + GetCaster()->KillSelf(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_sappy_burst::HandleHitTarget, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +void AddSC_boss_leymor() +{ + // Creature + RegisterAzureVaultCreatureAI(boss_leymor); + RegisterAzureVaultCreatureAI(npc_arcane_tender); + RegisterAzureVaultCreatureAI(npc_ley_line_sprouts); + RegisterAzureVaultCreatureAI(npc_volatile_sapling); + + // Spells + RegisterSpellScript(spell_ley_line_sprouts); + RegisterSpellScript(spell_stasis_ritual); + RegisterSpellScript(spell_wild_eruption); + RegisterSpellScript(spell_consuming_stomp); + RegisterSpellScript(spell_erupting_fissure); + RegisterSpellScript(spell_sappy_burst); + RegisterSpellAndAuraScriptPair(spell_explosive_brand, spell_explosive_brand_AuraScript); + + // AreaTrigger + RegisterAreaTriggerAI(at_leymor_arcane_eruption); +} diff --git a/src/server/scripts/DragonIsles/AzureVault/instance_azure_vault.cpp b/src/server/scripts/DragonIsles/AzureVault/instance_azure_vault.cpp new file mode 100644 index 00000000000..6054beddf52 --- /dev/null +++ b/src/server/scripts/DragonIsles/AzureVault/instance_azure_vault.cpp @@ -0,0 +1,108 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * 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 "AreaBoundary.h" +#include "InstanceScript.h" +#include "ScriptMgr.h" +#include "azure_vault.h" + +BossBoundaryData const boundaries = +{ + { DATA_LEYMOR, new CircleBoundary(Position(-5129.39f, 1253.30f), 75.0f) } +}; + +ObjectData const creatureData[] = +{ + { BOSS_LEYMOR, DATA_LEYMOR }, + { BOSS_AZUREBLADE, DATA_AZUREBLADE }, + { BOSS_TELASH_GREYWING, DATA_TELASH_GREYWING }, + { BOSS_UMBRELSKUL, DATA_UMBRELSKUL }, + { 0, 0 } // END +}; + +DoorData const doorData[] = +{ + { GO_ARCANE_VAULTS_DOOR_LEYMOR_ENTRANCE, DATA_LEYMOR, DOOR_TYPE_ROOM }, + { GO_ARCANE_VAULTS_DOOR_LEYMOR_EXIT, DATA_LEYMOR, DOOR_TYPE_PASSAGE }, + { 0, 0, DOOR_TYPE_ROOM } // END +}; + +DungeonEncounterData const encounters[] = +{ + { DATA_LEYMOR, {{ 2582 }} }, + { DATA_AZUREBLADE, {{ 2585 }} }, + { DATA_TELASH_GREYWING, {{ 2583 }} }, + { DATA_UMBRELSKUL, {{ 2584 }} }, +}; + +class instance_azure_vault : public InstanceMapScript +{ + public: + instance_azure_vault() : InstanceMapScript(AVScriptName, 2515) { } + + struct instance_azure_vault_InstanceMapScript: public InstanceScript + { + instance_azure_vault_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + LoadObjectData(creatureData, nullptr); + LoadDoorData(doorData); + LoadBossBoundaries(boundaries); + LoadDungeonEncounterData(encounters); + + _leymorIntroDone = false; + } + + uint32 GetData(uint32 dataId) const override + { + switch (dataId) + { + case DATA_LEYMOR_INTRO_DONE: + return _leymorIntroDone ? 1 : 0; + default: + break; + } + return 0; + } + + void SetData(uint32 dataId, uint32 /*value*/) override + { + switch (dataId) + { + case DATA_LEYMOR_INTRO_DONE: + _leymorIntroDone = true; // no need to pass value, it will never reset to false + break; + default: + break; + } + } + + private: + bool _leymorIntroDone; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_azure_vault_InstanceMapScript(map); + } +}; + +void AddSC_instance_azure_vault() +{ + new instance_azure_vault(); +} diff --git a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp b/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp index 5719c2936ee..39123bc1c02 100644 --- a/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp +++ b/src/server/scripts/DragonIsles/dragon_isles_script_loader.cpp @@ -22,6 +22,10 @@ void AddSC_zone_the_forbidden_reach(); void AddSC_instance_ruby_life_pools(); void AddSC_ruby_life_pools(); +// Azure Vault +void AddSC_instance_azure_vault(); +void AddSC_boss_leymor(); + // The name of this function should match: // void Add${NameOfDirectory}Scripts() void AddDragonIslesScripts() @@ -31,4 +35,8 @@ void AddDragonIslesScripts() // Ruby Life Pools AddSC_instance_ruby_life_pools(); AddSC_ruby_life_pools(); + + // Azure Vault + AddSC_instance_azure_vault(); + AddSC_boss_leymor(); } |