Merge branch 'master' into Playerbot
This commit is contained in:
@@ -37,7 +37,7 @@ DELETE FROM `spell_script_names` WHERE `spell_id` = 30745;
|
|||||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
(30745, 'spell_target_fissures');
|
(30745, 'spell_target_fissures');
|
||||||
|
|
||||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 3) AND (`SourceEntry` = 30745);
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 30745);
|
||||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
(13, 1, 30745, 0, 0, 31, 0, 3, 17083, 151090, 0, 0, 0, '', 'Target Fissures (30745) can only target Fel Orc Convert (17083) of specific guids'),
|
(13, 1, 30745, 0, 0, 31, 0, 3, 17083, 151090, 0, 0, 0, '', 'Target Fissures (30745) can only target Fel Orc Convert (17083) of specific guids'),
|
||||||
(13, 1, 30745, 0, 1, 31, 0, 3, 17083, 151091, 0, 0, 0, '', 'Target Fissures (30745) can only target Fel Orc Convert (17083) of specific guids'),
|
(13, 1, 30745, 0, 1, 31, 0, 3, 17083, 151091, 0, 0, 0, '', 'Target Fissures (30745) can only target Fel Orc Convert (17083) of specific guids'),
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_05_23_00 -> 2023_05_24_00
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `speed_run` = 1.14286 WHERE `entry` = 4480;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2023_05_24_00 -> 2023_05_24_01
|
||||||
|
--
|
||||||
|
DELETE FROM `creature_template_spell` WHERE `CreatureID`=18847 AND `Index`=2 AND `Spell`=33096;
|
||||||
|
INSERT INTO `creature_template_spell` (`CreatureID`, `Index`, `Spell`, `VerifiedBuild`) VALUES (18847, 2, 33096, 0);
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
-- DB update 2023_05_24_01 -> 2023_05_24_02
|
||||||
|
--
|
||||||
|
-- Blackrock Summoner
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 9818);
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(9818, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 11, 12380, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - On Reset - Cast \'Shadow Channeling\' (Phase 1) (Normal Dungeon)'),
|
||||||
|
(9818, 0, 1, 0, 4, 0, 100, 2, 0, 0, 0, 0, 0, 39, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - On Aggro - Call For Help (Normal Dungeon)'),
|
||||||
|
(9818, 0, 2, 0, 4, 0, 100, 3, 0, 0, 0, 0, 0, 87, 981800, 981801, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - On Aggro - Summon Random Enemy (No Repeat) (Normal Dungeon)'),
|
||||||
|
(9818, 0, 3, 0, 0, 0, 100, 2, 50, 100, 3600, 6300, 0, 11, 12466, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - In Combat - Cast \'Fireball\' (Normal Dungeon)'),
|
||||||
|
(9818, 0, 4, 0, 0, 0, 100, 2, 11400, 11400, 12700, 16700, 0, 11, 15532, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - In Combat - Cast \'Frost Nova\' (Normal Dungeon)'),
|
||||||
|
(9818, 0, 5, 0, 2, 0, 100, 3, 0, 15, 0, 0, 0, 25, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - Between 0-15% Health - Flee For Assist (No Repeat) (Normal Dungeon)'),
|
||||||
|
(9818, 0, 6, 0, 1, 0, 100, 2, 0, 8000, 12000, 14000, 0, 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - Out of Combat - Play Emote 1 (No Repeat) (Normal Dungeon)');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 9 AND `entryorguid` IN (981800, 981801));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(981800, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 15792, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - ActionList - Cast \'Summon Blackhand Veteran\' (No Repeat) (Normal Dungeon)'),
|
||||||
|
(981800, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - ActionList - Say Line 0 (No Repeat) (Normal Dungeon)'),
|
||||||
|
(981801, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 11, 15794, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - ActionList - Cast \'Summon Blackhand Dreadweaver\' (No Repeat) (Normal Dungeon)'),
|
||||||
|
(981801, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Blackhand Summoner - ActionList - Say Line 1 (No Repeat) (Normal Dungeon)');
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
-- DB update 2023_05_24_02 -> 2023_05_24_03
|
||||||
|
--
|
||||||
|
UPDATE `creature_loot_template` SET `GroupId` = 1 WHERE (`Entry` = 17370) AND (`Item` IN (1, 2, 3, 4, 5, 6));
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 5 WHERE (`Entry` = 17370) AND (`Item` IN (1, 2));
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 1 WHERE (`Entry` = 17370) AND (`Item` IN (3, 4, 5, 6));
|
||||||
|
|
||||||
|
UPDATE `creature_loot_template` SET `GroupId` = 1 WHERE (`Entry` = 18620) AND (`Item` IN (1, 2, 3, 4, 5, 6, 7));
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 5 WHERE (`Entry` = 18620) AND (`Item` IN (1, 2));
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 1 WHERE (`Entry` = 18620) AND (`Item` IN (3, 4, 5, 6, 7));
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
-- DB update 2023_05_24_03 -> 2023_05_28_00
|
||||||
|
--
|
||||||
|
UPDATE `smart_scripts` SET `event_param2`=2 WHERE `entryorguid`=-151131 AND `source_type`=0 AND `id`=1003 AND `link`=1004;
|
||||||
|
UPDATE `smart_scripts` SET `event_param2`=4 WHERE `entryorguid`=-151131 AND `source_type`=0 AND `id`=1005 AND `link`=1006;
|
||||||
|
UPDATE `smart_scripts` SET `event_param2`=6 WHERE `entryorguid`=-151131 AND `source_type`=0 AND `id`=1007 AND `link`=1008;
|
||||||
|
|
||||||
|
UPDATE `smart_scripts` SET `event_param2`=2 WHERE `entryorguid`=-151137 AND `source_type`=0 AND `id`=1003 AND `link`=1004;
|
||||||
|
UPDATE `smart_scripts` SET `event_param2`=4 WHERE `entryorguid`=-151137 AND `source_type`=0 AND `id`=1005 AND `link`=1006;
|
||||||
|
UPDATE `smart_scripts` SET `event_param2`=6 WHERE `entryorguid`=-151137 AND `source_type`=0 AND `id`=1007 AND `link`=1008;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_05_28_00 -> 2023_05_28_01
|
||||||
|
--
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 0.5 WHERE `Reference` = 24093;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-- DB update 2023_05_28_01 -> 2023_05_28_02
|
||||||
|
-- Change from old value to new value
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra`&~67108864|134217728 WHERE `entry` IN (16507,16523,16593,16594,16699,16700,16704,17420,17462,17464,17653,17694,17722,17800,17803,17993,17994,18155,18404,18405,18420,18421,18422,18620,18631,18632,18633,18634,18635,18639,18640,18641,18829,19166,19168,19505,19510,19735,19767,20059,20576,20577,20582,20586,20587,20589,20590,20591,20593,20594,20595,20621,20622,20625,20638,20640,20641,20642,20643,20647,20648,20649,20864,20865,20867,20868,20873,20875,20881,20883,20988,20990,21522,21523,21539,21540,21541,21542,21543,21544,21545,21548,21549,21570,21571,21574,21577,21578,21591,21593,21604,21605,21607,21608,21615,21619);
|
||||||
|
-- Add new flag
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|67108864 WHERE `entry` IN (17462, 20595, 14834);
|
||||||
|
|
||||||
|
-- Misc Fix for ShH
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 17462) AND (`source_type` = 0) AND (`id` IN (2));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(17462, 0, 2, 0, 40, 0, 100, 0, 4, 1746200, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Shattered Hand Zealot - On Waypoint Ended - Set In Combat With Zone');
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-- DB update 2023_05_28_02 -> 2023_05_28_03
|
||||||
|
--
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (-151090,-151091,-151092,-151093)) AND (`source_type` = 0) AND (`id` IN (0));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(-151090, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Flags Not Attackable'),
|
||||||
|
(-151091, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Flags Not Attackable'),
|
||||||
|
(-151092, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Flags Not Attackable'),
|
||||||
|
(-151093, 0, 1000, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 18, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Hack: Fel Orc Convert - On Respawn - Set Flags Not Attackable');
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|134217728 WHERE (`entry` IN (17083, 20567));
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
-- DB update 2023_05_28_03 -> 2023_05_28_04
|
||||||
|
UPDATE `creature_template` SET `ScriptName` = 'npc_shattered_hand_scout' WHERE `entry` = 17693;
|
||||||
|
|
||||||
|
SET @PATH := 17693 * 10;
|
||||||
|
DELETE FROM `waypoint_data` WHERE `id` = @PATH;
|
||||||
|
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
|
||||||
|
(@PATH,1,389.98074,315.4098,1.9338964,NULL,0,1,0,100,0),
|
||||||
|
(@PATH,2,419.4097,315.15308,1.940825,NULL,0,1,0,100,0),
|
||||||
|
(@PATH,3,460.31537,316.02213,1.9368871,NULL,0,1,0,100,0),
|
||||||
|
(@PATH,4,488.62424,315.73007,1.9498857,NULL,0,1,0,100,0);
|
||||||
|
|
||||||
|
DELETE FROM `spell_target_position` WHERE `ID` = 30976;
|
||||||
|
INSERT INTO `spell_target_position` (`ID`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `VerifiedBuild`) VALUES
|
||||||
|
(30976, 540, 520.062, 255.486, 2.0333333, 48999);
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 30952);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(13, 1, 30952, 0, 0, 31, 0, 3, 17687, 0, 0, 0, 0, '', 'Shoot Flame Arrow (30952) only hit Flame Arrow (17687)');
|
||||||
|
|
||||||
|
DELETE FROM `creature_formations` WHERE `memberGUID` IN (151094,151095,151096,151097);
|
||||||
|
INSERT INTO `creature_formations` (`memberGUID`, `leaderGUID`, `groupAI`) VALUES
|
||||||
|
(151095,151095,3),
|
||||||
|
(151096,151095,3),
|
||||||
|
(151097,151095,3);
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2023_05_28_04 -> 2023_05_29_00
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `mechanic_immune_mask` = `mechanic_immune_mask`|16|64|256|1024|2048|4096|65536|8388608|33554432 WHERE `entry` = 21102;
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_05_29_00 -> 2023_05_29_01
|
||||||
|
--
|
||||||
|
DELETE FROM `creature_template_resistance` WHERE `CreatureID` IN (17034, 17035, 17039, 17053);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2023_05_29_01 -> 2023_05_29_02
|
||||||
|
-- Hellfire Beacons
|
||||||
|
UPDATE `gameobject_template` SET `ScriptName` = 'go_beacon' WHERE `entry` IN (181579, 181580, 181581);
|
||||||
@@ -114,7 +114,7 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
|
|||||||
void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob)
|
void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob)
|
||||||
{
|
{
|
||||||
//calc random
|
//calc random
|
||||||
if (e.GetEventType() != SMART_EVENT_LINK && e.event.event_chance < 100 && e.event.event_chance)
|
if (e.event.event_chance < 100 && e.event.event_chance)
|
||||||
{
|
{
|
||||||
uint32 rnd = urand(1, 100);
|
uint32 rnd = urand(1, 100);
|
||||||
if (e.event.event_chance <= rnd)
|
if (e.event.event_chance <= rnd)
|
||||||
|
|||||||
@@ -2446,6 +2446,12 @@ bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /
|
|||||||
if (GetCharmerOrOwnerGUID())
|
if (GetCharmerOrOwnerGUID())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/// @todo: Implement aggro range, detection range and assistance range templates
|
||||||
|
if (m_creatureInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// only from same creature faction
|
// only from same creature faction
|
||||||
if (checkfaction)
|
if (checkfaction)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,15 +72,15 @@ enum CreatureFlagsExtra : uint32
|
|||||||
CREATURE_FLAG_EXTRA_NO_DODGE = 0x00800000, // xinef: target cannot dodge
|
CREATURE_FLAG_EXTRA_NO_DODGE = 0x00800000, // xinef: target cannot dodge
|
||||||
CREATURE_FLAG_EXTRA_MODULE = 0x01000000,
|
CREATURE_FLAG_EXTRA_MODULE = 0x01000000,
|
||||||
CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE = 0x02000000, // Prevent creatures from calling for assistance on initial aggro
|
CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE = 0x02000000, // Prevent creatures from calling for assistance on initial aggro
|
||||||
CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI = 0x04000000, // Load both ENTRY and GUID specific SAI
|
CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS = 0x04000000, // Prevents creature from responding to assistance calls
|
||||||
CREATURE_FLAG_EXTRA_UNUSED_28 = 0x08000000,
|
CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI = 0x08000000, // Load both ENTRY and GUID specific SAI
|
||||||
CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)
|
CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)
|
||||||
CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding
|
CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding
|
||||||
CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects
|
CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects
|
||||||
CREATURE_FLAG_EXTRA_HARD_RESET = 0x80000000,
|
CREATURE_FLAG_EXTRA_HARD_RESET = 0x80000000,
|
||||||
|
|
||||||
// Masks
|
// Masks
|
||||||
CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_12 | CREATURE_FLAG_EXTRA_UNUSED_28), // SKIP
|
CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_12), // SKIP
|
||||||
|
|
||||||
CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) // SKIP
|
CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) // SKIP
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ AC_API_EXPORT EnumText EnumUtils<CreatureFlagsExtra>::ToString(CreatureFlagsExtr
|
|||||||
case CREATURE_FLAG_EXTRA_NO_DODGE: return { "CREATURE_FLAG_EXTRA_NO_DODGE", "CREATURE_FLAG_EXTRA_NO_DODGE", "xinef: target cannot dodge" };
|
case CREATURE_FLAG_EXTRA_NO_DODGE: return { "CREATURE_FLAG_EXTRA_NO_DODGE", "CREATURE_FLAG_EXTRA_NO_DODGE", "xinef: target cannot dodge" };
|
||||||
case CREATURE_FLAG_EXTRA_MODULE: return { "CREATURE_FLAG_EXTRA_MODULE", "CREATURE_FLAG_EXTRA_MODULE", "Used by module creatures to avoid blizzlike checks." };
|
case CREATURE_FLAG_EXTRA_MODULE: return { "CREATURE_FLAG_EXTRA_MODULE", "CREATURE_FLAG_EXTRA_MODULE", "Used by module creatures to avoid blizzlike checks." };
|
||||||
case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return { "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "Creature does not call for assistance on initial aggro", "" };
|
case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return { "CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE", "Creature does not call for assistance on initial aggro", "" };
|
||||||
|
case CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS: return { "CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS", "Prevents creature from responding to assistance calls", "" };
|
||||||
case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return { "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "Creature entry SAI won't be overriden by GUID SAI", "" };
|
case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return { "CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI", "Creature entry SAI won't be overriden by GUID SAI", "" };
|
||||||
case CREATURE_FLAG_EXTRA_UNUSED_28: return { "CREATURE_FLAG_EXTRA_UNUSED_28", "CREATURE_FLAG_EXTRA_UNUSED_28", "" };
|
|
||||||
case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return { "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)" };
|
case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return { "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "CREATURE_FLAG_EXTRA_DUNGEON_BOSS", "creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB)" };
|
||||||
case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return { "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "creature ignore pathfinding" };
|
case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return { "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING", "creature ignore pathfinding" };
|
||||||
case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return { "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "creature is immune to knockback effects" };
|
case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return { "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK", "creature is immune to knockback effects" };
|
||||||
@@ -101,8 +101,8 @@ AC_API_EXPORT CreatureFlagsExtra EnumUtils<CreatureFlagsExtra>::FromIndex(size_t
|
|||||||
case 23: return CREATURE_FLAG_EXTRA_NO_DODGE;
|
case 23: return CREATURE_FLAG_EXTRA_NO_DODGE;
|
||||||
case 24: return CREATURE_FLAG_EXTRA_MODULE;
|
case 24: return CREATURE_FLAG_EXTRA_MODULE;
|
||||||
case 25: return CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE;
|
case 25: return CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE;
|
||||||
case 26: return CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI;
|
case 26: return CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS;
|
||||||
case 27: return CREATURE_FLAG_EXTRA_UNUSED_28;
|
case 27: return CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI;
|
||||||
case 28: return CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
|
case 28: return CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
|
||||||
case 29: return CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING;
|
case 29: return CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING;
|
||||||
case 30: return CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK;
|
case 30: return CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK;
|
||||||
@@ -142,8 +142,8 @@ AC_API_EXPORT size_t EnumUtils<CreatureFlagsExtra>::ToIndex(CreatureFlagsExtra v
|
|||||||
case CREATURE_FLAG_EXTRA_NO_DODGE: return 23;
|
case CREATURE_FLAG_EXTRA_NO_DODGE: return 23;
|
||||||
case CREATURE_FLAG_EXTRA_MODULE: return 24;
|
case CREATURE_FLAG_EXTRA_MODULE: return 24;
|
||||||
case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return 25;
|
case CREATURE_FLAG_EXTRA_DONT_CALL_ASSISTANCE: return 25;
|
||||||
case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return 26;
|
case CREATURE_FLAG_EXTRA_IGNORE_ALL_ASSISTANCE_CALLS: return 26;
|
||||||
case CREATURE_FLAG_EXTRA_UNUSED_28: return 27;
|
case CREATURE_FLAG_DONT_OVERRIDE_ENTRY_SAI: return 27;
|
||||||
case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return 28;
|
case CREATURE_FLAG_EXTRA_DUNGEON_BOSS: return 28;
|
||||||
case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return 29;
|
case CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING: return 29;
|
||||||
case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return 30;
|
case CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK: return 30;
|
||||||
|
|||||||
@@ -5284,7 +5284,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
|
|||||||
if (at)
|
if (at)
|
||||||
Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
|
Relocate(at->target_X, at->target_Y, at->target_Z, at->target_Orientation);
|
||||||
else
|
else
|
||||||
RelocateToHomebind();
|
RelocateToHomebind();
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOW player must have valid map
|
// NOW player must have valid map
|
||||||
|
|||||||
@@ -70,14 +70,21 @@ public:
|
|||||||
{
|
{
|
||||||
auto itemTokens = Acore::Tokenize(itemString, ':', false);
|
auto itemTokens = Acore::Tokenize(itemString, ':', false);
|
||||||
|
|
||||||
if (itemTokens.size() != 2)
|
uint32 itemCount;
|
||||||
|
switch (itemTokens.size())
|
||||||
{
|
{
|
||||||
handler->SendSysMessage(Acore::StringFormatFmt("> Incorrect item list format for '{}'", itemString));
|
case 1:
|
||||||
continue;
|
itemCount = 1; // Default to sending 1 item
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
itemCount = *Acore::StringTo<uint32>(itemTokens.at(1));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
handler->SendSysMessage(Acore::StringFormatFmt("> Incorrect item list format for '{}'", itemString));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 itemID = *Acore::StringTo<uint32>(itemTokens.at(0));
|
uint32 itemID = *Acore::StringTo<uint32>(itemTokens.at(0));
|
||||||
uint32 itemCount = *Acore::StringTo<uint32>(itemTokens.at(1));
|
|
||||||
|
|
||||||
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemID);
|
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemID);
|
||||||
if (!itemTemplate)
|
if (!itemTemplate)
|
||||||
|
|||||||
+149
-149
@@ -19,29 +19,27 @@
|
|||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "old_hillsbrad.h"
|
#include "old_hillsbrad.h"
|
||||||
|
|
||||||
enum CaptainSkarloc
|
enum Text
|
||||||
{
|
{
|
||||||
SAY_ENTER = 0,
|
SAY_ENTER = 0,
|
||||||
SAY_TAUNT = 1,
|
SAY_TAUNT = 1,
|
||||||
SAY_SLAY = 2,
|
SAY_SLAY = 2,
|
||||||
SAY_DEATH = 3,
|
SAY_DEATH = 3
|
||||||
|
};
|
||||||
|
|
||||||
SPELL_HOLY_LIGHT = 29427,
|
enum Spells
|
||||||
SPELL_CLEANSE = 29380,
|
{
|
||||||
SPELL_HAMMER_OF_JUSTICE = 13005,
|
SPELL_HOLY_LIGHT = 29427,
|
||||||
SPELL_HOLY_SHIELD = 31904,
|
SPELL_CLEANSE = 29380,
|
||||||
SPELL_DEVOTION_AURA = 8258,
|
SPELL_HAMMER_OF_JUSTICE = 13005,
|
||||||
SPELL_CONSECRATION = 38385,
|
SPELL_HOLY_SHIELD = 31904,
|
||||||
|
SPELL_DEVOTION_AURA = 8258,
|
||||||
|
SPELL_CONSECRATION = 38385
|
||||||
|
};
|
||||||
|
|
||||||
WAYPOINTS_COUNT = 4,
|
enum Misc
|
||||||
|
{
|
||||||
EVENT_INITIAL_TALK = 1,
|
WAYPOINTS_COUNT = 4
|
||||||
EVENT_START_FIGHT = 2,
|
|
||||||
EVENT_SPELL_CLEANSE = 10,
|
|
||||||
EVENT_SPELL_HAMMER = 11,
|
|
||||||
EVENT_SPELL_HOLY_LIGHT = 12,
|
|
||||||
EVENT_SPELL_HOLY_SHIELD = 13,
|
|
||||||
EVENT_SPELL_CONSECRATION = 14
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Position startPath[WAYPOINTS_COUNT] =
|
const Position startPath[WAYPOINTS_COUNT] =
|
||||||
@@ -52,172 +50,174 @@ const Position startPath[WAYPOINTS_COUNT] =
|
|||||||
{2058.77f, 236.04f, 63.92f, 0.0f}
|
{2058.77f, 236.04f, 63.92f, 0.0f}
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_captain_skarloc : public CreatureScript
|
struct boss_captain_skarloc : public BossAI
|
||||||
{
|
{
|
||||||
public:
|
boss_captain_skarloc(Creature* creature) : BossAI(creature, DATA_CAPTAIN_SKARLOC), summons(me)
|
||||||
boss_captain_skarloc() : CreatureScript("boss_captain_skarloc") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
return GetOldHillsbradAI<boss_captain_skarlocAI>(creature);
|
scheduler.SetValidator([this]
|
||||||
|
{
|
||||||
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_captain_skarlocAI : public ScriptedAI
|
SummonList summons;
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
{
|
{
|
||||||
boss_captain_skarlocAI(Creature* creature) : ScriptedAI(creature), summons(me) { }
|
_Reset();
|
||||||
|
summons.DespawnAll();
|
||||||
|
}
|
||||||
|
|
||||||
EventMap events;
|
void JustSummoned(Creature* summon) override
|
||||||
SummonList summons;
|
{
|
||||||
|
summons.Summon(summon);
|
||||||
void Reset() override
|
if (Creature* thrall = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_THRALL_GUID)))
|
||||||
{
|
{
|
||||||
events.Reset();
|
thrall->AI()->JustSummoned(summon);
|
||||||
summons.DespawnAll();
|
|
||||||
}
|
}
|
||||||
|
summon->SetImmuneToAll(true);
|
||||||
|
if (summon->GetEntry() == NPC_SKARLOC_MOUNT)
|
||||||
|
return;
|
||||||
|
|
||||||
void JustSummoned(Creature* summon) override
|
if (summons.size() == 1)
|
||||||
{
|
{
|
||||||
summons.Summon(summon);
|
summon->GetMotionMaster()->MovePoint(0, 2060.788f, 237.301f, 63.999f);
|
||||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_THRALL_GUID)))
|
|
||||||
thrall->AI()->JustSummoned(summon);
|
|
||||||
summon->SetImmuneToAll(true);
|
|
||||||
|
|
||||||
if (summon->GetEntry() == NPC_SKARLOC_MOUNT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (summons.size() == 1)
|
|
||||||
summon->GetMotionMaster()->MovePoint(0, 2060.788f, 237.301f, 63.999f);
|
|
||||||
else
|
|
||||||
summon->GetMotionMaster()->MovePoint(0, 2056.870f, 234.853f, 63.839f);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
void InitializeAI() override
|
|
||||||
{
|
{
|
||||||
ScriptedAI::InitializeAI();
|
summon->GetMotionMaster()->MovePoint(0, 2056.870f, 234.853f, 63.839f);
|
||||||
|
|
||||||
Movement::PointsArray path;
|
|
||||||
path.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
|
||||||
for (uint8 i = 0; i < WAYPOINTS_COUNT; ++i)
|
|
||||||
path.push_back(G3D::Vector3(startPath[i].GetPositionX(), startPath[i].GetPositionY(), startPath[i].GetPositionZ()));
|
|
||||||
|
|
||||||
me->GetMotionMaster()->MoveSplinePath(&path);
|
|
||||||
me->SetImmuneToAll(true);
|
|
||||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MovementInform(uint32 type, uint32 id) override
|
void InitializeAI() override
|
||||||
|
{
|
||||||
|
ScriptedAI::InitializeAI();
|
||||||
|
Movement::PointsArray path;
|
||||||
|
path.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||||
|
for (uint8 i = 0; i < WAYPOINTS_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (type != ESCORT_MOTION_TYPE)
|
path.push_back(G3D::Vector3(startPath[i].GetPositionX(), startPath[i].GetPositionY(), startPath[i].GetPositionZ()));
|
||||||
return;
|
}
|
||||||
|
me->GetMotionMaster()->MoveSplinePath(&path);
|
||||||
|
me->SetImmuneToAll(true);
|
||||||
|
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||||
|
}
|
||||||
|
|
||||||
// Xinef: we can rely here on internal counting
|
void MovementInform(uint32 type, uint32 id) override
|
||||||
if (id == 1)
|
{
|
||||||
|
if (type != ESCORT_MOTION_TYPE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Xinef: we can rely here on internal counting
|
||||||
|
if (id == 1)
|
||||||
|
{
|
||||||
|
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2038.549f, 273.303f, 63.420f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||||
|
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2032.810f, 269.416f, 63.561f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||||
|
}
|
||||||
|
else if (id == 2)
|
||||||
|
{
|
||||||
|
me->Dismount();
|
||||||
|
me->SetWalk(true);
|
||||||
|
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||||
{
|
{
|
||||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2038.549f, 273.303f, 63.420f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2032.810f, 269.416f, 63.561f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
|
||||||
}
|
|
||||||
else if (id == 2)
|
|
||||||
{
|
|
||||||
me->Dismount();
|
|
||||||
me->SetWalk(true);
|
|
||||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
|
||||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
|
||||||
summon->SetWalk(true);
|
|
||||||
if (Creature* mount = me->SummonCreature(NPC_SKARLOC_MOUNT, 2049.12f, 252.31f, 62.855f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN))
|
|
||||||
{
|
{
|
||||||
mount->SetImmuneToNPC(true);
|
summon->SetWalk(true);
|
||||||
mount->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (Creature* mount = me->SummonCreature(NPC_SKARLOC_MOUNT, 2049.12f, 252.31f, 62.855f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN))
|
||||||
if (me->movespline->Finalized())
|
|
||||||
{
|
{
|
||||||
Talk(SAY_ENTER, 500ms);
|
mount->SetImmuneToNPC(true);
|
||||||
|
mount->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
me->m_Events.AddEventAtOffset([this]()
|
if (me->movespline->Finalized())
|
||||||
|
{
|
||||||
|
Talk(SAY_ENTER, 500ms);
|
||||||
|
|
||||||
|
me->m_Events.AddEventAtOffset([this]()
|
||||||
|
{
|
||||||
|
me->SetImmuneToAll(false);
|
||||||
|
me->SetInCombatWithZone();
|
||||||
|
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||||
{
|
{
|
||||||
me->SetImmuneToAll(false);
|
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||||
me->SetInCombatWithZone();
|
|
||||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
|
||||||
{
|
{
|
||||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
if (summon->GetEntry() != NPC_SKARLOC_MOUNT)
|
||||||
{
|
{
|
||||||
if (summon->GetEntry() != NPC_SKARLOC_MOUNT)
|
summon->SetImmuneToAll(false);
|
||||||
{
|
summon->SetInCombatWithZone();
|
||||||
summon->SetImmuneToAll(false);
|
|
||||||
summon->SetInCombatWithZone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 8s);
|
}
|
||||||
}
|
}, 8s);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
_JustEngagedWith();
|
||||||
|
DoCastSelf(SPELL_DEVOTION_AURA);
|
||||||
|
scheduler.Schedule(15s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
me->CastSpell(me, SPELL_DEVOTION_AURA, true);
|
DoCastSelf(SPELL_HOLY_LIGHT);
|
||||||
|
context.Repeat(20s);
|
||||||
events.ScheduleEvent(EVENT_SPELL_HOLY_LIGHT, 15000);
|
}).Schedule(6s, [this](TaskContext context)
|
||||||
events.ScheduleEvent(EVENT_SPELL_CLEANSE, 6000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_HAMMER, 20000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_HOLY_SHIELD, 10000);
|
|
||||||
if (IsHeroic())
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KilledUnit(Unit* /*victim*/) override
|
|
||||||
{
|
{
|
||||||
Talk(SAY_SLAY);
|
if (roll_chance_i(33))
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
Talk(SAY_DEATH);
|
|
||||||
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_SKARLOC_KILLED);
|
|
||||||
me->GetInstanceScript()->SetData(DATA_THRALL_ADD_FLAG, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
events.Update(diff);
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (events.ExecuteEvent())
|
|
||||||
{
|
{
|
||||||
case EVENT_SPELL_HOLY_LIGHT:
|
Talk(SAY_TAUNT);
|
||||||
me->CastSpell(me, SPELL_HOLY_LIGHT, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_HOLY_LIGHT, 20000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_CLEANSE:
|
|
||||||
if (roll_chance_i(33))
|
|
||||||
Talk(SAY_TAUNT);
|
|
||||||
me->CastSpell(me, SPELL_CLEANSE, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_CLEANSE, 10000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_HAMMER:
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_HAMMER, 30000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_HOLY_SHIELD:
|
|
||||||
me->CastSpell(me, SPELL_HOLY_SHIELD, false);
|
|
||||||
events.ScheduleEvent(SPELL_HOLY_SHIELD, 30000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_CONSECRATION:
|
|
||||||
me->CastSpell(me, SPELL_CONSECRATION, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 20000);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
DoCastSelf(SPELL_CLEANSE);
|
||||||
|
context.Repeat(10s);
|
||||||
|
}).Schedule(20s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_HAMMER_OF_JUSTICE);
|
||||||
|
context.Repeat(30s);
|
||||||
|
}).Schedule(10s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_HOLY_SHIELD);
|
||||||
|
context.Repeat(30s);
|
||||||
|
});
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
if (IsHeroic())
|
||||||
|
{
|
||||||
|
scheduler.Schedule(1s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_CONSECRATION);
|
||||||
|
context.Repeat(20s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
void KilledUnit(Unit* /*victim*/) override
|
||||||
|
{
|
||||||
|
Talk(SAY_SLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* /*killer*/) override
|
||||||
|
{
|
||||||
|
_JustDied();
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_SKARLOC_KILLED);
|
||||||
|
me->GetInstanceScript()->SetData(DATA_THRALL_ADD_FLAG, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
scheduler.Update(diff);
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_captain_skarloc()
|
void AddSC_boss_captain_skarloc()
|
||||||
{
|
{
|
||||||
new boss_captain_skarloc();
|
RegisterOldHillsbradCreatureAI(boss_captain_skarloc);
|
||||||
}
|
}
|
||||||
|
|||||||
+75
-84
@@ -19,107 +19,98 @@
|
|||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "old_hillsbrad.h"
|
#include "old_hillsbrad.h"
|
||||||
|
|
||||||
enum EpochHunter
|
enum Text
|
||||||
{
|
{
|
||||||
SAY_AGGRO = 5,
|
SAY_AGGRO = 5,
|
||||||
SAY_SLAY = 6,
|
SAY_SLAY = 6,
|
||||||
SAY_BREATH = 7,
|
SAY_BREATH = 7,
|
||||||
SAY_DEATH = 8,
|
SAY_DEATH = 8
|
||||||
|
|
||||||
SPELL_SAND_BREATH = 31914,
|
|
||||||
SPELL_IMPENDING_DEATH = 31916,
|
|
||||||
SPELL_MAGIC_DISRUPTION_AURA = 33834,
|
|
||||||
SPELL_WING_BUFFET = 31475,
|
|
||||||
|
|
||||||
EVENT_SPELL_SAND_BREATH = 1,
|
|
||||||
EVENT_SPELL_IMPENDING_DEATH = 2,
|
|
||||||
EVENT_SPELL_DISRUPTION = 3,
|
|
||||||
EVENT_SPELL_WING_BUFFET = 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_epoch_hunter : public CreatureScript
|
enum Spells
|
||||||
{
|
{
|
||||||
public:
|
SPELL_SAND_BREATH = 31914,
|
||||||
boss_epoch_hunter() : CreatureScript("boss_epoch_hunter") { }
|
SPELL_IMPENDING_DEATH = 31916,
|
||||||
|
SPELL_MAGIC_DISRUPTION_AURA = 33834,
|
||||||
|
SPELL_WING_BUFFET = 31475
|
||||||
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
struct boss_epoch_hunter : public BossAI
|
||||||
|
{
|
||||||
|
boss_epoch_hunter(Creature* creature) : BossAI(creature, DATA_EPOCH_HUNTER)
|
||||||
{
|
{
|
||||||
return GetOldHillsbradAI<boss_epoch_hunterAI>(creature);
|
scheduler.SetValidator([this]
|
||||||
|
{
|
||||||
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_epoch_hunterAI : public ScriptedAI
|
void Reset() override
|
||||||
{
|
{
|
||||||
boss_epoch_hunterAI(Creature* creature) : ScriptedAI(creature) { }
|
_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
EventMap events;
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
|
{
|
||||||
void Reset() override
|
_JustEngagedWith();
|
||||||
|
Talk(SAY_AGGRO);
|
||||||
|
scheduler.Schedule(8s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
}
|
if (roll_chance_i(50))
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
|
||||||
{
|
|
||||||
Talk(SAY_AGGRO);
|
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_SAND_BREATH, 8000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_IMPENDING_DEATH, 2000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTION, 20000);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 14000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
|
||||||
{
|
|
||||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
Talk(SAY_SLAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* killer) override
|
|
||||||
{
|
|
||||||
if (killer && killer == me)
|
|
||||||
return;
|
|
||||||
Talk(SAY_DEATH);
|
|
||||||
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_EPOCH_KILLED);
|
|
||||||
if (Creature* taretha = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_TARETHA_GUID)))
|
|
||||||
taretha->AI()->DoAction(me->GetEntry());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
events.Update(diff);
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (events.ExecuteEvent())
|
|
||||||
{
|
{
|
||||||
case EVENT_SPELL_SAND_BREATH:
|
Talk(SAY_BREATH);
|
||||||
if (roll_chance_i(50))
|
|
||||||
Talk(SAY_BREATH);
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_SAND_BREATH, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_SAND_BREATH, 20000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_IMPENDING_DEATH:
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_IMPENDING_DEATH, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_IMPENDING_DEATH, 30000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_WING_BUFFET:
|
|
||||||
me->CastSpell(me, SPELL_WING_BUFFET, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 30000);
|
|
||||||
break;
|
|
||||||
case EVENT_SPELL_DISRUPTION:
|
|
||||||
me->CastSpell(me, SPELL_MAGIC_DISRUPTION_AURA, false);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTION, 30000);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
DoCastVictim(SPELL_SAND_BREATH);
|
||||||
|
context.Repeat(20s);
|
||||||
|
}).Schedule(2s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_IMPENDING_DEATH);
|
||||||
|
context.Repeat(30s);
|
||||||
|
}).Schedule(20s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_MAGIC_DISRUPTION_AURA);
|
||||||
|
context.Repeat(30s);
|
||||||
|
}).Schedule(14s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_WING_BUFFET);
|
||||||
|
context.Repeat(30s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
void KilledUnit(Unit* victim) override
|
||||||
|
{
|
||||||
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
Talk(SAY_SLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* killer) override
|
||||||
|
{
|
||||||
|
if (killer && killer == me)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_JustDied();
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_EPOCH_KILLED);
|
||||||
|
if (Creature* taretha = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_TARETHA_GUID)))
|
||||||
|
{
|
||||||
|
taretha->AI()->DoAction(me->GetEntry());
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
scheduler.Update(diff);
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_epoch_hunter()
|
void AddSC_boss_epoch_hunter()
|
||||||
{
|
{
|
||||||
new boss_epoch_hunter();
|
RegisterOldHillsbradCreatureAI(boss_epoch_hunter);
|
||||||
}
|
}
|
||||||
|
|||||||
+124
-132
@@ -21,159 +21,151 @@
|
|||||||
#include "SmartScriptMgr.h"
|
#include "SmartScriptMgr.h"
|
||||||
#include "old_hillsbrad.h"
|
#include "old_hillsbrad.h"
|
||||||
|
|
||||||
enum LieutenantDrake
|
enum Text
|
||||||
{
|
{
|
||||||
SAY_ENTER = 0,
|
SAY_ENTER = 0,
|
||||||
SAY_AGGRO = 1,
|
SAY_AGGRO = 1,
|
||||||
SAY_SLAY = 2,
|
SAY_SLAY = 2,
|
||||||
SAY_MORTAL = 3,
|
SAY_MORTAL = 3,
|
||||||
SAY_SHOUT = 4,
|
SAY_SHOUT = 4,
|
||||||
SAY_DEATH = 5,
|
SAY_DEATH = 5
|
||||||
|
|
||||||
SPELL_WHIRLWIND = 31909,
|
|
||||||
SPELL_EXPLODING_SHOT = 33792,
|
|
||||||
SPELL_HAMSTRING = 9080,
|
|
||||||
SPELL_MORTAL_STRIKE = 31911,
|
|
||||||
SPELL_FRIGHTENING_SHOUT = 33789,
|
|
||||||
|
|
||||||
EVENT_WHIRLWIND = 1,
|
|
||||||
EVENT_FRIGHTENING_SHOUT = 2,
|
|
||||||
EVENT_MORTAL_STRIKE = 3,
|
|
||||||
EVENT_HAMSTRING = 4,
|
|
||||||
EVENT_EXPLODING_SHOT = 5
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_lieutenant_drake : public CreatureScript
|
enum Spells
|
||||||
{
|
{
|
||||||
public:
|
SPELL_WHIRLWIND = 31909,
|
||||||
boss_lieutenant_drake() : CreatureScript("boss_lieutenant_drake") { }
|
SPELL_EXPLODING_SHOT = 33792,
|
||||||
|
SPELL_HAMSTRING = 9080,
|
||||||
|
SPELL_MORTAL_STRIKE = 31911,
|
||||||
|
SPELL_FRIGHTENING_SHOUT = 33789
|
||||||
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
struct boss_lieutenant_drake : public BossAI
|
||||||
|
{
|
||||||
|
boss_lieutenant_drake(Creature* creature) : BossAI(creature, DATA_LIEUTENANT_DRAKE)
|
||||||
{
|
{
|
||||||
return GetOldHillsbradAI<boss_lieutenant_drakeAI>(creature);
|
scheduler.SetValidator([this]
|
||||||
|
{
|
||||||
|
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_lieutenant_drakeAI : public ScriptedAI
|
void InitializeAI() override
|
||||||
{
|
{
|
||||||
boss_lieutenant_drakeAI(Creature* creature) : ScriptedAI(creature)
|
runSecondPath = false;
|
||||||
|
pathId = me->GetEntry() * 10;
|
||||||
|
me->GetMotionMaster()->MovePath(pathId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
_JustEngagedWith();
|
||||||
|
Talk(SAY_AGGRO);
|
||||||
|
scheduler.Schedule(4s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
|
DoCastSelf(SPELL_WHIRLWIND);
|
||||||
|
context.Repeat(25s);
|
||||||
|
}).Schedule(14s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (roll_chance_i(40))
|
||||||
|
{
|
||||||
|
Talk(SAY_SHOUT);
|
||||||
|
}
|
||||||
|
DoCastSelf(SPELL_FRIGHTENING_SHOUT);
|
||||||
|
context.Repeat(25s);
|
||||||
|
}).Schedule(9s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (roll_chance_i(40))
|
||||||
|
{
|
||||||
|
Talk(SAY_MORTAL);
|
||||||
|
}
|
||||||
|
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||||
|
context.Repeat(10s);
|
||||||
|
}).Schedule(18s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_HAMSTRING);
|
||||||
|
context.Repeat(25s);
|
||||||
|
}).Schedule(1s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 40.0f))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_EXPLODING_SHOT);
|
||||||
|
}
|
||||||
|
context.Repeat(25s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void KilledUnit(Unit* victim) override
|
||||||
|
{
|
||||||
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
Talk(SAY_SLAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* /*killer*/) override
|
||||||
|
{
|
||||||
|
_JustDied();
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
if (InstanceScript* instance = me->GetInstanceScript())
|
||||||
|
{
|
||||||
|
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_DRAKE_KILLED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementInform(uint32 type, uint32 point) override
|
||||||
|
{
|
||||||
|
if (type != WAYPOINT_MOTION_TYPE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeAI() override
|
if (pathId == me->GetEntry() * 10)
|
||||||
|
{
|
||||||
|
switch (point)
|
||||||
|
{
|
||||||
|
case 7:
|
||||||
|
Talk(SAY_ENTER);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
pathId = (me->GetEntry() * 10) + 1;
|
||||||
|
runSecondPath = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (runSecondPath)
|
||||||
{
|
{
|
||||||
runSecondPath = false;
|
runSecondPath = false;
|
||||||
pathId = me->GetEntry() * 10;
|
me->GetMotionMaster()->MovePath(pathId, true);
|
||||||
me->GetMotionMaster()->MovePath(pathId, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
if (!UpdateVictim())
|
||||||
{
|
return;
|
||||||
events.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
scheduler.Update(diff);
|
||||||
{
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
Talk(SAY_AGGRO);
|
return;
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_WHIRLWIND, 4000);
|
DoMeleeAttackIfReady();
|
||||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 14000);
|
}
|
||||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 9000);
|
|
||||||
events.ScheduleEvent(EVENT_HAMSTRING, 18000);
|
|
||||||
events.ScheduleEvent(EVENT_EXPLODING_SHOT, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
private:
|
||||||
{
|
uint32 pathId;
|
||||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
bool runSecondPath;
|
||||||
Talk(SAY_SLAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
Talk(SAY_DEATH);
|
|
||||||
if (InstanceScript* instance = me->GetInstanceScript())
|
|
||||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_DRAKE_KILLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MovementInform(uint32 type, uint32 point) override
|
|
||||||
{
|
|
||||||
if (type != WAYPOINT_MOTION_TYPE)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pathId == me->GetEntry() * 10)
|
|
||||||
{
|
|
||||||
switch (point)
|
|
||||||
{
|
|
||||||
case 7:
|
|
||||||
Talk(SAY_ENTER);
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
pathId = (me->GetEntry() * 10) + 1;
|
|
||||||
runSecondPath = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
if (runSecondPath)
|
|
||||||
{
|
|
||||||
runSecondPath = false;
|
|
||||||
me->GetMotionMaster()->MovePath(pathId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
events.Update(diff);
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (events.ExecuteEvent())
|
|
||||||
{
|
|
||||||
case EVENT_WHIRLWIND:
|
|
||||||
me->CastSpell(me, SPELL_WHIRLWIND, false);
|
|
||||||
events.ScheduleEvent(EVENT_WHIRLWIND, 25000);
|
|
||||||
break;
|
|
||||||
case EVENT_EXPLODING_SHOT:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 40.0f))
|
|
||||||
me->CastSpell(target, SPELL_EXPLODING_SHOT, false);
|
|
||||||
events.ScheduleEvent(EVENT_EXPLODING_SHOT, 25000);
|
|
||||||
break;
|
|
||||||
case EVENT_MORTAL_STRIKE:
|
|
||||||
if (roll_chance_i(40))
|
|
||||||
Talk(SAY_MORTAL);
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
|
|
||||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 10000);
|
|
||||||
break;
|
|
||||||
case EVENT_FRIGHTENING_SHOUT:
|
|
||||||
if (roll_chance_i(40))
|
|
||||||
Talk(SAY_SHOUT);
|
|
||||||
me->CastSpell(me, SPELL_FRIGHTENING_SHOUT, false);
|
|
||||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 25000);
|
|
||||||
break;
|
|
||||||
case EVENT_HAMSTRING:
|
|
||||||
me->CastSpell(me->GetVictim(), SPELL_HAMSTRING, false);
|
|
||||||
events.ScheduleEvent(EVENT_HAMSTRING, 25000);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
EventMap events;
|
|
||||||
uint32 pathId;
|
|
||||||
bool runSecondPath;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_lieutenant_drake()
|
void AddSC_boss_lieutenant_drake()
|
||||||
{
|
{
|
||||||
new boss_lieutenant_drake();
|
RegisterOldHillsbradCreatureAI(boss_lieutenant_drake);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,9 @@
|
|||||||
enum DataIds
|
enum DataIds
|
||||||
{
|
{
|
||||||
DATA_ESCORT_PROGRESS = 0,
|
DATA_ESCORT_PROGRESS = 0,
|
||||||
|
DATA_LIEUTENANT_DRAKE = 1,
|
||||||
|
DATA_CAPTAIN_SKARLOC = 2,
|
||||||
|
DATA_EPOCH_HUNTER = 3,
|
||||||
|
|
||||||
DATA_BOMBS_PLACED = 10,
|
DATA_BOMBS_PLACED = 10,
|
||||||
DATA_THRALL_REPOSITION = 11,
|
DATA_THRALL_REPOSITION = 11,
|
||||||
@@ -95,4 +98,6 @@ inline AI* GetOldHillsbradAI(T* obj)
|
|||||||
return GetInstanceAI<AI>(obj, OldHillsbradScriptName);
|
return GetInstanceAI<AI>(obj, OldHillsbradScriptName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RegisterOldHillsbradCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetOldHillsbradAI)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,14 +19,17 @@
|
|||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "the_black_morass.h"
|
#include "the_black_morass.h"
|
||||||
|
|
||||||
enum Enums
|
enum Text
|
||||||
{
|
{
|
||||||
SAY_AGGRO = 1,
|
SAY_AGGRO = 1,
|
||||||
SAY_BANISH = 2,
|
SAY_BANISH = 2,
|
||||||
SAY_SLAY = 3,
|
SAY_SLAY = 3,
|
||||||
SAY_DEATH = 4,
|
SAY_DEATH = 4,
|
||||||
EMOTE_FRENZY = 5,
|
EMOTE_FRENZY = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Spells
|
||||||
|
{
|
||||||
SPELL_CLEAVE = 40504,
|
SPELL_CLEAVE = 40504,
|
||||||
SPELL_TIME_STOP = 31422,
|
SPELL_TIME_STOP = 31422,
|
||||||
SPELL_ENRAGE = 37605,
|
SPELL_ENRAGE = 37605,
|
||||||
|
|||||||
@@ -19,19 +19,21 @@
|
|||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "the_black_morass.h"
|
#include "the_black_morass.h"
|
||||||
|
|
||||||
enum Enums
|
enum Text
|
||||||
{
|
{
|
||||||
SAY_AGGRO = 1,
|
SAY_AGGRO = 1,
|
||||||
SAY_BANISH = 2,
|
SAY_BANISH = 2,
|
||||||
SAY_SLAY = 3,
|
SAY_SLAY = 3,
|
||||||
SAY_DEATH = 4,
|
SAY_DEATH = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Spells
|
||||||
|
{
|
||||||
SPELL_ARCANE_BLAST = 31457,
|
SPELL_ARCANE_BLAST = 31457,
|
||||||
SPELL_ARCANE_DISCHARGE = 31472,
|
SPELL_ARCANE_DISCHARGE = 31472,
|
||||||
SPELL_TIME_LAPSE = 31467,
|
SPELL_TIME_LAPSE = 31467,
|
||||||
SPELL_ATTRACTION = 38540,
|
SPELL_ATTRACTION = 38540,
|
||||||
|
SPELL_BANISH_DRAGON_HELPER = 31550
|
||||||
SPELL_BANISH_DRAGON_HELPER = 31550,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct boss_chrono_lord_deja : public BossAI
|
struct boss_chrono_lord_deja : public BossAI
|
||||||
|
|||||||
@@ -19,13 +19,16 @@
|
|||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
#include "the_black_morass.h"
|
#include "the_black_morass.h"
|
||||||
|
|
||||||
enum Enums
|
enum Text
|
||||||
{
|
{
|
||||||
SAY_AGGRO = 1,
|
SAY_AGGRO = 1,
|
||||||
SAY_BANISH = 2,
|
SAY_BANISH = 2,
|
||||||
SAY_SLAY = 3,
|
SAY_SLAY = 3,
|
||||||
SAY_DEATH = 4,
|
SAY_DEATH = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Spells
|
||||||
|
{
|
||||||
SPELL_HASTEN = 31458,
|
SPELL_HASTEN = 31458,
|
||||||
SPELL_MORTAL_WOUND = 31464,
|
SPELL_MORTAL_WOUND = 31464,
|
||||||
SPELL_WING_BUFFET = 31475,
|
SPELL_WING_BUFFET = 31475,
|
||||||
@@ -46,7 +49,6 @@ struct boss_temporus : public BossAI
|
|||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
_JustEngagedWith();
|
_JustEngagedWith();
|
||||||
|
|
||||||
scheduler.Schedule(12s, [this](TaskContext context)
|
scheduler.Schedule(12s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
DoCastSelf(SPELL_HASTEN);
|
DoCastSelf(SPELL_HASTEN);
|
||||||
@@ -69,7 +71,6 @@ struct boss_temporus : public BossAI
|
|||||||
context.Repeat(30s);
|
context.Repeat(30s);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnTalk(SAY_AGGRO);
|
OwnTalk(SAY_AGGRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,6 @@ struct boss_temporus : public BossAI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptedAI::MoveInLineOfSight(who);
|
ScriptedAI::MoveInLineOfSight(who);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,6 +111,16 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
});
|
});
|
||||||
|
|
||||||
instance->SetBossState(DATA_NETHEKURSE, NOT_STARTED);
|
instance->SetBossState(DATA_NETHEKURSE, NOT_STARTED);
|
||||||
|
|
||||||
|
if (!_canAggro)
|
||||||
|
{
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustReachedHome() override
|
||||||
|
{
|
||||||
|
me->GetMotionMaster()->Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
@@ -121,7 +131,7 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
|
|
||||||
void SetData(uint32 data, uint32 value) override
|
void SetData(uint32 data, uint32 value) override
|
||||||
{
|
{
|
||||||
if (data != SETDATA_DATA)
|
if (data != SETDATA_DATA || me->IsInCombat())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (value == SETDATA_PEON_AGGRO && PeonEngagedCount <= 4)
|
if (value == SETDATA_PEON_AGGRO && PeonEngagedCount <= 4)
|
||||||
@@ -137,9 +147,13 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
scheduler.Schedule(500ms, GROUP_RP, [this](TaskContext /*context*/)
|
scheduler.Schedule(500ms, GROUP_RP, [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
me->HandleEmoteCommand(EMOTE_ONESHOT_APPLAUD);
|
me->HandleEmoteCommand(EMOTE_ONESHOT_APPLAUD);
|
||||||
me->GetMotionMaster()->Initialize();
|
|
||||||
Talk(SAY_PEON_DIES);
|
Talk(SAY_PEON_DIES);
|
||||||
|
|
||||||
|
scheduler.Schedule(1s, GROUP_RP, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
me->GetMotionMaster()->Initialize();
|
||||||
|
});
|
||||||
|
|
||||||
if (++PeonKilledCount == 4)
|
if (++PeonKilledCount == 4)
|
||||||
{
|
{
|
||||||
Talk(SAY_INTRO_2);
|
Talk(SAY_INTRO_2);
|
||||||
@@ -161,16 +175,14 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
me->GetMotionMaster()->MoveIdle();
|
me->GetMotionMaster()->MoveIdle();
|
||||||
me->SetFacingTo(4.572762489318847656f);
|
me->SetFacingTo(4.572762489318847656f);
|
||||||
|
|
||||||
scheduler.Schedule(500ms, GROUP_RP, [this](TaskContext /*context*/)
|
scheduler.Schedule(2500ms, GROUP_RP, [this](TaskContext /*context*/)
|
||||||
{
|
{
|
||||||
scheduler.Schedule(2500ms, GROUP_RP, [this](TaskContext /*context*/)
|
PeonRoleplay roleplayData = Acore::Containers::SelectRandomContainerElement(PeonRoleplayData);
|
||||||
{
|
DoCast(me, roleplayData.spellId);
|
||||||
PeonRoleplay roleplayData = Acore::Containers::SelectRandomContainerElement(PeonRoleplayData);
|
Talk(roleplayData.textId);
|
||||||
DoCast(me, roleplayData.spellId);
|
me->GetMotionMaster()->Initialize();
|
||||||
Talk(roleplayData.textId);
|
|
||||||
me->GetMotionMaster()->Initialize();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
context.Repeat(16400ms, 28500ms);
|
context.Repeat(16400ms, 28500ms);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -225,6 +237,19 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
}
|
}
|
||||||
else if (action == ACTION_START_INTRO)
|
else if (action == ACTION_START_INTRO)
|
||||||
{
|
{
|
||||||
|
// Hack: Prevent from pulling from behind door
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
_canAggro = true;
|
||||||
|
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_PEON, 60.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
IntroRP();
|
IntroRP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,6 +271,7 @@ struct boss_grand_warlock_nethekurse : public BossAI
|
|||||||
private:
|
private:
|
||||||
uint8 PeonEngagedCount = 0;
|
uint8 PeonEngagedCount = 0;
|
||||||
uint8 PeonKilledCount = 0;
|
uint8 PeonKilledCount = 0;
|
||||||
|
bool _canAggro = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class spell_tsh_shadow_bolt : public SpellScript
|
class spell_tsh_shadow_bolt : public SpellScript
|
||||||
|
|||||||
+2
@@ -126,6 +126,8 @@ struct boss_warchief_kargath_bladefist : public BossAI
|
|||||||
{
|
{
|
||||||
Talk(SAY_DEATH);
|
Talk(SAY_DEATH);
|
||||||
BossAI::JustDied(killer);
|
BossAI::JustDied(killer);
|
||||||
|
if (Creature* warchiefPortal = instance->GetCreature(DATA_WARCHIEF_PORTAL))
|
||||||
|
warchiefPortal->AI()->SetData(DATA_RESET_FIGHT, 0);
|
||||||
if (instance)
|
if (instance)
|
||||||
{
|
{
|
||||||
if (Creature* executioner = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EXECUTIONER)))
|
if (Creature* executioner = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EXECUTIONER)))
|
||||||
|
|||||||
+232
-1
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "CreatureTextMgr.h"
|
#include "CreatureTextMgr.h"
|
||||||
#include "InstanceScript.h"
|
#include "InstanceScript.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "shattered_halls.h"
|
#include "shattered_halls.h"
|
||||||
|
|
||||||
@@ -181,6 +182,221 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ScoutMisc
|
||||||
|
{
|
||||||
|
SAY_INVADERS_BREACHED = 0,
|
||||||
|
|
||||||
|
SAY_PORUNG_ARCHERS = 0,
|
||||||
|
SAY_PORUNG_READY = 1,
|
||||||
|
SAY_PORUNG_AIM = 2,
|
||||||
|
SAY_PORUNG_FIRE = 3,
|
||||||
|
|
||||||
|
SPELL_CLEAR_ALL = 28471,
|
||||||
|
SPELL_SUMMON_ZEALOTS = 30976,
|
||||||
|
SPELL_SHOOT_FLAME_ARROW = 30952,
|
||||||
|
|
||||||
|
POINT_SCOUT_WP_END = 3,
|
||||||
|
|
||||||
|
SET_DATA_ARBITRARY_VALUE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct npc_shattered_hand_scout : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_shattered_hand_scout(Creature* creature) : ScriptedAI(creature) { }
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveInLineOfSight(Unit* who) override
|
||||||
|
{
|
||||||
|
if (!me->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE) && me->IsWithinDist2d(who, 50.0f) && who->GetPositionZ() > -3.0f
|
||||||
|
&& who->IsPlayer())
|
||||||
|
{
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
DoCastSelf(SPELL_CLEAR_ALL);
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||||
|
Talk(SAY_INVADERS_BREACHED);
|
||||||
|
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);
|
||||||
|
|
||||||
|
_firstZealots.clear();
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 15.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
_firstZealots.insert(creature->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*type*/, SpellSchoolMask /*school*/) override
|
||||||
|
{
|
||||||
|
if (damage >= me->GetHealth())
|
||||||
|
{
|
||||||
|
// Let creature fall to 1 HP but prevent it from dying.
|
||||||
|
damage = me->GetHealth() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementInform(uint32 type, uint32 point) override
|
||||||
|
{
|
||||||
|
if (type == WAYPOINT_MOTION_TYPE && point == POINT_SCOUT_WP_END)
|
||||||
|
{
|
||||||
|
me->SetVisible(false);
|
||||||
|
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->setActive(true);
|
||||||
|
porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_ARCHERS);
|
||||||
|
|
||||||
|
_scheduler.Schedule(45s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->AI()->DoCastAOE(SPELL_SUMMON_ZEALOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Repeat();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(1s, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
_zealotGUIDs.clear();
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ZEALOT, 100.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->AI()->SetData(SET_DATA_ARBITRARY_VALUE, SET_DATA_ARBITRARY_VALUE);
|
||||||
|
_zealotGUIDs.insert(creature->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& guid : _firstZealots)
|
||||||
|
{
|
||||||
|
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
{
|
||||||
|
zealot->SetInCombatWithZone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_READY, 3600ms);
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_AIM, 4800ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(5800ms, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Creature* porung = GetPorung())
|
||||||
|
{
|
||||||
|
porung->AI()->Talk(SAY_PORUNG_FIRE, 200ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.Schedule(2s, 9750ms, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (FireArrows())
|
||||||
|
{
|
||||||
|
context.Repeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!me->SelectNearestPlayer(250.0f))
|
||||||
|
{
|
||||||
|
me->SetVisible(true);
|
||||||
|
me->DespawnOrUnsummon(5s, 5s);
|
||||||
|
|
||||||
|
for (auto const& guid : _zealotGUIDs)
|
||||||
|
{
|
||||||
|
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
{
|
||||||
|
if (zealot->IsAlive())
|
||||||
|
{
|
||||||
|
zealot->DespawnOrUnsummon(5s, 5s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zealot->Respawn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& guid : _firstZealots)
|
||||||
|
{
|
||||||
|
if (Creature* zealot = ObjectAccessor::GetCreature(*me, guid))
|
||||||
|
{
|
||||||
|
if (zealot->IsAlive())
|
||||||
|
{
|
||||||
|
zealot->DespawnOrUnsummon(5s, 5s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zealot->Respawn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
_scheduler.Update(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FireArrows()
|
||||||
|
{
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SH_ARCHER, 100.0f);
|
||||||
|
|
||||||
|
if (creatureList.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Creature* creature : creatureList)
|
||||||
|
{
|
||||||
|
if (creature)
|
||||||
|
{
|
||||||
|
creature->AI()->DoCastAOE(SPELL_SHOOT_FLAME_ARROW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Creature* GetPorung()
|
||||||
|
{
|
||||||
|
return me->FindNearestCreature(IsHeroic() ? NPC_PORUNG : NPC_BLOOD_GUARD, 100.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
GuidSet _zealotGUIDs;
|
||||||
|
GuidSet _firstZealots;
|
||||||
|
};
|
||||||
|
|
||||||
class spell_tsh_shoot_flame_arrow : public SpellScriptLoader
|
class spell_tsh_shoot_flame_arrow : public SpellScriptLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -192,6 +408,15 @@ public:
|
|||||||
|
|
||||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||||
{
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
if (!caster)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unitList.remove_if([&](WorldObject* target) -> bool
|
||||||
|
{
|
||||||
|
return !target->SelectNearestPlayer(15.0f);
|
||||||
|
});
|
||||||
|
|
||||||
Acore::Containers::RandomResize(unitList, 1);
|
Acore::Containers::RandomResize(unitList, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +448,12 @@ public:
|
|||||||
bool OnTrigger(Player* player, AreaTrigger const* /*areaTrigger*/) override
|
bool OnTrigger(Player* player, AreaTrigger const* /*areaTrigger*/) override
|
||||||
{
|
{
|
||||||
if (InstanceScript* instanceScript = player->GetInstanceScript())
|
if (InstanceScript* instanceScript = player->GetInstanceScript())
|
||||||
instanceScript->SetData(DATA_ENTERED_ROOM, DATA_ENTERED_ROOM);
|
{
|
||||||
|
if (player->GetMap()->IsHeroic())
|
||||||
|
{
|
||||||
|
instanceScript->SetData(DATA_ENTERED_ROOM, DATA_ENTERED_ROOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -232,6 +462,7 @@ public:
|
|||||||
void AddSC_instance_shattered_halls()
|
void AddSC_instance_shattered_halls()
|
||||||
{
|
{
|
||||||
new instance_shattered_halls();
|
new instance_shattered_halls();
|
||||||
|
RegisterShatteredHallsCreatureAI(npc_shattered_hand_scout);
|
||||||
new spell_tsh_shoot_flame_arrow();
|
new spell_tsh_shoot_flame_arrow();
|
||||||
new at_shattered_halls_execution();
|
new at_shattered_halls_execution();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ enum CreatureIds
|
|||||||
{
|
{
|
||||||
NPC_GRAND_WARLOCK_NETHEKURSE = 16807,
|
NPC_GRAND_WARLOCK_NETHEKURSE = 16807,
|
||||||
NPC_FEL_ORC_CONVERT = 17083,
|
NPC_FEL_ORC_CONVERT = 17083,
|
||||||
|
NPC_PORUNG = 20923,
|
||||||
|
NPC_BLOOD_GUARD = 17461,
|
||||||
|
NPC_SH_ZEALOT = 17462,
|
||||||
|
NPC_SH_ARCHER = 17427,
|
||||||
|
|
||||||
// Warchief Kargath
|
// Warchief Kargath
|
||||||
NPC_WARCHIEF_KARGATH = 16808,
|
NPC_WARCHIEF_KARGATH = 16808,
|
||||||
NPC_WARCHIEF_PORTAL = 17611,
|
NPC_WARCHIEF_PORTAL = 17611,
|
||||||
|
|||||||
@@ -22,13 +22,13 @@
|
|||||||
|
|
||||||
enum Texts
|
enum Texts
|
||||||
{
|
{
|
||||||
SAY_INTRO = 0,
|
SAY_INTRO = 0,
|
||||||
SAY_AGGRO = 1,
|
SAY_AGGRO = 1,
|
||||||
SAY_SURPREME = 2,
|
SAY_SURPREME = 2,
|
||||||
SAY_KILL = 3,
|
SAY_KILL = 3,
|
||||||
SAY_DEATH = 4,
|
SAY_DEATH = 4,
|
||||||
EMOTE_FRENZY = 5,
|
EMOTE_FRENZY = 5,
|
||||||
SAY_RAND = 6
|
SAY_RAND = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
@@ -42,19 +42,7 @@ enum Spells
|
|||||||
SPELL_ENRAGE = 32964,
|
SPELL_ENRAGE = 32964,
|
||||||
SPELL_CAPTURE_SOUL = 32966,
|
SPELL_CAPTURE_SOUL = 32966,
|
||||||
SPELL_TWISTED_REFLECTION = 21063,
|
SPELL_TWISTED_REFLECTION = 21063,
|
||||||
SPELL_BERSERK = 32965,
|
SPELL_BERSERK = 32965
|
||||||
};
|
|
||||||
|
|
||||||
enum Events
|
|
||||||
{
|
|
||||||
EVENT_SHADOW_VOLLEY = 1,
|
|
||||||
EVENT_CLEAVE = 2,
|
|
||||||
EVENT_THUNDERCLAP = 3,
|
|
||||||
EVENT_VOID_BOLT = 4,
|
|
||||||
EVENT_MARK_OF_KAZZAK = 5,
|
|
||||||
EVENT_ENRAGE = 6,
|
|
||||||
EVENT_TWISTED_REFLECTION = 7,
|
|
||||||
EVENT_BERSERK = 8
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_doomlord_kazzak : public CreatureScript
|
class boss_doomlord_kazzak : public CreatureScript
|
||||||
@@ -64,21 +52,11 @@ public:
|
|||||||
|
|
||||||
struct boss_doomlordkazzakAI : public ScriptedAI
|
struct boss_doomlordkazzakAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
boss_doomlordkazzakAI(Creature* creature) : ScriptedAI(creature)
|
boss_doomlordkazzakAI(Creature* creature) : ScriptedAI(creature) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_events.Reset();
|
_inBerserk = false;
|
||||||
_events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(6000, 10000));
|
|
||||||
_events.ScheduleEvent(EVENT_CLEAVE, 7000);
|
|
||||||
_events.ScheduleEvent(EVENT_THUNDERCLAP, urand(14000, 18000));
|
|
||||||
_events.ScheduleEvent(EVENT_VOID_BOLT, 30000);
|
|
||||||
_events.ScheduleEvent(EVENT_MARK_OF_KAZZAK, 25000);
|
|
||||||
_events.ScheduleEvent(EVENT_ENRAGE, 60000);
|
|
||||||
_events.ScheduleEvent(EVENT_TWISTED_REFLECTION, 33000);
|
|
||||||
_events.ScheduleEvent(EVENT_BERSERK, 180000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustRespawned() override
|
void JustRespawned() override
|
||||||
@@ -89,17 +67,58 @@ public:
|
|||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
Talk(SAY_AGGRO);
|
Talk(SAY_AGGRO);
|
||||||
|
_scheduler.Schedule(6s, 10s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_SHADOW_VOLLEY);
|
||||||
|
context.Repeat(4s, 6s);
|
||||||
|
}).Schedule(7s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_CLEAVE);
|
||||||
|
context.Repeat(8s, 12s);
|
||||||
|
}).Schedule(14s, 18s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_THUNDERCLAP);
|
||||||
|
context.Repeat(10s, 14s);
|
||||||
|
}).Schedule(30s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_VOID_BOLT);
|
||||||
|
context.Repeat(15s, 18s);
|
||||||
|
}).Schedule(25s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 100.0f, true)))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_MARK_OF_KAZZAK);
|
||||||
|
}
|
||||||
|
context.Repeat(20s);
|
||||||
|
}).Schedule(1min, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
Talk(EMOTE_FRENZY);
|
||||||
|
DoCastSelf(SPELL_ENRAGE);
|
||||||
|
context.Repeat(30s);
|
||||||
|
}).Schedule(33s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_TWISTED_REFLECTION);
|
||||||
|
}
|
||||||
|
context.Repeat(15s);
|
||||||
|
}).Schedule(3min, [this](TaskContext /*context*/)
|
||||||
|
{
|
||||||
|
if (!_inBerserk)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_BERSERK);
|
||||||
|
_inBerserk = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
void KilledUnit(Unit* victim) override
|
||||||
{
|
{
|
||||||
// When Kazzak kills a player (not pets/totems), he regens some health
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
{
|
||||||
return;
|
Talk(SAY_KILL);
|
||||||
|
DoCastSelf(SPELL_CAPTURE_SOUL);
|
||||||
DoCast(me, SPELL_CAPTURE_SOUL);
|
}
|
||||||
|
|
||||||
Talk(SAY_KILL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
@@ -109,63 +128,19 @@ public:
|
|||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
// Return since we have no target
|
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_events.Update(diff);
|
_scheduler.Update(diff);
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (uint32 eventId = _events.ExecuteEvent())
|
|
||||||
{
|
|
||||||
switch (eventId)
|
|
||||||
{
|
|
||||||
case EVENT_SHADOW_VOLLEY:
|
|
||||||
DoCastVictim(SPELL_SHADOW_VOLLEY);
|
|
||||||
_events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(4000, 6000));
|
|
||||||
break;
|
|
||||||
case EVENT_CLEAVE:
|
|
||||||
DoCastVictim(SPELL_CLEAVE);
|
|
||||||
_events.ScheduleEvent(EVENT_CLEAVE, urand(8000, 12000));
|
|
||||||
break;
|
|
||||||
case EVENT_THUNDERCLAP:
|
|
||||||
DoCastVictim(SPELL_THUNDERCLAP);
|
|
||||||
_events.ScheduleEvent(EVENT_THUNDERCLAP, urand(10000, 14000));
|
|
||||||
break;
|
|
||||||
case EVENT_VOID_BOLT:
|
|
||||||
DoCastVictim(SPELL_VOID_BOLT);
|
|
||||||
_events.ScheduleEvent(EVENT_VOID_BOLT, urand(15000, 18000));
|
|
||||||
break;
|
|
||||||
case EVENT_MARK_OF_KAZZAK:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 100.0f, true)))
|
|
||||||
DoCast(target, SPELL_MARK_OF_KAZZAK);
|
|
||||||
_events.ScheduleEvent(EVENT_MARK_OF_KAZZAK, 20000);
|
|
||||||
break;
|
|
||||||
case EVENT_ENRAGE:
|
|
||||||
Talk(EMOTE_FRENZY);
|
|
||||||
DoCast(me, SPELL_ENRAGE);
|
|
||||||
_events.ScheduleEvent(EVENT_ENRAGE, 30000);
|
|
||||||
break;
|
|
||||||
case EVENT_TWISTED_REFLECTION:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
|
|
||||||
DoCast(target, SPELL_TWISTED_REFLECTION);
|
|
||||||
_events.ScheduleEvent(EVENT_TWISTED_REFLECTION, 15000);
|
|
||||||
break;
|
|
||||||
case EVENT_BERSERK:
|
|
||||||
DoCast(me, SPELL_BERSERK);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventMap _events;
|
TaskScheduler _scheduler;
|
||||||
|
bool _inBerserk;
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
@@ -191,18 +166,18 @@ public:
|
|||||||
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
|
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
|
||||||
{
|
{
|
||||||
if (Unit* owner = GetUnitOwner())
|
if (Unit* owner = GetUnitOwner())
|
||||||
|
{
|
||||||
amount = CalculatePct(owner->GetPower(POWER_MANA), 5);
|
amount = CalculatePct(owner->GetPower(POWER_MANA), 5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnPeriodic(AuraEffect const* aurEff)
|
void OnPeriodic(AuraEffect const* aurEff)
|
||||||
{
|
{
|
||||||
Unit* target = GetTarget();
|
Unit* target = GetTarget();
|
||||||
|
|
||||||
if (target->GetPower(POWER_MANA) == 0)
|
if (target->GetPower(POWER_MANA) == 0)
|
||||||
{
|
{
|
||||||
target->CastSpell(target, SPELL_MARK_OF_KAZZAK_DAMAGE, true, nullptr, aurEff);
|
target->CastSpell(target, SPELL_MARK_OF_KAZZAK_DAMAGE, true, nullptr, aurEff);
|
||||||
// Remove aura
|
SetDuration(0); // Remove aura
|
||||||
SetDuration(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
|
|
||||||
enum Texts
|
enum Texts
|
||||||
{
|
{
|
||||||
SAY_AGGRO = 0,
|
SAY_AGGRO = 0,
|
||||||
SAY_EARTHQUAKE = 1,
|
SAY_EARTHQUAKE = 1,
|
||||||
SAY_OVERRUN = 2,
|
SAY_OVERRUN = 2,
|
||||||
SAY_SLAY = 3,
|
SAY_SLAY = 3,
|
||||||
SAY_DEATH = 4
|
SAY_DEATH = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
@@ -38,15 +38,6 @@ enum Spells
|
|||||||
SPELL_AURA_DEATH = 37131
|
SPELL_AURA_DEATH = 37131
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Events
|
|
||||||
{
|
|
||||||
EVENT_ENRAGE = 1,
|
|
||||||
EVENT_ARMOR = 2,
|
|
||||||
EVENT_CHAIN = 3,
|
|
||||||
EVENT_QUAKE = 4,
|
|
||||||
EVENT_OVERRUN = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
class boss_doomwalker : public CreatureScript
|
class boss_doomwalker : public CreatureScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -54,29 +45,23 @@ public:
|
|||||||
|
|
||||||
struct boss_doomwalkerAI : public ScriptedAI
|
struct boss_doomwalkerAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
boss_doomwalkerAI(Creature* creature) : ScriptedAI(creature)
|
boss_doomwalkerAI(Creature* creature) : ScriptedAI(creature) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_events.Reset();
|
|
||||||
_events.ScheduleEvent(EVENT_ENRAGE, 0);
|
|
||||||
_events.ScheduleEvent(EVENT_ARMOR, urand(5000, 13000));
|
|
||||||
_events.ScheduleEvent(EVENT_CHAIN, urand(10000, 30000));
|
|
||||||
_events.ScheduleEvent(EVENT_QUAKE, urand(25000, 35000));
|
|
||||||
_events.ScheduleEvent(EVENT_OVERRUN, urand(30000, 45000));
|
|
||||||
_inEnrage = false;
|
_inEnrage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
void KilledUnit(Unit* victim) override
|
||||||
{
|
{
|
||||||
victim->CastSpell(victim, SPELL_MARK_DEATH, 0);
|
victim->CastSpell(victim, SPELL_MARK_DEATH, 0);
|
||||||
|
|
||||||
if (urand(0, 4))
|
if (urand(0, 4))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Talk(SAY_SLAY);
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
Talk(SAY_SLAY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
@@ -87,13 +72,55 @@ public:
|
|||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
Talk(SAY_AGGRO);
|
Talk(SAY_AGGRO);
|
||||||
|
_scheduler.Schedule(1ms, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (!HealthAbovePct(20))
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_ENRAGE);
|
||||||
|
context.Repeat(6s);
|
||||||
|
_inEnrage = true;
|
||||||
|
}
|
||||||
|
}).Schedule(5s, 13s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_SUNDER_ARMOR);
|
||||||
|
context.Repeat(10s, 25s);
|
||||||
|
}).Schedule(10s, 30s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_CHAIN_LIGHTNING);
|
||||||
|
}
|
||||||
|
context.Repeat(7s, 27s);
|
||||||
|
}).Schedule(25s, 35s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (urand(0, 1))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Talk(SAY_EARTHQUAKE);
|
||||||
|
if (_inEnrage) // avoid enrage + earthquake
|
||||||
|
{
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_ENRAGE);
|
||||||
|
}
|
||||||
|
DoCastAOE(SPELL_EARTHQUAKE);
|
||||||
|
context.Repeat(30s, 55s);
|
||||||
|
}).Schedule(30s, 45s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
Talk(SAY_OVERRUN);
|
||||||
|
DoCastVictim(SPELL_OVERRUN);
|
||||||
|
context.Repeat(25s, 40s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveInLineOfSight(Unit* who) override
|
void MoveInLineOfSight(Unit* who) override
|
||||||
{
|
{
|
||||||
if (who && who->GetTypeId() == TYPEID_PLAYER && me->IsValidAttackTarget(who))
|
if (who && who->GetTypeId() == TYPEID_PLAYER && me->IsValidAttackTarget(who))
|
||||||
|
{
|
||||||
if (who->HasAura(SPELL_MARK_DEATH) && !who->HasAura(27827)) // Spirit of Redemption
|
if (who->HasAura(SPELL_MARK_DEATH) && !who->HasAura(27827)) // Spirit of Redemption
|
||||||
|
{
|
||||||
who->CastSpell(who, SPELL_AURA_DEATH, 1);
|
who->CastSpell(who, SPELL_AURA_DEATH, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
@@ -101,59 +128,15 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_events.Update(diff);
|
_scheduler.Update(diff);
|
||||||
|
|
||||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (uint32 eventId = _events.ExecuteEvent())
|
|
||||||
{
|
|
||||||
switch (eventId)
|
|
||||||
{
|
|
||||||
case EVENT_ENRAGE:
|
|
||||||
if (!HealthAbovePct(20))
|
|
||||||
{
|
|
||||||
DoCast(me, SPELL_ENRAGE);
|
|
||||||
_events.ScheduleEvent(EVENT_ENRAGE, 6000);
|
|
||||||
_inEnrage = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EVENT_OVERRUN:
|
|
||||||
Talk(SAY_OVERRUN);
|
|
||||||
DoCastVictim(SPELL_OVERRUN);
|
|
||||||
_events.ScheduleEvent(EVENT_OVERRUN, urand(25000, 40000));
|
|
||||||
break;
|
|
||||||
case EVENT_QUAKE:
|
|
||||||
if (urand(0, 1))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Talk(SAY_EARTHQUAKE);
|
|
||||||
|
|
||||||
//remove enrage before casting earthquake because enrage + earthquake = 16000dmg over 8sec and all dead
|
|
||||||
if (_inEnrage)
|
|
||||||
me->RemoveAurasDueToSpell(SPELL_ENRAGE);
|
|
||||||
|
|
||||||
DoCast(me, SPELL_EARTHQUAKE);
|
|
||||||
_events.ScheduleEvent(EVENT_QUAKE, urand(30000, 55000));
|
|
||||||
break;
|
|
||||||
case EVENT_CHAIN:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true))
|
|
||||||
DoCast(target, SPELL_CHAIN_LIGHTNING);
|
|
||||||
_events.ScheduleEvent(EVENT_CHAIN, urand(7000, 27000));
|
|
||||||
break;
|
|
||||||
case EVENT_ARMOR:
|
|
||||||
DoCastVictim(SPELL_SUNDER_ARMOR);
|
|
||||||
_events.ScheduleEvent(EVENT_ARMOR, urand(10000, 25000));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventMap _events;
|
TaskScheduler _scheduler;
|
||||||
bool _inEnrage;
|
bool _inEnrage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,20 +15,7 @@
|
|||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ScriptData
|
#include "GameObjectAI.h"
|
||||||
SDName: Hellfire_Peninsula
|
|
||||||
SD%Complete: 100
|
|
||||||
SDComment: Quest support: 9375, 9410, 9418, 10129, 10146, 10162, 10163, 10340, 10346, 10347, 10382 (Special flight paths) "Needs update"
|
|
||||||
SDCategory: Hellfire Peninsula
|
|
||||||
EndScriptData */
|
|
||||||
|
|
||||||
/* ContentData
|
|
||||||
npc_aeranas
|
|
||||||
npc_ancestral_wolf
|
|
||||||
npc_wounded_blood_elf
|
|
||||||
npc_fel_guard_hound
|
|
||||||
EndContentData */
|
|
||||||
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
@@ -403,6 +390,62 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Beacon
|
||||||
|
{
|
||||||
|
NPC_STONESCHYE_WHELP = 16927,
|
||||||
|
};
|
||||||
|
|
||||||
|
class go_beacon : public GameObjectScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
go_beacon() : GameObjectScript("go_beacon") { }
|
||||||
|
|
||||||
|
struct go_beaconAI : public GameObjectAI
|
||||||
|
{
|
||||||
|
go_beaconAI(GameObject* gameObject) : GameObjectAI(gameObject) { }
|
||||||
|
|
||||||
|
std::list<Creature*> creatureList;
|
||||||
|
|
||||||
|
void OnStateChanged(uint32 state, Unit* /*unit*/) override
|
||||||
|
{
|
||||||
|
if (state == GO_ACTIVATED)
|
||||||
|
{
|
||||||
|
me->GetCreaturesWithEntryInRange(creatureList, 40, NPC_STONESCHYE_WHELP);
|
||||||
|
{
|
||||||
|
for (Creature* whelp : creatureList)
|
||||||
|
{
|
||||||
|
if (whelp->IsAlive() && !whelp->IsInCombat() && whelp->GetMotionMaster()->GetCurrentMovementGeneratorType() != HOME_MOTION_TYPE)
|
||||||
|
{
|
||||||
|
whelp->GetMotionMaster()->MovePoint(0, me->GetNearPosition(4.0f, whelp->GetOrientation()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == GO_JUST_DEACTIVATED)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
for (Creature* whelp : creatureList)
|
||||||
|
{
|
||||||
|
if (whelp->IsAlive() && !whelp->IsInCombat() && whelp->GetMotionMaster()->GetCurrentMovementGeneratorType() != HOME_MOTION_TYPE)
|
||||||
|
{
|
||||||
|
whelp->GetMotionMaster()->MoveTargetedHome();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
creatureList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GameObjectAI* GetAI(GameObject* go) const override
|
||||||
|
{
|
||||||
|
return new go_beaconAI(go);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_hellfire_peninsula()
|
void AddSC_hellfire_peninsula()
|
||||||
{
|
{
|
||||||
// Ours
|
// Ours
|
||||||
@@ -413,4 +456,5 @@ void AddSC_hellfire_peninsula()
|
|||||||
new npc_ancestral_wolf();
|
new npc_ancestral_wolf();
|
||||||
new npc_wounded_blood_elf();
|
new npc_wounded_blood_elf();
|
||||||
new npc_fel_guard_hound();
|
new npc_fel_guard_hound();
|
||||||
|
new go_beacon();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2000,8 +2000,15 @@ public:
|
|||||||
|
|
||||||
bool OnGossipHello(Player* player, Creature* creature) override
|
bool OnGossipHello(Player* player, Creature* creature) override
|
||||||
{
|
{
|
||||||
AddGossipItemFor(player, GOSSIP_MENU_EXP_NPC, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); // "I no longer wish to gain experience."
|
if (!player->HasPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN))
|
||||||
AddGossipItemFor(player, GOSSIP_MENU_EXP_NPC, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); // "I wish to start gaining experience again."
|
{
|
||||||
|
AddGossipItemFor(player, GOSSIP_MENU_EXP_NPC, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); // "I no longer wish to gain experience."
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddGossipItemFor(player, GOSSIP_MENU_EXP_NPC, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); // "I wish to start gaining experience again."
|
||||||
|
}
|
||||||
|
|
||||||
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature);
|
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user