mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Scripts/MawOfSouls: Implemented Ymiron, the Fallen King encounter (#29987)
This commit is contained in:
100
sql/updates/world/master/2024_05_22_02_world.sql
Normal file
100
sql/updates/world/master/2024_05_22_02_world.sql
Normal file
@@ -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;
|
||||
@@ -4696,6 +4696,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
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
52
src/server/scripts/BrokenIsles/MawOfSouls/maw_of_souls.h
Normal file
52
src/server/scripts/BrokenIsles/MawOfSouls/maw_of_souls.h
Normal file
@@ -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
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user