diff options
author | ModoX <moardox@gmail.com> | 2024-05-22 16:00:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-22 16:00:48 +0200 |
commit | 5f5871708ff0d9080936cdf1e30b5b3481813b6a (patch) | |
tree | 944e146e6f165eb9f02610db628abf6a8311581b | |
parent | 7f077e72bd1e8c9a066f8f26ec26d31587b3ed0d (diff) |
Scripts/MawOfSouls: Implemented Ymiron, the Fallen King encounter (#29987)
6 files changed, 974 insertions, 0 deletions
diff --git a/sql/updates/world/master/2024_05_22_02_world.sql b/sql/updates/world/master/2024_05_22_02_world.sql new file mode 100644 index 00000000000..9cba5daf84a --- /dev/null +++ b/sql/updates/world/master/2024_05_22_02_world.sql @@ -0,0 +1,100 @@ +-- +SET @ATID := 65; +SET @ATSPAWNID := 67; +SET @ATCP := 53; + +DELETE FROM `areatrigger` WHERE `SpawnId`=@ATSPAWNID+0; +INSERT INTO `areatrigger` (`SpawnId`, `AreaTriggerCreatePropertiesId`, `IsCustom`, `MapId`, `SpawnDifficulties`, `PosX`, `PosY`, `PosZ`, `Orientation`, `PhaseUseFlags`, `PhaseId`, `PhaseGroup`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES +(@ATSPAWNID+0, @ATCP+0, 1, 1492, '1,2,8,23', 7380.5766, 7289.9389, 43.8447, 2.8720, 1, 0, 0, 'at_ymiron_the_fallen_king_activation', 'Maw of Souls - Ymiron Activation Trigger', 0); + +DELETE FROM `areatrigger_create_properties` WHERE `Id`=@ATCP+0 AND `IsCustom`=1; +INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES +(@ATCP+0, 1, @ATID+0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 4, 35, 35, 5, 5, 0, 0, 0, 0, '', 0); + +DELETE FROM `areatrigger_template` WHERE `Id`=@ATID+0 AND `IsCustom`=1; +INSERT INTO `areatrigger_template` (`Id`, `IsCustom`, `Flags`, `VerifiedBuild`) VALUES +(@ATID+0, 1, 1, 0); + +UPDATE `creature_model_info` SET `VerifiedBuild`=52129 WHERE `DisplayID` IN (30076, 66346, 66348, 66681, 66345, 66238, 66121, 70528, 66688, 64208, 66852, 26725, 66184, 106378, 67556, 30710, 70529, 66102, 66181, 67179, 66183, 66103, 65823, 64467, 64200, 28120, 28118, 65214, 67001, 65079, 21342, 66119, 25801, 27824, 66091, 11686, 16925, 66090, 25630); +UPDATE `creature_model_info` SET `BoundingRadius`=10.46424579620361328, `VerifiedBuild`=52129 WHERE `DisplayID`=65778; +UPDATE `creature_model_info` SET `BoundingRadius`=52.32122802734375, `VerifiedBuild`=52129 WHERE `DisplayID`=66680; +UPDATE `creature_model_info` SET `BoundingRadius`=13.0803070068359375, `VerifiedBuild`=52129 WHERE `DisplayID`=66618; +UPDATE `creature_model_info` SET `BoundingRadius`=31.39273834228515625, `VerifiedBuild`=52129 WHERE `DisplayID`=67211; + +DELETE FROM `areatrigger_create_properties_orbit` WHERE (`AreaTriggerCreatePropertiesId`=5838 AND `IsCustom`=0); +INSERT INTO `areatrigger_create_properties_orbit` (`AreaTriggerCreatePropertiesId`, `IsCustom`, `StartDelay`, `CircleRadius`, `BlendFromRadius`, `InitialAngle`, `ZOffset`, `CounterClockwise`, `CanLoop`, `VerifiedBuild`) VALUES +(5838, 0, 0, 0, 0, 0, 0, 0, 1, 52129); -- Spell: 193465 (Bane) + +DELETE FROM `areatrigger_create_properties` WHERE (`IsCustom`=0 AND `Id` IN (5838)); +INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `TimeToTarget`, `TimeToTargetScale`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `VerifiedBuild`) VALUES +(5838, 0, 10407, 0, 0, 0, 0, 0, 0, -1, 0, 26, 11863, 21000, 0, 2, 2, 0, 0, 0, 0, 0, 0, 52129); -- Spell: 193465 (Bane) + +UPDATE `areatrigger_create_properties` SET `ScriptName`='at_ymiron_the_fallen_king_bane' WHERE `Id`=5838 AND `IsCustom`=0; + +UPDATE `areatrigger_template` SET `Flags`=0, `VerifiedBuild`=52129 WHERE (`Id`=10407 AND `IsCustom`=0); + +-- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + +DELETE FROM `instance_template` WHERE `map`=1492; +INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES +(1492, 0, 'instance_maw_of_souls'); + +UPDATE `creature_template` SET `AIName`='', `ScriptName`='boss_ymiron_the_fallen_king' WHERE `entry`=96756; +UPDATE `creature_template` SET `AIName`='', `ScriptName`='npc_ymiron_the_fallen_king_risen_warrior' WHERE `entry`=98246; +UPDATE `creature_template_addon` SET `auras`='342788' WHERE `entry`=96756; -- remove kneeling from template +UPDATE `creature` SET `equipment_id`=-1 WHERE `guid`=650507; -- add weapon to ymiron + +UPDATE `creature_template` SET `faction`=16, `speed_run`=0.857142865657806396, `BaseAttackTime`=1500, `unit_flags`=32768, `unit_flags2`=2099200, `unit_flags3`=524288 WHERE `entry`=98246; -- Risen Warrior + +DELETE FROM `creature_template_addon` WHERE `entry`=98246; +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES +(98246, '123978'); + +SET @PATHID := 9675600; +DELETE FROM `waypoint_path` WHERE `PathId` BETWEEN @PATHID+0 AND @PATHID+1; +INSERT INTO `waypoint_path` (`PathId`, `MoveType`, `Flags`, `Velocity`, `Comment`) VALUES +(@PATHID+0, 0, 0, NULL, 'Ymiron - Intro Path towards Runecarver Slaves'), +(@PATHID+1, 0, 0, NULL, 'Ymiron - Intro Path away from Runecarver Slaves'); + +DELETE FROM `waypoint_path_node` WHERE `PathId` BETWEEN @PATHID+0 AND @PATHID+1; +INSERT INTO `waypoint_path_node` (`PathId`, `NodeId`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `Delay`) VALUES +(@PATHID+0, 0, 7400.461, 7288.4614, 44.063484, NULL, 0), +(@PATHID+0, 1, 7398.961, 7291.4614, 44.063484, NULL, 0), +(@PATHID+0, 2, 7394.7075, 7295.432, 43.7841, NULL, 0), +(@PATHID+1, 0, 7397.9185, 7286.777, 43.79471, NULL, 0), +(@PATHID+1, 1, 7398.374, 7277.1206, 43.792637, 5.724679946899414062, 0); + +DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceEntry` IN (243029)); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `Comment`) VALUES +(13, 0x1|0x2|0x4, 243029, 0, 0, 51, 0, 5, 114712, 0, '', 0, 'Potential target of the spell is creature, entry is Runecarver Slave (114712)'); + +DELETE FROM `serverside_spell` WHERE `Id`=193510; +INSERT INTO `serverside_spell` (`Id`, `DifficultyID`, `CategoryId`, `Dispel`, `Mechanic`, `Attributes`, `AttributesEx`, `AttributesEx2`, `AttributesEx3`, `AttributesEx4`, `AttributesEx5`, `AttributesEx6`, `AttributesEx7`, `AttributesEx8`, `AttributesEx9`, `AttributesEx10`, `AttributesEx11`, `AttributesEx12`, `AttributesEx13`, `AttributesEx14`, `Stances`, `StancesNot`, `Targets`, `TargetCreatureType`, `RequiresSpellFocus`, `FacingCasterFlags`, `CasterAuraState`, `TargetAuraState`, `ExcludeCasterAuraState`, `ExcludeTargetAuraState`, `CasterAuraSpell`, `TargetAuraSpell`, `ExcludeCasterAuraSpell`, `ExcludeTargetAuraSpell`, `CasterAuraType`, `TargetAuraType`, `ExcludeCasterAuraType`, `ExcludeTargetAuraType`, `CastingTimeIndex`, `RecoveryTime`, `CategoryRecoveryTime`, `StartRecoveryCategory`, `StartRecoveryTime`, `InterruptFlags`, `AuraInterruptFlags1`, `AuraInterruptFlags2`, `ChannelInterruptFlags1`, `ChannelInterruptFlags2`, `ProcFlags`, `ProcFlags2`, `ProcChance`, `ProcCharges`, `ProcCooldown`, `ProcBasePPM`, `MaxLevel`, `BaseLevel`, `SpellLevel`, `DurationIndex`, `RangeIndex`, `Speed`, `LaunchDelay`, `StackAmount`, `EquippedItemClass`, `EquippedItemSubClassMask`, `EquippedItemInventoryTypeMask`, `ContentTuningId`, `SpellName`, `ConeAngle`, `ConeWidth`, `MaxTargetLevel`, `MaxAffectedTargets`, `SpellFamilyName`, `SpellFamilyFlags1`, `SpellFamilyFlags2`, `SpellFamilyFlags3`, `SpellFamilyFlags4`, `DmgClass`, `PreventionType`, `AreaGroupId`, `SchoolMask`, `ChargeCategoryId`) VALUES +(193510, 0, 0, 0, 0, 0x100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 1, 0, 0, 0, -1, 0, 0, 0, 'Arise, Fallen', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +DELETE FROM `serverside_spell_effect` WHERE `SpellID`=193510; +INSERT INTO `serverside_spell_effect` (`SpellID`, `EffectIndex`, `DifficultyID`, `Effect`, `EffectAura`, `EffectAmplitude`, `EffectAttributes`, `EffectAuraPeriod`, `EffectBonusCoefficient`, `EffectChainAmplitude`, `EffectChainTargets`, `EffectItemType`, `EffectMechanic`, `EffectPointsPerResource`, `EffectPosFacing`, `EffectRealPointsPerLevel`, `EffectTriggerSpell`, `BonusCoefficientFromAP`, `PvpMultiplier`, `Coefficient`, `Variance`, `ResourceCoefficient`, `GroupSizeBasePointsCoefficient`, `EffectBasePoints`, `EffectMiscValue1`, `EffectMiscValue2`, `EffectRadiusIndex1`, `EffectRadiusIndex2`, `EffectSpellClassMask1`, `EffectSpellClassMask2`, `EffectSpellClassMask3`, `EffectSpellClassMask4`, `ImplicitTarget1`, `ImplicitTarget2`) VALUES +(193510, 0, 0, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN(167922, 193460, 243029, 193566); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(167922, 'spell_ymiron_the_fallen_king_power_periodic'), +(193460, 'spell_ymiron_the_fallen_king_bane_periodic'), +(243029, 'spell_ymiron_the_fallen_king_soul_siphon'), +(193566, 'spell_ymiron_the_fallen_king_arise_fallen_selector'); + +DELETE FROM `creature_text` WHERE `CreatureID`=96756; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(96756, 0, 0, 'Your souls will drift for eternity in the tides of the underworld!', 14, 0, 100, 0, 0, 54404, 102193, 0, 'Ymiron, the Fallen King to Player'), +(96756, 1, 0, 'Another drop in the sea of souls!', 14, 0, 100, 66, 0, 54367, 102185, 0, 'Ymiron, the Fallen King to Player'), +(96756, 2, 0, 'Mortals... I fell to your wretched kind once before. It WILL NOT happen again!', 14, 0, 100, 0, 0, 54403, 102191, 0, 'Ymiron, the Fallen King to Player'), +(96756, 3, 0, 'FLEE, COWARDS!', 14, 0, 100, 0, 0, 54360, 102175, 0, 'Ymiron, the Fallen King'), +(96756, 3, 1, 'COWER BEFORE ME!', 14, 0, 100, 0, 0, 54359, 102174, 0, 'Ymiron, the Fallen King'), +(96756, 3, 2, 'CRAVEN MAGGOTS!', 14, 0, 100, 0, 0, 54361, 102176, 0, 'Ymiron, the Fallen King'), +(96756, 4, 0, 'Know the bitter chill of death as I have!', 14, 0, 100, 0, 0, 54362, 102177, 0, 'Ymiron, the Fallen King'), +(96756, 4, 1, 'The winds of the frozen north still howl in these veins!', 14, 0, 100, 0, 0, 54364, 102178, 0, 'Ymiron, the Fallen King'), +(96756, 5, 0, 'The shadows of the underworld bend to me!', 14, 0, 100, 0, 0, 54357, 102171, 0, 'Ymiron, the Fallen King'), +(96756, 6, 0, 'The shadows of Helheim cut deeper than steel!', 14, 0, 100, 0, 0, 54358, 102173, 0, 'Ymiron, the Fallen King'), +(96756, 7, 0, 'Not... again... HARBARON! CAST THEIR SOULS INTO THE TIDES!', 14, 0, 100, 0, 0, 54366, 102182, 0, 'Ymiron, the Fallen King to Player'); + +UPDATE `creature_template_difficulty` SET `StaticFlags2`=`StaticFlags2`|0x02|0x04 WHERE `Entry`=96756; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 6bd0010f723..6ac6f93cc9e 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4697,6 +4697,22 @@ void SpellMgr::LoadSpellInfoCorrections() // ENDOF MARDUM SPELLS // + // MAW OF SOULS SPELLS + // + + // 193465 - Bane + ApplySpellFix({ 193465 }, [](SpellInfo* spellInfo) + { + ApplySpellEffectFix(spellInfo, EFFECT_0, [](SpellEffectInfo* spellEffectInfo) + { + // Normal difficulty should also be using the regular heroic+ AreaTriggerCreateProperties + spellEffectInfo->MiscValue = 5838; + }); + }); + + // ENDOF MAW OF SOULS SPELLS + + // // ANTORUS THE BURNING THRONE SPELLS // diff --git a/src/server/scripts/BrokenIsles/MawOfSouls/boss_ymiron_the_fallen_king.cpp b/src/server/scripts/BrokenIsles/MawOfSouls/boss_ymiron_the_fallen_king.cpp new file mode 100644 index 00000000000..514a386767a --- /dev/null +++ b/src/server/scripts/BrokenIsles/MawOfSouls/boss_ymiron_the_fallen_king.cpp @@ -0,0 +1,723 @@ +/* + * 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 "Containers.h" +#include "CreatureAI.h" +#include "CreatureAIImpl.h" +#include "InstanceScript.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellAuras.h" +#include "SpellScript.h" +#include "SharedDefines.h" +#include "TemporarySummon.h" +#include "maw_of_souls.h" + +enum YmironFallenKingSpells +{ + // Intro + SPELL_SOUL_SIPHON = 243029, + SPELL_SOUL_SIPHON_CHANNEL = 194665, + SPELL_KNEELING = 197227, + SPELL_SUICIDE = 117624, + + SPELL_POWER = 167922, + SPELL_DARK_SLASH = 193211, + SPELL_SCREAMS_OF_THE_DEAD = 193364, + SPELL_WINDS_OF_NORTHREND = 193977, + SPELL_BANE_AURA = 193460, + SPELL_BANE_MISSILE = 193463, + SPELL_BANE_AT_NHC_HEROIC = 193465, + SPELL_BANE_DAMAGE = 193513, // only on triggering unit of Bane + SPELL_BANE_NOVA = 200194, // AoE on party when Bane orb is triggered + SPELL_ARISE_FALLEN_ENABLER = 193510, + SPELL_ARISE_FALLEN_SELECTOR = 193566, + SPELL_ARISE_FALLEN_SUMMON = 193594, + SPELL_DESPAWN_AREA_TRIGGERS = 115905, + + SPELL_VIGOR = 203816, // stacking every 6s +}; + +enum YmironFallenKingSpellVisuals +{ + SPELL_VISUAL_SOUL_SIPHON = 52528, + SPELL_VISUAL_BANE_PRECAST = 50121, + SPELL_VISUAL_ARISE_FALLEN = 50259, + + SPELL_VISUAL_KIT_ARISE_FALLEN = 59548, +}; + +enum YmironFallenKingEvents +{ + EVENT_DARK_SLASH_CHECKER = 1, + EVENT_SCREAMS_OF_THE_DEAD, + EVENT_WINDS_OF_NORTHREND, + EVENT_BANE, + EVENT_ARISE_FALLEN +}; + +enum YmironFallenKingTexts +{ + SAY_INTRO1 = 0, // Your souls will drift for eternity in the tides of the underworld! + SAY_INTRO2 = 1, // Another drop in the sea of souls! + SAY_AGGRO = 2, // Mortals... I fell to your wretched kind once before. It WILL NOT happen again! + SAY_SCREAMS_OF_THE_DEAD = 3, // COWER BEFORE ME! + SAY_WINDS_OF_NORTHREND = 4, // Know the bitter chill of death as I have! + SAY_BANE = 5, // The shadows of the underworld bend to me! + SAY_ARISE_FALLEN = 6, // The shadows of Helheim cut deeper than steel! + SAY_DEATH = 7, // Not... again... HARBARON! CAST THEIR SOULS INTO THE TIDES! +}; + +enum YmironFallenKingActions +{ + ACTION_ACTIVATE = 1, +}; + +enum YmironFallenKingPaths +{ + PATH_INTRO_TOWARDS_SLAVES = 9675600, + PATH_INTRO_AWAY_FROM_SLAVES = 9675601 +}; + +constexpr Position YmironIntroJumpPos = { 7401.39f, 7281.7f, 44.0207f }; +constexpr Position YmironRespawnPos = { 7398.374f, 7277.1206f, 43.792637f, 5.724679946899414062f }; + +// 96756 - Ymiron, the Fallen King +struct boss_ymiron_the_fallen_king : public BossAI +{ + boss_ymiron_the_fallen_king(Creature* creature) : BossAI(creature, DATA_YMIRON), _firstScreamDone(false) { } + + void JustAppeared() override + { + scheduler.ClearValidator(); + + DoCastSelf(SPELL_KNEELING); + + me->SetPower(me->GetPowerType(), 80); + } + + void InitializeAI() override + { + if (instance->GetBossState(DATA_YMIRON) != NOT_STARTED) + me->Relocate(YmironRespawnPos); + } + + void Reset() override + { + BossAI::Reset(); + _firstScreamDone = false; + } + + 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 JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + + me->InterruptNonMeleeSpells(true); + + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); + + Talk(SAY_AGGRO); + + DoCastAOE(SPELL_POWER); + + scheduler.CancelAll(); + + // should turn to highest threat target after standing up + if (me->HasAura(SPELL_KNEELING)) + { + me->RemoveAurasDueToSpell(SPELL_KNEELING); + me->SetReactState(REACT_PASSIVE); + + scheduler.Schedule(1600ms, [this](TaskContext /*task*/) + { + me->SetReactState(REACT_AGGRESSIVE); + }); + } + + events.ScheduleEvent(EVENT_DARK_SLASH_CHECKER, 500ms); + events.ScheduleEvent(EVENT_SCREAMS_OF_THE_DEAD, 5900ms); + events.ScheduleEvent(EVENT_WINDS_OF_NORTHREND, 15100ms); + events.ScheduleEvent(EVENT_BANE, 22100ms); + } + + void UpdateAI(uint32 diff) override + { + scheduler.Update(diff); + + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + if (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_DARK_SLASH_CHECKER: + { + if (me->GetPower(me->GetPowerType()) >= 100) + { + DoCastVictim(SPELL_DARK_SLASH); + me->SetPower(me->GetPowerType(), 0); + } + events.Repeat(500ms); + break; + } + case EVENT_SCREAMS_OF_THE_DEAD: + { + if (_firstScreamDone) + Talk(SAY_SCREAMS_OF_THE_DEAD); + else + _firstScreamDone = true; + + DoCastAOE(SPELL_SCREAMS_OF_THE_DEAD); + events.Repeat(31s); + break; + } + case EVENT_WINDS_OF_NORTHREND: + Talk(SAY_WINDS_OF_NORTHREND); + DoCastAOE(SPELL_WINDS_OF_NORTHREND); + events.Repeat(29s); + break; + case EVENT_BANE: + { + Talk(SAY_BANE); + DoCastAOE(SPELL_BANE_AURA); + if (IsHeroicOrHigher()) + events.ScheduleEvent(EVENT_ARISE_FALLEN, 19100ms); + events.Repeat(59s); + break; + } + case EVENT_ARISE_FALLEN: + Talk(SAY_ARISE_FALLEN); + DoCastAOE(SPELL_ARISE_FALLEN_ENABLER); + DoCastAOE(SPELL_ARISE_FALLEN_SELECTOR); + break; + default: + break; + } + } + } + + void DoAction(int32 param) override + { + if (param != ACTION_ACTIVATE) + return; + + me->RemoveAurasDueToSpell(SPELL_KNEELING); + scheduler.Schedule(2s, [this](TaskContext /*task*/) + { + me->GetMotionMaster()->MoveJumpWithGravity(YmironIntroJumpPos, 24.0f, 25.31545448303222656, EVENT_JUMP); + }); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != EFFECT_MOTION_TYPE) + return; + + if (pointId != EVENT_JUMP) + return; + + scheduler.Schedule(1500ms, [this](TaskContext /*task*/) + { + me->GetMotionMaster()->MovePath(PATH_INTRO_TOWARDS_SLAVES, false); + }); + } + + void OnChannelFinished(SpellInfo const* spell) override + { + if (spell->Id != SPELL_SOUL_SIPHON_CHANNEL) + return; + + scheduler.Schedule(2s, [this](TaskContext task) + { + Talk(SAY_INTRO2); + + task.Schedule(5s, [this](TaskContext /*task*/) + { + me->GetMotionMaster()->MovePath(PATH_INTRO_AWAY_FROM_SLAVES, false); + }); + }); + } + + void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override + { + if (me->IsInCombat()) + return; + + if (pathId == PATH_INTRO_TOWARDS_SLAVES) + { + scheduler.Schedule(2s, [this](TaskContext /*task*/) + { + DoCastAOE(SPELL_SOUL_SIPHON_CHANNEL); + Talk(SAY_INTRO1); + }); + } + else if (pathId == PATH_INTRO_AWAY_FROM_SLAVES) + { + DoCastSelf(SPELL_KNEELING); + } + } + +private: + bool _firstScreamDone; +}; + +// Maw of Souls - Ymiron Activation Trigger +struct at_ymiron_the_fallen_king_activation : AreaTriggerAI +{ + at_ymiron_the_fallen_king_activation(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + void OnUnitEnter(Unit* unit) override + { + Player* player = unit->ToPlayer(); + if (!player) + return; + + if (player->IsGameMaster()) + return; + + InstanceScript* instance = at->GetInstanceScript(); + if (!instance) + return; + + Creature* ymiron = instance->GetCreature(DATA_YMIRON); + if (!ymiron) + return; + + ymiron->AI()->DoAction(ACTION_ACTIVATE); + + at->Remove(); + } +}; + +class YmironSoulSiphonVisual : public BasicEvent +{ +public: + explicit YmironSoulSiphonVisual(ObjectGuid ymironGUID, Unit* runecarver, float travelSpeed) : _ymironGUID(ymironGUID), _runecarver(runecarver), _travelSpeed(travelSpeed) { } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) override + { + if (_runecarver->isDead()) + return true; + + Unit* ymiron = ObjectAccessor::GetCreature(*_runecarver, _ymironGUID); + if (!ymiron) + return true; + + _runecarver->SendPlaySpellVisual(ymiron->GetPosition(), SPELL_VISUAL_SOUL_SIPHON, 0, 0, _travelSpeed, false, 0.0f); + + _runecarver->m_Events.AddEventAtOffset(this, 400ms); + return false; + } + +private: + ObjectGuid _ymironGUID; + Unit* _runecarver; + float _travelSpeed; +}; + +// 243029 - Soul Siphon +class spell_ymiron_the_fallen_king_soul_siphon : public AuraScript +{ + void OnAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + float travelSpeed = 15 + 0.180f * caster->GetDistance(GetTarget()); + GetTarget()->m_Events.AddEventAtOffset(new YmironSoulSiphonVisual(caster->GetGUID(), GetTarget(), travelSpeed), 1s); + } + + void TriggerSuicide() + { + Creature* targetCreature = GetTarget()->ToCreature(); + if (!targetCreature) + return; + + targetCreature->CastSpell(nullptr, SPELL_SUICIDE, true); + targetCreature->DespawnOrUnsummon(20s); + } + + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + if (!roll_chance_f(10)) + return; + + TriggerSuicide(); + } + + void OnAfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE) + return; + + TriggerSuicide(); + } + + void Register() override + { + AfterEffectApply += AuraEffectRemoveFn(spell_ymiron_the_fallen_king_soul_siphon::OnAfterApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_ymiron_the_fallen_king_soul_siphon::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_ymiron_the_fallen_king_soul_siphon::OnAfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +// 167922 - Power +class spell_ymiron_the_fallen_king_power_periodic : public AuraScript +{ + void OnPeriodic(AuraEffect const* aurEff) + { + int32 newPower = GetTarget()->GetPower(POWER_ENERGY) + (((aurEff->GetTickNumber() + 1) % 3 == 0) ? 6 : 7); + GetTarget()->SetPower(POWER_ENERGY, newPower); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_ymiron_the_fallen_king_power_periodic::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +class YmironBanePrecastVisual : public BasicEvent +{ +public: + explicit YmironBanePrecastVisual(Unit* caster, int8 remainingVisualsToSpawn) : _caster(caster), _remainingVisualsToSpawn(remainingVisualsToSpawn) { } + + static constexpr int8 BANE_VISUAL_NUM = 11; + static constexpr float BANE_VISUAL_TIME_OFFSET = 0.204545438289642f; + static constexpr float BANE_VISUAL_TIME_BASE = 0.75f; + + bool Execute(uint64 /*time*/, uint32 /*diff*/) override + { + float dist = frand(10.0f, 35.0f); + float angle = frand(0.0f, 2.0f * float(M_PI)); + Position dest(_caster->GetPositionX() + dist * std::cos(angle), _caster->GetPositionY() + dist * std::sin(angle), _caster->GetPositionZ()); + float travelSpeed = BANE_VISUAL_TIME_BASE + (BANE_VISUAL_TIME_OFFSET * _remainingVisualsToSpawn); + + _caster->SendPlaySpellVisual(dest, SPELL_VISUAL_BANE_PRECAST, 0, 0, travelSpeed, true); + + _remainingVisualsToSpawn--; + + if (_remainingVisualsToSpawn > 0) + { + _caster->m_Events.AddEventAtOffset(this, 200ms); + return false; + } + return true; + } + +private: + Unit* _caster; + int8 _remainingVisualsToSpawn; +}; + +// 193460 - Bane +class spell_ymiron_the_fallen_king_bane_periodic : public SpellScript +{ + void OnPrecast() override + { + GetCaster()->m_Events.AddEventAtOffset(new YmironBanePrecastVisual(GetCaster(), YmironBanePrecastVisual::BANE_VISUAL_NUM), 0s); + } + + void Register() override { } +}; + +// 193460 - Bane +class spell_ymiron_the_fallen_king_bane_periodic_AuraScript : public AuraScript +{ + static constexpr float BANE_MISSILE_DIST_OFFSET = 2.272f; + static constexpr float BANE_MISSILE_DIST_BASE = 10.0f; + static constexpr float BANE_MISSILE_ANGLE_OFFSET = 0.75f; + + static constexpr int8 BANE_MAX_TOTAL_TICKS = 4 + 4 + 14; + + void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& /*isPeriodic*/, int32& amplitude) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + if (caster->GetMap()->IsMythic() || caster->GetMap()->IsMythicPlus()) + amplitude = 1 * IN_MILLISECONDS; + + // defaults to 2000 for Normal and Heroic via. db2 data + } + + void SpawnBaneOrb(int8 tickNumber) + { + float dist = _distances[tickNumber - 1]; + float angle = _angles[tickNumber - 1]; + Position dest = { GetTarget()->GetPositionX() + dist * std::cos(angle), GetTarget()->GetPositionY() + dist * std::sin(angle), GetTarget()->GetPositionZ(), angle}; + GetTarget()->CastSpell(dest, SPELL_BANE_MISSILE, true); + } + + void OnAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + for (int8 i = 0; i < BANE_MAX_TOTAL_TICKS; i++) + { + float angle = Position::NormalizeOrientation(GetCaster()->GetOrientation() + (i * BANE_MISSILE_ANGLE_OFFSET)); + _angles[2 * i + 0] = angle; + _angles[2 * i + 1] = angle; + + float dist = BANE_MISSILE_DIST_BASE + (i * BANE_MISSILE_DIST_OFFSET); + _distances[2 * i + 0] = dist; + _distances[2 * i + 1] = dist; + } + Trinity::Containers::RandomShuffle(_angles); + Trinity::Containers::RandomShuffle(_distances); + } + + void OnPeriodic(AuraEffect const* aurEff) + { + if (aurEff->GetTickNumber() == 1 || (aurEff->GetTickNumber() == 2 && (GetTarget()->GetMap()->IsMythic() || GetTarget()->GetMap()->IsMythicPlus()))) + { + for (int8 i = 0; i < 4; i++) + SpawnBaneOrb(aurEff->GetTickNumber() + i); + } + else + SpawnBaneOrb(aurEff->GetTickNumber() + 8); + } + + void OnAfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_ARISE_FALLEN_ENABLER, true); + } + + void Register() override + { + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_ymiron_the_fallen_king_bane_periodic_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + AfterEffectApply += AuraEffectApplyFn(spell_ymiron_the_fallen_king_bane_periodic_AuraScript::OnAfterApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_ymiron_the_fallen_king_bane_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_ymiron_the_fallen_king_bane_periodic_AuraScript::OnAfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + +private: + std::array<float, BANE_MAX_TOTAL_TICKS * 2> _angles; + std::array<float, BANE_MAX_TOTAL_TICKS * 2> _distances; +}; + +struct at_ymiron_the_fallen_king_bane : AreaTriggerAI +{ + at_ymiron_the_fallen_king_bane(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) { } + + static constexpr float TIME_TO_TARGET_DIST_MULTIPLIER = 966.6466466434464f; + + void OnInitialize() override + { + Unit* caster = at->GetCaster(); + if (!caster) + return; + + float radius = at->GetExactDist(caster); + float timeToTarget = radius * TIME_TO_TARGET_DIST_MULTIPLIER; + float angle = at->GetOrientation(); + + AreaTriggerOrbitInfo orbitInfo; + orbitInfo.CounterClockwise = false; + orbitInfo.CanLoop = true; + orbitInfo.ElapsedTimeForMovement = 0; + orbitInfo.StartDelay = 0; + orbitInfo.Radius = radius; + orbitInfo.BlendFromRadius = radius; + orbitInfo.InitialAngle = angle; + orbitInfo.PathTarget = caster->GetGUID(); + at->InitOrbit(orbitInfo, timeToTarget); + } + + void OnUnitEnter(Unit* unit) override + { + Player* player = unit->ToPlayer(); + if (!player) + return; + + Unit* caster = at->GetCaster(); + if (!caster) + return; + + caster->CastSpell(player, SPELL_BANE_DAMAGE, true); + caster->CastSpell(nullptr, SPELL_BANE_NOVA, true); + + at->Remove(); + } +}; + +class YmironAriseFallenVisual : public BasicEvent +{ +public: + explicit YmironAriseFallenVisual(Unit* caster, Position dest) : _caster(caster), _dest(dest) { } + + static constexpr int8 BANE_VISUAL_NUM = 11; + static constexpr float BANE_VISUAL_TIME_OFFSET = 0.204545438289642f; + static constexpr float BANE_VISUAL_TIME_BASE = 0.75f; + + bool Execute(uint64 /*time*/, uint32 /*diff*/) override + { + _caster->CastSpell(_dest, SPELL_ARISE_FALLEN_SUMMON, true); + return true; + } + +private: + Unit* _caster; + Position _dest; +}; + +// 193566 - Arise, Fallen +class spell_ymiron_the_fallen_king_arise_fallen_selector : public SpellScript +{ + static constexpr float SPAWN_DIST_TO_TARGET = 3.5f; + + void HandleHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->RemoveAurasDueToSpell(SPELL_ARISE_FALLEN_ENABLER); + + std::vector<AreaTrigger*> atList = GetCaster()->GetAreaTriggers(SPELL_BANE_AT_NHC_HEROIC); + Trinity::Containers::RandomShuffle(atList); + + for (AreaTrigger* at : atList) + { + _baneATGUIDs.push(at->GetGUID()); + } + + _atsPerTarget = atList.size() / GetUnitTargetCountForEffect(EFFECT_0); + _remainingBaneATs = atList.size() % GetUnitTargetCountForEffect(EFFECT_0); + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if([](WorldObject* target) -> bool + { + return !target->IsPlayer(); + }); + } + + void HandleHitTarget(SpellEffIndex /*effIndex*/) + { + uint8 atNum = _atsPerTarget; + if (_remainingBaneATs > 0) + { + atNum++; + _remainingBaneATs--; + } + + for (uint8 i = 0; i < atNum; i++) + { + AreaTrigger* at = ObjectAccessor::GetAreaTrigger(*GetCaster(), _baneATGUIDs.front()); + _baneATGUIDs.pop(); + + if (!at) + return; + + Position dest = GetHitUnit()->GetFirstCollisionPosition(SPAWN_DIST_TO_TARGET, frand(0, 2.0f * float(M_PI))); + + float travelSpeed = frand(1.50f, 2.50f); + at->SendPlayOrphanSpellVisual(dest, SPELL_VISUAL_ARISE_FALLEN, travelSpeed, true); + + uint32 travelSpeedInMs = (uint32)(travelSpeed * 1000); + GetCaster()->m_Events.AddEventAtOffset(new YmironAriseFallenVisual(GetCaster(), dest), Milliseconds(travelSpeedInMs)); + at->Remove(); + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ymiron_the_fallen_king_arise_fallen_selector::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHit += SpellEffectFn(spell_ymiron_the_fallen_king_arise_fallen_selector::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_ymiron_the_fallen_king_arise_fallen_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY); + } + +private: + std::queue<ObjectGuid> _baneATGUIDs; + uint8 _atsPerTarget = 0; + uint8 _remainingBaneATs = 0; +}; + +// 98246 - Risen Warrior +struct npc_ymiron_the_fallen_king_risen_warrior : public ScriptedAI +{ + npc_ymiron_the_fallen_king_risen_warrior(Creature* creature) : ScriptedAI(creature) { } + + void JustAppeared() override + { + me->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_ARISE_FALLEN, 4, 2000); + + me->SetReactState(REACT_PASSIVE); + _scheduler.Schedule(2s, [this](TaskContext /*task*/) + { + me->SetReactState(REACT_AGGRESSIVE); + }); + + DoZoneInCombat(); + + _scheduler.Schedule(6s, [this](TaskContext task) + { + DoCastSelf(SPELL_VIGOR, true); + task.Repeat(6s); + }); + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + + UpdateVictim(); + } + +private: + TaskScheduler _scheduler; +}; + +void AddSC_boss_ymiron_the_fallen_king() +{ + RegisterMawOfSoulsCreatureAI(boss_ymiron_the_fallen_king); + RegisterAreaTriggerAI(at_ymiron_the_fallen_king_activation); + RegisterSpellScript(spell_ymiron_the_fallen_king_soul_siphon); + + RegisterSpellScript(spell_ymiron_the_fallen_king_power_periodic); + + RegisterSpellAndAuraScriptPair(spell_ymiron_the_fallen_king_bane_periodic, spell_ymiron_the_fallen_king_bane_periodic_AuraScript); + RegisterAreaTriggerAI(at_ymiron_the_fallen_king_bane); + + RegisterSpellScript(spell_ymiron_the_fallen_king_arise_fallen_selector); + RegisterMawOfSoulsCreatureAI(npc_ymiron_the_fallen_king_risen_warrior); +} diff --git a/src/server/scripts/BrokenIsles/MawOfSouls/instance_maw_of_souls.cpp b/src/server/scripts/BrokenIsles/MawOfSouls/instance_maw_of_souls.cpp new file mode 100644 index 00000000000..136d929850a --- /dev/null +++ b/src/server/scripts/BrokenIsles/MawOfSouls/instance_maw_of_souls.cpp @@ -0,0 +1,75 @@ +/* + * 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 "maw_of_souls.h" + +BossBoundaryData const boundaries = +{ + { DATA_YMIRON, new CircleBoundary({ 7382.8168f, 7300.5527f }, 55.0f)} +}; + +ObjectData const creatureData[] = +{ + { BOSS_YMIRON, DATA_YMIRON }, + { BOSS_HARBARON, DATA_HARBARON }, + { BOSS_HELYA, DATA_HELYA }, + { 0, 0 } // END +}; + +DoorData const doorData[] = +{ + { 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress } // END +}; + +DungeonEncounterData const encounters[] = +{ + { DATA_YMIRON, {{ 1822 }} }, + { DATA_HARBARON, {{ 1823 }} }, + { DATA_HELYA, {{ 1824 }} }, +}; + +class instance_maw_of_souls : public InstanceMapScript +{ +public: + instance_maw_of_souls() : InstanceMapScript(MOSScriptName, 1492) { } + + struct AddSC_instance_maw_of_souls_InstanceMapScript : public InstanceScript + { + AddSC_instance_maw_of_souls_InstanceMapScript(InstanceMap* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(EncounterCount); + LoadObjectData(creatureData, nullptr); + LoadDoorData(doorData); + LoadBossBoundaries(boundaries); + LoadDungeonEncounterData(encounters); + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new AddSC_instance_maw_of_souls_InstanceMapScript(map); + } +}; + +void AddSC_instance_maw_of_souls() +{ + new instance_maw_of_souls(); +} diff --git a/src/server/scripts/BrokenIsles/MawOfSouls/maw_of_souls.h b/src/server/scripts/BrokenIsles/MawOfSouls/maw_of_souls.h new file mode 100644 index 00000000000..b1fdaa60114 --- /dev/null +++ b/src/server/scripts/BrokenIsles/MawOfSouls/maw_of_souls.h @@ -0,0 +1,52 @@ +/* + * 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_MAW_OF_SOULS_H_ +#define DEF_MAW_OF_SOULS_H_ + +#include "CreatureAIImpl.h" + +#define DataHeader "MawOfSouls" +#define MOSScriptName "instance_maw_of_souls" + +uint32 const EncounterCount = 3; + +enum MOSDataTypes +{ + // Encounters + DATA_YMIRON = 0, + DATA_HARBARON, + DATA_HELYA, +}; + +enum MOSCreatureIds +{ + // Bosses + BOSS_YMIRON = 96756, + BOSS_HARBARON = 96754, + BOSS_HELYA = 96759, +}; + +template <class AI, class T> +inline AI* GetMawOfSoulsAI(T* obj) +{ + return GetInstanceAI<AI>(obj, MOSScriptName); +} + +#define RegisterMawOfSoulsCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetMawOfSoulsAI) + +#endif diff --git a/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp b/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp index 23c452eb8e5..aba5c241fac 100644 --- a/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp +++ b/src/server/scripts/BrokenIsles/broken_isles_script_loader.cpp @@ -17,6 +17,10 @@ // This is where scripts' loading functions should be declared: +// Maw of Souls +void AddSC_boss_ymiron_the_fallen_king(); +void AddSC_instance_maw_of_souls(); + // Trial of Valor void AddSC_boss_guarm(); void AddSC_instance_trial_of_valor(); @@ -29,6 +33,10 @@ void AddSC_zone_mardum(); // void Add${NameOfDirectory}Scripts() void AddBrokenIslesScripts() { + // Maw of Souls + AddSC_boss_ymiron_the_fallen_king(); + AddSC_instance_maw_of_souls(); + // Trial of Valor AddSC_boss_guarm(); AddSC_instance_trial_of_valor(); |