Scripts/BlackRookHold: Implement Amalgam of Souls encounter (#31025)

This commit is contained in:
Aqua Deus
2025-06-28 15:22:46 +02:00
committed by GitHub
parent a7a17280fa
commit c4c721cb7d
6 changed files with 829 additions and 7 deletions

View File

@@ -0,0 +1,107 @@
SET @CGUID := 6005163;
-- Creatures
DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+2;
INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `PhaseGroup`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `MovementType`, `npcflag`, `unit_flags`, `unit_flags2`, `unit_flags3`, `StringId`, `VerifiedBuild`) VALUES
(@CGUID+0, 103662, 1501, 7805, 7805, '1,2,8,23,24', '0', 0, 0, 0, 3221.896728515625, 7534.16845703125, 22.26258468627929687, 0.978301584720611572, 7200, 0, 0, 0, NULL, NULL, NULL, NULL, 'amalgam_door_stalker_left', 60822), -- Secret Door Stalker (Area: Black Rook Hold - Difficulty: 0) CreateObject1 (Auras: )
(@CGUID+1, 103662, 1501, 7805, 7805, '1,2,8,23,24', '0', 0, 0, 0, 3219.341064453125, 7535.9443359375, 24.50200271606445312, 0.885492563247680664, 7200, 0, 0, 0, NULL, NULL, NULL, NULL, 'amalgam_door_stalker_mid', 60822), -- Secret Door Stalker (Area: Black Rook Hold - Difficulty: 0) CreateObject1 (Auras: )
(@CGUID+2, 103662, 1501, 7805, 7805, '1,2,8,23,24', '0', 0, 0, 0, 3217.076416015625, 7537.67041015625, 22.50607109069824218, 0.794547736644744873, 7200, 0, 0, 0, NULL, NULL, NULL, NULL, 'amalgam_door_stalker_right', 60822); -- Secret Door Stalker (Area: Black Rook Hold - Difficulty: 0) CreateObject1 (Auras: )
DELETE FROM `creature_template_addon` WHERE `entry` IN (99090);
INSERT INTO `creature_template_addon` (`entry`, `PathId`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES
(99090, 0, 0, 0, 0, 0, 1, 0, 0, 9176, 0, 0, 0, ''); -- 99090 (Soul Echoes Stalker)
UPDATE `creature_template_difficulty` SET `ContentTuningID`=629, `StaticFlags1`=0x20000100, `VerifiedBuild`=60822 WHERE (`Entry`=99090 AND `DifficultyID`=23); -- 99090 (Soul Echoes Stalker) - Sessile, Floating
UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`=2, `LevelScalingDeltaMax`=2, `ContentTuningID`=629, `StaticFlags1`=0x10000000, `VerifiedBuild`=60822 WHERE (`Entry`=98542 AND `DifficultyID`=23); -- 98542 (Amalgam of Souls) - CanSwim
UPDATE `creature_template_difficulty` SET `ContentTuningID`=1279 WHERE (`Entry`=99664 AND `DifficultyID`=23);
UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`=1, `LevelScalingDeltaMax`=1, `ContentTuningID`=629, `StaticFlags1`=0x10000000, `VerifiedBuild`=60822 WHERE (`Entry`=99857 AND `DifficultyID`=23); -- 99857 (Lord Etheldrin Ravencrest) - CanSwim
UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`=1, `LevelScalingDeltaMax`=1, `ContentTuningID`=629, `StaticFlags1`=0x10000000, `VerifiedBuild`=60822 WHERE (`Entry`=99858 AND `DifficultyID`=23); -- 99858 (Lady Velandras Ravencrest) - CanSwim
UPDATE `creature_template_difficulty` SET `LevelScalingDeltaMin`=1, `LevelScalingDeltaMax`=1, `ContentTuningID`=629, `StaticFlags1`=0x10000000, `VerifiedBuild`=60822 WHERE (`Entry`=99426 AND `DifficultyID`=23); -- 99426 (Staellis Rivermoor) - CanSwim
UPDATE `creature_template_difficulty` SET `ContentTuningID`=629, `StaticFlags1`=0x20000100, `VerifiedBuild`=60822 WHERE (`Entry`=103662 AND `DifficultyID`=0); -- 103662 (Secret Door Stalker) - Sessile, Floating
UPDATE `creature_template` SET `faction`=16, `BaseAttackTime`=2000, `unit_flags`=0x2000000, `unit_flags2`=0x800, `unit_flags3`=0x41080001, `ScriptName`='npc_amalgam_of_souls_soul_echoes_stalker' WHERE `entry`=99090; -- Soul Echoes Stalker
UPDATE `creature_template` SET `unit_flags2`=0x800, `ScriptName`='boss_amalgam_of_souls' WHERE `entry`=98542; -- Amalgam of Souls
UPDATE `creature_template` SET `ScriptName`='npc_amalgam_of_souls_restless_soul' WHERE `entry`=99664;
UPDATE `creature_template` SET `BaseAttackTime`=2000, `unit_flags2`=0x800, `unit_flags3`=0x80000, `AIName`='SmartAI' WHERE `entry`=99426; -- Staellis Rivermoor
UPDATE `creature_template` SET `BaseAttackTime`=2000, `unit_flags2`=0x800, `unit_flags3`=0x80000, `ScriptName`='npc_amalgam_of_souls_lord_etheldrin_ravencrest' WHERE `entry`=99857; -- Lord Etheldrin Ravencrest
UPDATE `creature_template` SET `BaseAttackTime`=1500, `unit_flags2`=0x800, `unit_flags3`=0x80000, `AIName`='SmartAI' WHERE `entry`=99858; -- Lady Velandras Ravencrest
UPDATE `creature_template` SET `unit_flags3`=0x41000000 WHERE `entry`=103662; -- Secret Door Stalker
DELETE FROM `creature_equip_template` WHERE (`ID`=1 AND `CreatureID` IN (99426,99857,99858));
INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `AppearanceModID1`, `ItemVisual1`, `ItemID2`, `AppearanceModID2`, `ItemVisual2`, `ItemID3`, `AppearanceModID3`, `ItemVisual3`, `VerifiedBuild`) VALUES
(99426, 1, 118562, 0, 0, 0, 0, 0, 0, 0, 0, 60822), -- Staellis Rivermoor
(99857, 1, 116571, 0, 0, 0, 0, 0, 0, 0, 0, 60822), -- Lord Etheldrin Ravencrest
(99858, 1, 29437, 0, 0, 0, 0, 0, 0, 0, 0, 60822); -- Lady Velandras Ravencrest
DELETE FROM `creature_summon_groups` WHERE `summonerId`=98542;
INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES
(98542, 0, 0, 99664, 3265.507080078125, 7543.8681640625, 5.631319999694824218, 1.907930254936218261, 8, 0, 'Amalgam of Souls - Restless Souls'),
(98542, 0, 0, 99664, 3290.262939453125, 7574.5947265625, 5.631304740905761718, 2.955646991729736328, 8, 0, 'Amalgam of Souls - Restless Souls'),
(98542, 0, 0, 99664, 3286.51123046875, 7601.3115234375, 5.631319999694824218, 3.660738945007324218, 8, 0, 'Amalgam of Souls - Restless Souls'),
(98542, 0, 0, 99664, 3255.626708984375, 7622.0068359375, 5.631304740905761718, 4.62844085693359375, 8, 0, 'Amalgam of Souls - Restless Souls'),
(98542, 0, 0, 99664, 3228.8046875, 7616.51171875, 6.50103616714477539, 5.3057861328125, 8, 0, 'Amalgam of Souls - Restless Souls'),
(98542, 0, 0, 99664, 3212.127685546875, 7582.49462890625, 5.154406547546386718, 6.263723373413085937, 8, 0, 'Amalgam of Souls - Restless Souls'),
(98542, 0, 0, 99664, 3219.781005859375, 7560.11572265625, 5.68906402587890625, 0.588002622127532958, 8, 0, 'Amalgam of Souls - Restless Souls');
-- Areatriggers
UPDATE `areatrigger_template` SET `VerifiedBuild`=60822 WHERE (`Id`=9899 AND `IsCustom`=0);
UPDATE `areatrigger_template` SET `VerifiedBuild`=60822 WHERE (`Id`=10015 AND `IsCustom`=0);
DELETE FROM `areatrigger_create_properties` WHERE (`Id` IN (5167, 5293) AND `IsCustom`=0);
INSERT INTO `areatrigger_create_properties` (`Id`, `IsCustom`, `AreaTriggerId`, `IsAreatriggerCustom`, `Flags`, `MoveCurveId`, `ScaleCurveId`, `MorphCurveId`, `FacingCurveId`, `AnimId`, `AnimKitId`, `DecalPropertiesId`, `SpellForVisuals`, `TimeToTargetScale`, `Speed`, `Shape`, `ShapeData0`, `ShapeData1`, `ShapeData2`, `ShapeData3`, `ShapeData4`, `ShapeData5`, `ShapeData6`, `ShapeData7`, `ScriptName`, `VerifiedBuild`) VALUES
(5167, 0, 9899, 0, 82, 0, 0, 0, 0, -1, 0, 39, NULL, 30000, 8, 0, 3.5, 3.5, 0, 0, 0, 0, 0, 0, 'at_amalgam_of_souls_swirling_scythe', 60822), -- Spell: 195254 (Swirling Scythe)
(5293, 0, 10015, 0, 4, 0, 0, 0, 0, -1, 0, 0, NULL, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 'at_amalgam_of_souls_call_souls', 60822); -- Spell: 196925 (Call Souls)
-- Spells
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_amalgam_of_souls_soul_echoes_clone_caster', 'spell_amalgam_of_souls_soulgorge', 'spell_amalgam_of_souls_call_souls', 'spell_amalgam_of_souls_soul_burst');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(194981, 'spell_amalgam_of_souls_soul_echoes_clone_caster'),
(196930, 'spell_amalgam_of_souls_soulgorge'),
(196078, 'spell_amalgam_of_souls_call_souls'),
(196587, 'spell_amalgam_of_souls_soul_burst');
-- Texts
DELETE FROM `creature_text` WHERE `CreatureID` IN (98542, 99857);
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(98542, 0, 0, 'Consume! Devour!', 14, 0, 100, 0, 0, 54518, 100957, 0, 'Amalgam of Souls'),
(98542, 1, 0, 'The harvest has come!', 14, 0, 100, 0, 0, 54516, 100995, 0, 'Amalgam of Souls'),
(98542, 2, 0, 'Leave this meager vessel, and join us...', 14, 0, 100, 0, 0, 54564, 100994, 0, 'Amalgam of Souls'),
(98542, 3, 0, 'I feed on your essence...', 14, 0, 100, 0, 0, 54522, 100993, 0, 'Amalgam of Souls'),
(98542, 4, 0, 'Ancient souls of the Black Rook, rise and join our chorus!', 14, 0, 100, 0, 0, 54563, 100997, 0, 'Amalgam of Souls'),
(98542, 5, 0, 'This energy... it is too much!', 14, 0, 100, 0, 0, 54521, 100998, 0, 'Amalgam of Souls'),
(99857, 0, 0, 'I... understand now. You... you must find Kur\'talos. You must put a stop to this.', 12, 0, 100, 0, 0, 54558, 101007, 0, 'Lord Etheldrin Ravencrest');
-- Conditions
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (196930, 205210, 205211, 205212);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 196930, 0, 0, 51, 0, 5, 98542, 0, '', 0, 0, 0, '', 'Spell \'Soulgorge\' can only hit \'Amalgam of Souls\''),
(13, 1, 205210, 0, 0, 58, 0, 0, 0, 0, 'amalgam_door_stalker_left', 0, 0, 0, '', 'Spell \'Secret Door Channel - Staellis Left\' can only hit \'Secret Door Stalker\''),
(13, 1, 205211, 0, 0, 58, 0, 0, 0, 0, 'amalgam_door_stalker_mid', 0, 0, 0, '', 'Spell \'Secret Door Channel - Lady V Mid\' can only hit \'Secret Door Stalker\''),
(13, 1, 205212, 0, 0, 58, 0, 0, 0, 0, 'amalgam_door_stalker_right', 0, 0, 0, '', 'Spell \'Secret Door Channel - Lord E Right\' can only hit \'Secret Door Stalker\'');
-- Conversation
DELETE FROM `conversation_actors` WHERE (`ConversationId`=754 AND `Idx` IN (2,1,0));
INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES
(754, 50270, 2, 99857, 0, 0, 0, 60822), -- Full: 0x204254BBA0618440000578000034D42F Creature/0 R4245/S1400 Map: 1501 (Black Rook Hold) Entry: 99857 (Lord Etheldrin Ravencrest) Low: 3462191
(754, 50272, 1, 99858, 0, 0, 0, 60822), -- Full: 0x204254BBA0618480000578000034D42F Creature/0 R4245/S1400 Map: 1501 (Black Rook Hold) Entry: 99858 (Lady Velandras Ravencrest) Low: 3462191
(754, 50273, 0, 99426, 0, 0, 0, 60822); -- Full: 0x204254BBA0611880000578000034D42F Creature/0 R4245/S1400 Map: 1501 (Black Rook Hold) Entry: 99426 (Staellis Rivermoor) Low: 3462191
DELETE FROM `conversation_line_template` WHERE `Id` IN (1792, 1791, 1790);
INSERT INTO `conversation_line_template` (`Id`, `UiCameraID`, `ActorIdx`, `Flags`, `ChatType`, `VerifiedBuild`) VALUES
(1792, 0, 2, 0, 1, 60822),
(1791, 0, 1, 0, 0, 60822),
(1790, 0, 0, 0, 0, 60822);
DELETE FROM `conversation_template` WHERE `Id` IN (754);
INSERT INTO `conversation_template` (`Id`, `FirstLineID`, `TextureKitId`, `ScriptName`, `VerifiedBuild`) VALUES
(754, 1790, 0, 'conversation_amalgam_of_souls_outro', 60822);
-- SAI
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (99858, 99426) AND `source_type`=0;
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `Difficulties`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param_string`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `action_param7`, `action_param_string`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_param_string`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(99858, 0, 0, 0, '', 63, 0, 100, 0, 0, 0, 0, 0, 0, '', 90, 8, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Lady Velandras Ravencrest - Just Created - Set StandState: Kneel'),
(99426, 0, 0, 0, '', 63, 0, 100, 0, 0, 0, 0, 0, 0, '', 90, 8, 0, 0, 0, 0, 0, 0, NULL, 1, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 'Staellis Rivermoor - Just Created - Set StandState: Kneel');
DELETE FROM `instance_template` WHERE `map`=1501;
INSERT INTO `instance_template` (`map`, `parent`, `script`) VALUES
(1501, 0, 'instance_black_rook_hold');

View File

@@ -4744,6 +4744,24 @@ void SpellMgr::LoadSpellInfoCorrections()
// ENDOF MAW OF SOULS SPELLS
//
// BLACK ROOK HOLD SPELLS
//
// Soul Echoes
ApplySpellFix({ 194981 }, [](SpellInfo* spellInfo)
{
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // Vision Range (AOI)
});
// Soulgorge
ApplySpellFix({ 196930 }, [](SpellInfo* spellInfo)
{
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(7); // 10 yd
});
// ENDOF BLACK ROOK HOLD SPELLS
//
// ANTORUS THE BURNING THRONE SPELLS
//

View File

@@ -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_BLACK_ROOK_HOLD_H_
#define DEF_BLACK_ROOK_HOLD_H_
#include "CreatureAIImpl.h"
#define DataHeader "BlackRookHold"
#define BRHScriptName "instance_black_rook_hold"
constexpr uint32 EncounterCount = 4;
enum BRHDataTypes : uint8
{
// Encounters
DATA_AMALGAM_OF_SOULS = 0,
DATA_ILLYSANNA_RAVENCREST,
DATA_SMASHPITE_THE_HATEFUL,
DATA_LORD_KURTALOS_RAVENCREST,
DATA_BOSS_1_POST_BOSS_DOOR
};
enum BRHCreatureIds
{
// Bosses
BOSS_AMALGAM_OF_SOULS = 98542,
BOSS_ILLYSANNA_RAVENCREST = 98696,
BOSS_SMASHPITE_THE_HATEFUL = 98949,
BOSS_LORD_KURTALOS_RAVENCREST = 94923
};
enum BRHGameObjects
{
GO_BOSS_1_DOOR_1 = 247403,
GO_BOSS_1_DOOR_2 = 247404,
GO_BOSS_1_DOOR_3 = 247405,
GO_BOSS_1_DOOR_4 = 247406,
GO_BOSS_1_POST_BOSS_DOOR = 247407
};
template <class AI, class T>
inline AI* GetBlackRookHoldAI(T* obj)
{
return GetInstanceAI<AI>(obj, BRHScriptName);
}
#define RegisterBlackRookHoldCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackRookHoldAI)
#endif

View File

@@ -0,0 +1,542 @@
/*
* 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 "Conversation.h"
#include "ConversationAI.h"
#include "Creature.h"
#include "GameObject.h"
#include "InstanceScript.h"
#include "MotionMaster.h"
#include "PathGenerator.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h"
#include "SharedDefines.h"
#include "SpellAuras.h"
#include "SpellHistory.h"
#include "SpellScript.h"
#include "black_rook_hold.h"
enum AmalgamOfSoulsSpells
{
SPELL_SWIRLING_SCYTHE = 195254,
SPELL_SWIRLING_SCYTHE_DAMAGE = 196517,
SPELL_REAP_SOUL = 194956,
SPELL_SOUL_ECHOES = 194966,
SPELL_SOUL_ECHOES_CLONE_CASTER = 194981,
SPELL_SOUL_ECHOES_DAMAGE = 194960,
SPELL_SOULGORGE = 196930,
SPELL_CALL_SOULS = 196078,
SPELL_CALL_SOULS_AREATRIGGER = 196925,
SPELL_SOUL_BURST = 196587,
SPELL_TRANSFORM_TIMER = 224032, // Achievement
// Outro
SPELL_SUMMON_MINIBOSS_A = 196619,
SPELL_SUMMON_MINIBOSS_B = 196620,
SPELL_SUMMON_MINIBOSS_C = 196646,
SPELL_START_SPLIT_CONVERSATION = 197075,
SPELL_SECRET_DOOR_CHANNEL_LEFT = 205210,
SPELL_SECRET_DOOR_CHANNEL_MID = 205211,
SPELL_SECRET_DOOR_CHANNEL_RIGHT = 205212
};
enum AmalgamOfSoulsEvents
{
EVENT_SWIRLING_SCYTE = 1,
EVENT_REAP_SOUL,
EVENT_SOUL_ECHOES,
EVENT_CHECK_ALIVE_SOULS,
EVENT_SOUL_BURST,
EVENT_OUTRO
};
enum AmalgamOfSoulsTexts
{
SAY_AGGRO = 0,
SAY_SWIRLING_SCYTHE = 1,
SAY_SOUL_ECHOES = 2,
SAY_REAP_SOUL = 3,
SAY_CALL_SOULS = 4,
SAY_SOUL_BURST = 5,
SAY_OUTRO = 0
};
enum AmalgamOfSoulsConversation
{
NPC_LORD_ETHELDRIN_RAVENCREST = 99857,
NPC_LADY_VELANDRAS_RAVENCREST = 99858,
NPC_STAELLIS_RIVERMOOR = 99426,
POINT_SECRET_DOOR = 0
};
enum AmalgamOfSoulsMisc
{
POINT_START_CALL_SOULS = 0,
POINT_RESTLESS_SOUL = 0,
POINT_AMALGAM_OF_SOULS = 1,
SUMMON_GROUP_RESTLESS_SOULS = 0,
NPC_RESTLESS_SOUL = 99664,
NPC_SOUL_ECHO = 99090,
SOUL_ECHOES_STALKER_ANIM_KIT_1 = 9038,
SOUL_ECHOES_STALKER_ANIM_KIT_2 = 9039,
SOUL_ECHOES_STALKER_ANIM_KIT_3 = 9176
};
constexpr uint16 RandomAnimKit[3] =
{
SOUL_ECHOES_STALKER_ANIM_KIT_1,
SOUL_ECHOES_STALKER_ANIM_KIT_2,
SOUL_ECHOES_STALKER_ANIM_KIT_3
};
constexpr Position AmalgamOfSoulsPosition = { 3252.25f, 7581.75f, 12.884051f };
constexpr Position EtheldrinOutroPosition = { 3226.6829f, 7552.8877f, 15.355894f };
constexpr Position VelandrasOutroPosition = { 3228.9f, 7548.45f, 14.977584f };
constexpr Position StaellisOutroPosition = { 3233.22f, 7548.13f, 15.162442f };
// 98542 - Amalgam of Souls
struct boss_amalgam_of_souls : public BossAI
{
boss_amalgam_of_souls(Creature* creature) : BossAI(creature, DATA_AMALGAM_OF_SOULS), _callSoulsTriggered(false) { }
void DespawnSoulEchoes() const
{
std::list<Creature*> soulEchoes;
GetCreatureListWithEntryInGrid(soulEchoes, me, NPC_SOUL_ECHO, 100.0f);
for (Creature* soulEcho : soulEchoes)
soulEcho->DespawnOrUnsummon();
}
void Reset() override
{
_Reset();
_callSoulsTriggered = false;
}
void JustDied(Unit* /*killer*/) override
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
_JustDied();
DespawnSoulEchoes();
DoCastSelf(SPELL_SUMMON_MINIBOSS_A);
DoCastSelf(SPELL_SUMMON_MINIBOSS_B);
DoCastSelf(SPELL_SUMMON_MINIBOSS_C);
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
summons.DespawnAll();
DespawnSoulEchoes();
_EnterEvadeMode();
_DespawnAtEvade();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
events.ScheduleEvent(EVENT_SWIRLING_SCYTE, 8100ms);
events.ScheduleEvent(EVENT_SOUL_ECHOES, 16900ms);
events.ScheduleEvent(EVENT_REAP_SOUL, 20200ms);
}
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id == POINT_START_CALL_SOULS)
{
Talk(SAY_CALL_SOULS);
DoCastSelf(SPELL_CALL_SOULS);
DoCastSelf(SPELL_CALL_SOULS_AREATRIGGER, TRIGGERED_FULL_MASK);
events.ScheduleEvent(EVENT_CHECK_ALIVE_SOULS, 1s);
}
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
if (!IsHeroicOrHigher() || _callSoulsTriggered || !me->HealthBelowPctDamaged(50, damage))
return;
_callSoulsTriggered = true;
DoStopAttack();
me->SetReactState(REACT_PASSIVE);
events.CancelEvent(EVENT_SWIRLING_SCYTE);
events.CancelEvent(EVENT_SOUL_ECHOES);
events.CancelEvent(EVENT_REAP_SOUL);
me->GetMotionMaster()->MovePoint(POINT_START_CALL_SOULS, me->GetHomePosition(), false);
}
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_SWIRLING_SCYTE:
{
Talk(SAY_SWIRLING_SCYTHE);
DoCastVictim(SPELL_SWIRLING_SCYTHE);
events.Repeat(20600ms);
break;
}
case EVENT_REAP_SOUL:
{
Talk(SAY_REAP_SOUL);
DoCastVictim(SPELL_REAP_SOUL);
events.Repeat(13400ms);
break;
}
case EVENT_SOUL_ECHOES:
{
Talk(SAY_SOUL_ECHOES);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
DoCast(target, SPELL_SOUL_ECHOES);
events.Repeat(26700ms);
break;
}
case EVENT_CHECK_ALIVE_SOULS:
{
if (me->FindNearestCreature(NPC_RESTLESS_SOUL, 100.0f))
events.Repeat(500ms);
else
events.ScheduleEvent(EVENT_SOUL_BURST, 5s);
break;
}
case EVENT_SOUL_BURST:
{
Talk(SAY_SOUL_BURST);
me->RemoveAurasDueToSpell(SPELL_CALL_SOULS_AREATRIGGER);
DoCastSelf(SPELL_SOUL_BURST);
events.ScheduleEvent(EVENT_SWIRLING_SCYTE, 14200ms);
events.ScheduleEvent(EVENT_SOUL_ECHOES, 23s);
events.ScheduleEvent(EVENT_REAP_SOUL, 26400ms);
break;
}
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
}
private:
bool _callSoulsTriggered;
};
// 99090 - Soul Echoes Stalker
struct npc_amalgam_of_souls_soul_echoes_stalker : public ScriptedAI
{
npc_amalgam_of_souls_soul_echoes_stalker(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(WorldObject* summoner) override
{
me->SetReactState(REACT_PASSIVE);
me->SetAIAnimKitId(RandomAnimKit[urand(SOUL_ECHOES_STALKER_ANIM_KIT_1, SOUL_ECHOES_STALKER_ANIM_KIT_3)]);
summoner->CastSpell(me, SPELL_SOUL_ECHOES_CLONE_CASTER, TRIGGERED_FULL_MASK);
}
};
// 99664 - Restless Soul
struct npc_amalgam_of_souls_restless_soul : public ScriptedAI
{
npc_amalgam_of_souls_restless_soul(Creature* creature) : ScriptedAI(creature) { }
void JustAppeared() override
{
me->SetReactState(REACT_PASSIVE);
DoCastSelf(SPELL_TRANSFORM_TIMER);
me->GetMotionMaster()->MovePoint(POINT_RESTLESS_SOUL, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + frand(10.0f, 12.0f), false);
}
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id == POINT_RESTLESS_SOUL)
{
Creature* amalgamOfSouls = me->GetInstanceScript()->GetCreature(DATA_AMALGAM_OF_SOULS);
if (!amalgamOfSouls)
return;
me->GetMotionMaster()->MovePoint(POINT_AMALGAM_OF_SOULS, AmalgamOfSoulsPosition);
}
}
};
// 99857 - Lord Etheldrin Ravencrest
struct npc_amalgam_of_souls_lord_etheldrin_ravencrest : public ScriptedAI
{
npc_amalgam_of_souls_lord_etheldrin_ravencrest(Creature* creature) : ScriptedAI(creature) { }
void JustAppeared() override
{
me->SetStandState(UNIT_STAND_STATE_KNEEL);
DoCastSelf(SPELL_START_SPLIT_CONVERSATION);
}
void MovementInform(uint32 /*type*/, uint32 id) override
{
if (id != POINT_SECRET_DOOR)
return;
Milliseconds delay = 1s;
_scheduler.Schedule(1s, [this](TaskContext /*task*/)
{
Talk(SAY_OUTRO);
});
delay += 4s;
_scheduler.Schedule(delay, [this](TaskContext /*task*/)
{
if (Creature* velandras = me->FindNearestCreature(NPC_LADY_VELANDRAS_RAVENCREST, 100.0f))
{
velandras->CastSpell(velandras, SPELL_SECRET_DOOR_CHANNEL_MID);
velandras->DespawnOrUnsummon(6s);
}
if (Creature* staellis = me->FindNearestCreature(NPC_STAELLIS_RIVERMOOR, 100.0f))
{
staellis->CastSpell(staellis, SPELL_SECRET_DOOR_CHANNEL_LEFT);
staellis->DespawnOrUnsummon(6s);
}
DoCastSelf(SPELL_SECRET_DOOR_CHANNEL_RIGHT);
me->DespawnOrUnsummon(6s);
});
delay += 6s;
_scheduler.Schedule(delay, [this](TaskContext /*task*/)
{
if (GameObject* door = me->GetInstanceScript()->GetGameObject(DATA_BOSS_1_POST_BOSS_DOOR))
door->SetGoState(GO_STATE_ACTIVE);
});
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
};
// 194981 - Soul Echoes
class spell_amalgam_of_souls_soul_echoes_clone_caster : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SOUL_ECHOES_DAMAGE });
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
Unit* target = GetTarget();
target->CastSpell(target, SPELL_SOUL_ECHOES_DAMAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_amalgam_of_souls_soul_echoes_clone_caster::OnRemove, EFFECT_0, SPELL_AURA_CLONE_CASTER, AURA_EFFECT_HANDLE_REAL);
}
};
// 196930 - Soulgorge
class spell_amalgam_of_souls_soulgorge : public AuraScript
{
void OnApply(AuraEffect const* /*auraEffect*/, AuraEffectHandleModes /*mode*/) const
{
if (Creature* creatureCaster = Object::ToCreature(GetCaster()))
creatureCaster->DespawnOrUnsummon(3s);
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_amalgam_of_souls_soulgorge::OnApply, EFFECT_1, SPELL_AURA_MOD_SCALE, AURA_EFFECT_HANDLE_REAL);
}
};
// 196078 - Call Souls
class spell_amalgam_of_souls_call_souls : public SpellScript
{
void HandleHitTarget(SpellEffIndex /*effIndex*/) const
{
if (Creature* creatureCaster = GetCaster()->ToCreature())
creatureCaster->SummonCreatureGroup(SUMMON_GROUP_RESTLESS_SOULS);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_amalgam_of_souls_call_souls::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 196587 - Soul Burst
class spell_amalgam_of_souls_soul_burst : public SpellScript
{
void HandleAfterCast() const
{
if (Creature* creatureCaster = GetCaster()->ToCreature())
{
creatureCaster->SetReactState(REACT_AGGRESSIVE);
creatureCaster->RemoveAurasDueToSpell(SPELL_SOULGORGE);
}
}
void Register() override
{
AfterCast += SpellCastFn(spell_amalgam_of_souls_soul_burst::HandleAfterCast);
}
};
// 195254 - Swirling Scythe
// ID - 5167
/* THIS AREATRIGGER SHOULD ROTATE, BUT IT DOESNT, BECAUSE ROLLPITCHYAW IS NYI */
struct at_amalgam_of_souls_swirling_scythe : AreaTriggerAI
{
using AreaTriggerAI::AreaTriggerAI;
void OnInitialize() override
{
Position destPos = at->GetPosition();
PathGenerator path(at);
path.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), false);
at->InitSplines(path.GetPath());
}
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
unit->CastSpell(unit, SPELL_SWIRLING_SCYTHE_DAMAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
};
// 196925 - Call Souls
// ID - 5293
struct at_amalgam_of_souls_call_souls : AreaTriggerAI
{
using AreaTriggerAI::AreaTriggerAI;
void OnUnitEnter(Unit* unit) override
{
if (unit->GetEntry() != NPC_RESTLESS_SOUL)
return;
Unit* caster = at->GetCaster();
if (!caster)
return;
unit->CastSpell(caster, SPELL_SOULGORGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
};
// 197075 - Start Split Conversation
// ID - 754
class conversation_amalgam_of_souls_outro : public ConversationAI
{
public:
conversation_amalgam_of_souls_outro(Conversation* conversation) : ConversationAI(conversation) { }
void OnStart() override
{
LocaleConstant privateOwnerLocale = conversation->GetPrivateObjectOwnerLocale();
_events.ScheduleEvent(EVENT_OUTRO, conversation->GetLastLineEndTime(privateOwnerLocale));
}
void OnUpdate(uint32 diff) override
{
_events.Update(diff);
switch (_events.ExecuteEvent())
{
case EVENT_OUTRO:
{
if (Creature* etheldrin = conversation->FindNearestCreature(NPC_LORD_ETHELDRIN_RAVENCREST, 100.0f))
{
etheldrin->SetStandState(UNIT_STAND_STATE_STAND);
etheldrin->GetMotionMaster()->MovePoint(POINT_SECRET_DOOR, EtheldrinOutroPosition);
}
if (Creature* velandras = conversation->FindNearestCreature(NPC_LADY_VELANDRAS_RAVENCREST, 100.0f))
{
velandras->SetStandState(UNIT_STAND_STATE_STAND);
velandras->GetMotionMaster()->MovePoint(POINT_SECRET_DOOR, VelandrasOutroPosition);
}
if (Creature* staellis = conversation->FindNearestCreature(NPC_STAELLIS_RIVERMOOR, 100.0f))
{
staellis->SetStandState(UNIT_STAND_STATE_STAND);
staellis->GetMotionMaster()->MovePoint(POINT_SECRET_DOOR, StaellisOutroPosition);
}
break;
}
default:
break;
}
}
private:
EventMap _events;
};
void AddSC_boss_amalgam_of_souls()
{
RegisterBlackRookHoldCreatureAI(boss_amalgam_of_souls);
RegisterBlackRookHoldCreatureAI(npc_amalgam_of_souls_soul_echoes_stalker);
RegisterBlackRookHoldCreatureAI(npc_amalgam_of_souls_restless_soul);
RegisterBlackRookHoldCreatureAI(npc_amalgam_of_souls_lord_etheldrin_ravencrest);
RegisterSpellScript(spell_amalgam_of_souls_soul_echoes_clone_caster);
RegisterSpellScript(spell_amalgam_of_souls_soulgorge);
RegisterSpellScript(spell_amalgam_of_souls_call_souls);
RegisterSpellScript(spell_amalgam_of_souls_soul_burst);
RegisterAreaTriggerAI(at_amalgam_of_souls_swirling_scythe);
RegisterAreaTriggerAI(at_amalgam_of_souls_call_souls);
RegisterConversationAI(conversation_amalgam_of_souls_outro);
}

View File

@@ -0,0 +1,87 @@
/*
* 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 "black_rook_hold.h"
BossBoundaryData const boundaries =
{
{ DATA_AMALGAM_OF_SOULS, new CircleBoundary(Position(3251.350098f, 7582.790039f), 40.0f) }
};
ObjectData const creatureData[] =
{
{ BOSS_AMALGAM_OF_SOULS, DATA_AMALGAM_OF_SOULS },
{ BOSS_ILLYSANNA_RAVENCREST, DATA_ILLYSANNA_RAVENCREST },
{ BOSS_SMASHPITE_THE_HATEFUL, DATA_SMASHPITE_THE_HATEFUL },
{ BOSS_LORD_KURTALOS_RAVENCREST, DATA_LORD_KURTALOS_RAVENCREST },
{ 0, 0 } // END
};
ObjectData const gameobjectData[] =
{
{ GO_BOSS_1_POST_BOSS_DOOR, DATA_BOSS_1_POST_BOSS_DOOR },
{ 0, 0 } // END
};
DoorData const doorData[] =
{
{ GO_BOSS_1_DOOR_1, DATA_AMALGAM_OF_SOULS, EncounterDoorBehavior::OpenWhenNotInProgress },
{ GO_BOSS_1_DOOR_2, DATA_AMALGAM_OF_SOULS, EncounterDoorBehavior::OpenWhenNotInProgress },
{ GO_BOSS_1_DOOR_3, DATA_AMALGAM_OF_SOULS, EncounterDoorBehavior::OpenWhenNotInProgress },
{ GO_BOSS_1_DOOR_4, DATA_AMALGAM_OF_SOULS, EncounterDoorBehavior::OpenWhenNotInProgress },
{ 0, 0, EncounterDoorBehavior::OpenWhenNotInProgress }
};
DungeonEncounterData const encounters[] =
{
{ DATA_AMALGAM_OF_SOULS, {{ 1832 }} },
{ DATA_ILLYSANNA_RAVENCREST, {{ 1833 }} },
{ DATA_SMASHPITE_THE_HATEFUL, {{ 1834 }} },
{ DATA_LORD_KURTALOS_RAVENCREST, {{ 1835 }} },
};
class instance_black_rook_hold : public InstanceMapScript
{
public:
instance_black_rook_hold() : InstanceMapScript(BRHScriptName, 1501) { }
struct instance_black_rook_hold_InstanceMapScript: public InstanceScript
{
instance_black_rook_hold_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, gameobjectData);
LoadDoorData(doorData);
LoadBossBoundaries(boundaries);
LoadDungeonEncounterData(encounters);
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_black_rook_hold_InstanceMapScript(map);
}
};
void AddSC_instance_black_rook_hold()
{
new instance_black_rook_hold();
}

View File

@@ -17,9 +17,6 @@
// This is where scripts' loading functions should be declared:
void AddSC_zone_dalaran_broken_isle();
void AddSC_zone_mardum();
// Maw of Souls
void AddSC_boss_ymiron_the_fallen_king();
void AddSC_instance_maw_of_souls();
@@ -28,16 +25,18 @@ void AddSC_instance_maw_of_souls();
void AddSC_boss_guarm();
void AddSC_instance_trial_of_valor();
// Black Rook Hold
void AddSC_boss_amalgam_of_souls();
void AddSC_instance_black_rook_hold();
// Orderhalls
void AddSC_orderhall_warrior();
void AddSC_zone_mardum();
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
void AddBrokenIslesScripts()
{
AddSC_zone_dalaran_broken_isle();
AddSC_zone_mardum();
// Maw of Souls
AddSC_boss_ymiron_the_fallen_king();
AddSC_instance_maw_of_souls();
@@ -46,6 +45,10 @@ void AddBrokenIslesScripts()
AddSC_boss_guarm();
AddSC_instance_trial_of_valor();
// Orderhalls
// Black Rook Hold
AddSC_boss_amalgam_of_souls();
AddSC_instance_black_rook_hold();
AddSC_orderhall_warrior();
AddSC_zone_mardum();
}