11 Commits
Author SHA1 Message Date
luis f60ffe5032 wq fix 2026-09-24 22:23:01 -03:00
luis ebf4b1b22c misc 2026-09-24 21:59:38 -03:00
luis 27c5476d5a Add the missing Underbog boss script. 2026-09-24 21:58:52 -03:00
luis 83da508058 Rebuild the Exile's Reach quests from the retail storyline. 2026-09-24 21:54:46 -03:00
luis ebbe43a634 exiles 2026-09-24 21:52:06 -03:00
luis ff44fb9b69 The Necrotic Wake 2026-09-24 21:36:17 -03:00
luis 7947401f3d typo 2026-09-24 21:22:55 -03:00
luis 9c7248966d EcodomeAldani 2026-09-24 21:21:39 -03:00
luis e4daabc3a1 Operation Floodgate 2026-09-24 21:10:56 -03:00
luis 1835f627f6 Update enums part 1 2026-09-24 20:51:04 -03:00
luis ae710dcbbc exiles and waking shore 2026-09-24 20:19:16 -03:00
29 changed files with 4480 additions and 27 deletions
File diff suppressed because one or more lines are too long
@@ -0,0 +1,576 @@
-- Alliance chain after Cooking Meat.
-- Quilboar pair, then the copter. Harpy trio, then Message to Base. Who Lurks after Westward Bound.
-- To Darkmaul Citadel waits for both Message to Base and Who Lurks. The ogre trio waits for Right Beneath Their Eyes.
UPDATE `quest_template_addon` SET `PrevQuestID` = 55173, `NextQuestID` = 55193, `ExclusiveGroup` = -55186 WHERE `ID` IN (55186, 55184);
UPDATE `quest_template_addon` SET `PrevQuestID` = 55194, `NextQuestID` = 0, `ExclusiveGroup` = 0 WHERE `ID` = 55196;
UPDATE `quest_template_addon` SET `PrevQuestID` = 55196, `NextQuestID` = 55882, `ExclusiveGroup` = -55764 WHERE `ID` IN (55763, 55764, 55881);
UPDATE `quest_template_addon` SET `PrevQuestID` = 55965, `NextQuestID` = 56344, `ExclusiveGroup` = -55882 WHERE `ID` = 55639;
UPDATE `quest_template_addon` SET `NextQuestID` = 56344, `ExclusiveGroup` = -55882 WHERE `ID` = 55882;
UPDATE `quest_template_addon` SET `PrevQuestID` = 55981, `NextQuestID` = 55992, `ExclusiveGroup` = -55988 WHERE `ID` IN (55988, 55989, 55990);
-- Horde mirror. Stocking Up already requires The Re-Deather. Westward Bound already requires Stocking Up.
UPDATE `quest_template_addon` SET `PrevQuestID` = 59935, `NextQuestID` = 59940, `ExclusiveGroup` = -59938 WHERE `ID` IN (59938, 59939);
UPDATE `quest_template_addon` SET `PrevQuestID` = 59950, `NextQuestID` = 0, `ExclusiveGroup` = 0 WHERE `ID` = 59943;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59943, `NextQuestID` = 59947, `ExclusiveGroup` = -59945 WHERE `ID` IN (59944, 59945, 59946);
UPDATE `quest_template_addon` SET `PrevQuestID` = 59948, `NextQuestID` = 59975, `ExclusiveGroup` = -59947 WHERE `ID` = 59949;
UPDATE `quest_template_addon` SET `NextQuestID` = 59975, `ExclusiveGroup` = -59947 WHERE `ID` = 59947;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59978, `NextQuestID` = 59984, `ExclusiveGroup` = -59979 WHERE `ID` IN (59979, 59980, 59981);
-- Class lessons open at the ogre ruins, after Stocking Up. Shaman opens after Who Lurks in the Pit, which is where the ghost wolf's pack is freed.
-- The follow-up is also on the turn-in NPC, so it needs its own previous quest or it can be taken first.
UPDATE `quest_template_addon` SET `PrevQuestID` = 55194 WHERE `ID` IN (58914, 58917, 58923, 58953, 58962, 59347, 59350, 59352, 59355);
UPDATE `quest_template_addon` SET `PrevQuestID` = 55639 WHERE `ID` = 59002;
UPDATE `quest_template_addon` SET `PrevQuestID` = 58914 WHERE `ID` = 58915;
UPDATE `quest_template_addon` SET `PrevQuestID` = 58917 WHERE `ID` = 58933;
UPDATE `quest_template_addon` SET `PrevQuestID` = 58923 WHERE `ID` = 58946;
UPDATE `quest_template_addon` SET `PrevQuestID` = 58953 WHERE `ID` = 58960;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59347 WHERE `ID` = 59349;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59352 WHERE `ID` = 59354;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59355 WHERE `ID` = 59356;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59356 WHERE `ID` = 60168;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59950 WHERE `ID` IN (59971, 59967, 59958, 59961, 59970, 59956, 59951, 59954, 59952);
UPDATE `quest_template_addon` SET `PrevQuestID` = 59949 WHERE `ID` = 59969;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59971 WHERE `ID` = 59972;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59967 WHERE `ID` = 59968;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59958 WHERE `ID` = 60174;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59961 WHERE `ID` = 59965;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59956 WHERE `ID` = 59957;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59954 WHERE `ID` = 59955;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59952 WHERE `ID` = 59953;
UPDATE `quest_template_addon` SET `PrevQuestID` = 59953 WHERE `ID` = 60162;
-- Availability. ElseGroups are OR. Rows in one ElseGroup are AND.
-- Team 469 is Alliance, team 67 is Horde. Class mask 4 is hunter, 512 is monk.
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 19 AND `SourceEntry` IN (
55173, 59935, 59254, 59933, 55186, 55184, 59938, 59939, 85678, 85679
);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
-- Alliance Northbound: after either tactics quest, or after Cooking Meat for hunters (they skip tactics).
(19, 0, 55173, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Northbound - Alliance'),
(19, 0, 55173, 0, 0, 8, 0, 59254, 0, 0, 0, 0, 0, '', 'Exile Northbound - Enhanced Combat Tactics rewarded'),
(19, 0, 55173, 0, 1, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Northbound - Alliance'),
(19, 0, 55173, 0, 1, 8, 0, 59339, 0, 0, 0, 0, 0, '', 'Exile Northbound - monk tactics rewarded'),
(19, 0, 55173, 0, 2, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Northbound - Alliance'),
(19, 0, 55173, 0, 2, 8, 0, 55174, 0, 0, 0, 0, 0, '', 'Exile Northbound - Cooking Meat rewarded'),
(19, 0, 55173, 0, 2, 15, 0, 4, 0, 0, 0, 0, 0, '', 'Exile Northbound - hunter'),
-- Horde Northbound
(19, 0, 59935, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Northbound - Horde'),
(19, 0, 59935, 0, 0, 8, 0, 59933, 0, 0, 0, 0, 0, '', 'Exile Northbound - Enhanced Combat Tactics rewarded'),
(19, 0, 59935, 0, 1, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Northbound - Horde'),
(19, 0, 59935, 0, 1, 8, 0, 59934, 0, 0, 0, 0, 0, '', 'Exile Northbound - monk tactics rewarded'),
(19, 0, 59935, 0, 2, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Northbound - Horde'),
(19, 0, 59935, 0, 2, 8, 0, 59932, 0, 0, 0, 0, 0, '', 'Exile Northbound - Cooking Meat rewarded'),
(19, 0, 59935, 0, 2, 15, 0, 4, 0, 0, 0, 0, 0, '', 'Exile Northbound - hunter'),
-- Generic tactics is every class except hunter and monk. Hunters go north from Cooking Meat. Monks use the monk tactics quest.
(19, 0, 59254, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile tactics - Alliance'),
(19, 0, 59254, 0, 0, 15, 0, 516, 0, 0, 1, 0, 0, '', 'Exile tactics - not hunter or monk'),
(19, 0, 59933, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile tactics - Horde'),
(19, 0, 59933, 0, 0, 15, 0, 516, 0, 0, 1, 0, 0, '', 'Exile tactics - not hunter or monk'),
-- Quilboar after Northbound. Hunters finish Taming the Wilds first.
(19, 0, 55186, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile quilboar - Alliance'),
(19, 0, 55186, 0, 0, 8, 0, 55173, 0, 0, 0, 0, 0, '', 'Exile quilboar - Northbound rewarded'),
(19, 0, 55186, 0, 0, 15, 0, 4, 0, 0, 1, 0, 0, '', 'Exile quilboar - not hunter'),
(19, 0, 55186, 0, 1, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile quilboar - Alliance hunter'),
(19, 0, 55186, 0, 1, 8, 0, 59342, 0, 0, 0, 0, 0, '', 'Exile quilboar - Taming the Wilds rewarded'),
(19, 0, 55184, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Alliance'),
(19, 0, 55184, 0, 0, 8, 0, 55173, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Northbound rewarded'),
(19, 0, 55184, 0, 0, 15, 0, 4, 0, 0, 1, 0, 0, '', 'Exile shadow magic - not hunter'),
(19, 0, 55184, 0, 1, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Alliance hunter'),
(19, 0, 55184, 0, 1, 8, 0, 59342, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Taming the Wilds rewarded'),
(19, 0, 59938, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile quilboar - Horde'),
(19, 0, 59938, 0, 0, 8, 0, 59935, 0, 0, 0, 0, 0, '', 'Exile quilboar - Northbound rewarded'),
(19, 0, 59938, 0, 0, 15, 0, 4, 0, 0, 1, 0, 0, '', 'Exile quilboar - not hunter'),
(19, 0, 59938, 0, 1, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile quilboar - Horde hunter'),
(19, 0, 59938, 0, 1, 8, 0, 59937, 0, 0, 0, 0, 0, '', 'Exile quilboar - Taming the Wilds rewarded'),
(19, 0, 59939, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Horde'),
(19, 0, 59939, 0, 0, 8, 0, 59935, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Northbound rewarded'),
(19, 0, 59939, 0, 0, 15, 0, 4, 0, 0, 1, 0, 0, '', 'Exile shadow magic - not hunter'),
(19, 0, 59939, 0, 1, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Horde hunter'),
(19, 0, 59939, 0, 1, 8, 0, 59937, 0, 0, 0, 0, 0, '', 'Exile shadow magic - Taming the Wilds rewarded'),
-- Repair Yourself is the optional vendor stop at the ogre ruins, after Stocking Up.
(19, 0, 85678, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Repair Yourself - Alliance'),
(19, 0, 85678, 0, 0, 8, 0, 55194, 0, 0, 0, 0, 0, '', 'Exile Repair Yourself - Stocking Up rewarded'),
(19, 0, 85679, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Repair Yourself - Horde'),
(19, 0, 85679, 0, 0, 8, 0, 59950, 0, 0, 0, 0, 0, '', 'Exile Repair Yourself - Stocking Up rewarded');
-- Faction lock for the shared story and class quests. Quests above already carry their own team row.
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 19 AND `ConditionTypeOrReference` = 6 AND `SourceEntry` IN (
56775, 58209, 58208, 55122, 54951, 54952, 55174, 59339, 59342, 55193, 56034, 55879, 55194, 55196, 55763, 55764, 55881, 55882, 55965, 55639, 56344, 55981, 55988, 55989, 55990, 55992, 55991,
58914, 58915, 58917, 58933, 58923, 58946, 58953, 58960, 58962, 59002, 59347, 59349, 59350, 59352, 59354, 59355, 59356, 60168,
59926, 59927, 59928, 59929, 59930, 59931, 59932, 59934, 59937, 59940, 59941, 59942, 59943, 59944, 59945, 59946, 59947, 59948, 59949, 59950, 59975, 59978, 59979, 59980, 59981, 59984, 59985,
59951, 59952, 59953, 59954, 59955, 59956, 59957, 59958, 59961, 59965, 59967, 59968, 59969, 59970, 59971, 59972, 60162, 60174,
54933, 56839
);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(19, 0, 56775, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Warming Up - Alliance'),
(19, 0, 58209, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Stand Your Ground - Alliance'),
(19, 0, 58208, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Brace for Impact - Alliance'),
(19, 0, 55122, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Murloc Mania - Alliance'),
(19, 0, 54951, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Emergency First Aid - Alliance'),
(19, 0, 54952, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Finding the Lost Expedition - Alliance'),
(19, 0, 55174, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Cooking Meat - Alliance'),
(19, 0, 59339, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile monk tactics - Alliance'),
(19, 0, 59342, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Taming the Wilds - Alliance'),
(19, 0, 55193, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Scout-o-Matic - Alliance'),
(19, 0, 56034, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Re-sizing - Alliance'),
(19, 0, 55879, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile boar ride - Alliance'),
(19, 0, 55194, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Stocking Up - Alliance'),
(19, 0, 55196, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Harpy Problem - Alliance'),
(19, 0, 55763, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Rescue Meredy - Alliance'),
(19, 0, 55764, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Harpy Culling - Alliance'),
(19, 0, 55881, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Purge the Totems - Alliance'),
(19, 0, 55882, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Message to Base - Alliance'),
(19, 0, 55965, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Westward Bound - Alliance'),
(19, 0, 55639, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Who Lurks - Alliance'),
(19, 0, 56344, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile To Darkmaul - Alliance'),
(19, 0, 55981, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Right Beneath Their Eyes - Alliance'),
(19, 0, 55988, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Like Ogres - Alliance'),
(19, 0, 55989, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Catapult Destruction - Alliance'),
(19, 0, 55990, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Controlling their Stones - Alliance'),
(19, 0, 55992, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Dungeon - Alliance'),
(19, 0, 55991, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile An End to Beginnings - Alliance'),
(19, 0, 58914, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Warrior''s End - Alliance'),
(19, 0, 58915, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Hjalmar - Alliance'),
(19, 0, 58917, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Rogue''s End - Alliance'),
(19, 0, 58933, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Deadliest of Poisons - Alliance'),
(19, 0, 58923, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Paladin''s Service - Alliance'),
(19, 0, 58946, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile The Divine''s Shield - Alliance'),
(19, 0, 58953, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Priest''s End - Alliance'),
(19, 0, 58960, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Resurrecting the Recruits - Alliance'),
(19, 0, 58962, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Warlock''s Bargain - Alliance'),
(19, 0, 59002, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Shaman''s Duty - Alliance'),
(19, 0, 59347, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Monk''s Focus - Alliance'),
(19, 0, 59349, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile One Last Spar - Alliance'),
(19, 0, 59350, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Druid''s Form - Alliance'),
(19, 0, 59352, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Mage''s Knowledge - Alliance'),
(19, 0, 59354, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Best Way to Use Sheep - Alliance'),
(19, 0, 59355, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile A Hunter''s Trap - Alliance'),
(19, 0, 59356, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Hunting the Stalker - Alliance'),
(19, 0, 60168, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile The Art of Taming - Alliance'),
(19, 0, 59926, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Warming Up - Horde'),
(19, 0, 59927, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Stand Your Ground - Horde'),
(19, 0, 59928, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Brace for Impact - Horde'),
(19, 0, 59929, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Murloc Mania - Horde'),
(19, 0, 59930, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Emergency First Aid - Horde'),
(19, 0, 59931, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Finding the Lost Expedition - Horde'),
(19, 0, 59932, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Cooking Meat - Horde'),
(19, 0, 59934, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile monk tactics - Horde'),
(19, 0, 59937, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Taming the Wilds - Horde'),
(19, 0, 59940, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Choppy Booster - Horde'),
(19, 0, 59941, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Re-sizing - Horde'),
(19, 0, 59942, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile The Re-Deather - Horde'),
(19, 0, 59943, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Harpy Problem - Horde'),
(19, 0, 59944, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Rescue Herbert - Horde'),
(19, 0, 59945, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Harpy Culling - Horde'),
(19, 0, 59946, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Purge the Totems - Horde'),
(19, 0, 59947, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Message to Base - Horde'),
(19, 0, 59948, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Westward Bound - Horde'),
(19, 0, 59949, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Who Lurks - Horde'),
(19, 0, 59950, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Stocking Up - Horde'),
(19, 0, 59975, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile To Darkmaul - Horde'),
(19, 0, 59978, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Right Beneath Their Eyes - Horde'),
(19, 0, 59979, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Like Ogres - Horde'),
(19, 0, 59980, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Catapult Destruction - Horde'),
(19, 0, 59981, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Controlling their Stones - Horde'),
(19, 0, 59984, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Dungeon - Horde'),
(19, 0, 59985, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile An End to Beginnings - Horde'),
(19, 0, 59951, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Druid''s Form - Horde'),
(19, 0, 59952, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Hunter''s Trap - Horde'),
(19, 0, 59953, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Hunting the Stalker - Horde'),
(19, 0, 60162, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile The Art of Taming - Horde'),
(19, 0, 59954, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Mage''s Knowledge - Horde'),
(19, 0, 59955, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Best Way to Use Sheep - Horde'),
(19, 0, 59956, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Monk''s Focus - Horde'),
(19, 0, 59957, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile One Last Spar - Horde'),
(19, 0, 59958, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Paladin''s Service - Horde'),
(19, 0, 60174, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile The Divine''s Shield - Horde'),
(19, 0, 59961, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Priest''s End - Horde'),
(19, 0, 59965, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Resurrecting the Recruits - Horde'),
(19, 0, 59967, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Rogue''s End - Horde'),
(19, 0, 59968, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Deadliest of Poisons - Horde'),
(19, 0, 59969, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Shaman''s Duty - Horde'),
(19, 0, 59970, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Warlock''s Bargain - Horde'),
(19, 0, 59971, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile A Warrior''s End - Horde'),
(19, 0, 59972, 0, 0, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Hjalmar - Horde'),
-- Freeing the Light and Killclaw already have one ElseGroup per faction. The team row belongs in that same group.
(19, 0, 54933, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Freeing the Light - Alliance'),
(19, 0, 54933, 0, 1, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Freeing the Light - Horde'),
(19, 0, 56839, 0, 0, 6, 0, 469, 0, 0, 0, 0, 0, '', 'Exile Killclaw - Alliance'),
(19, 0, 56839, 0, 1, 6, 0, 67, 0, 0, 0, 0, 0, '', 'Exile Killclaw - Horde');
-- Coulston's credit gossip existed, but the creature was never linked to it.
DELETE FROM `creature_template_gossip` WHERE `CreatureID` = 162972 AND `MenuID` = 27999;
INSERT INTO `creature_template_gossip` (`CreatureID`, `MenuID`, `VerifiedBuild`) VALUES (162972, 27999, 69875);
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` IN (163338, 163209, 167478, 167184, 164865);
UPDATE `creature_template` SET `faction` = 14 WHERE `entry` = 164865;
DELETE FROM `smart_scripts` WHERE `source_type` = 0 AND `entryorguid` IN (163338, 163209, 167478, 167184, 164865);
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`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `comment`) VALUES
(163338, 0, 0, 0, '', 9, 0, 100, 0, 0, 8, 2000, 2000, 0, '', 33, 163338, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile ghost wolf - free the pack after the blossoms are burned'),
(163209, 0, 0, 1, '', 62, 0, 100, 0, 25143, 0, 0, 0, 0, '', 33, 163209, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile Hubert Lucas - body investigated'),
(163209, 0, 1, 0, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 33, 163218, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile Hubert Lucas - grimoire summons the voidwalker'),
(167478, 0, 0, 1, '', 62, 0, 100, 0, 25576, 0, 0, 0, 0, '', 33, 167478, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile Sprag Buzzboom - body investigated'),
(167478, 0, 1, 0, '', 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 33, 167482, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile Sprag Buzzboom - grimoire summons the voidwalker'),
(167184, 0, 0, 0, '', 62, 0, 100, 0, 25589, 0, 0, 0, 0, '', 33, 167184, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile Drizza - first expedition rogue found'),
(164865, 0, 0, 0, '', 25, 0, 100, 0, 0, 0, 0, 0, 0, '', 8, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 'Exile sparring partner - stay passive'),
(164865, 0, 1, 0, '', 8, 0, 100, 0, 320863, 0, 0, 0, 0, '', 33, 164865, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 'Exile sparring partner - Touch of Death');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 22 AND `SourceEntry` IN (163338, 163209, 167478);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(22, 0, 163338, 0, 0, 60, 0, 59002, 395317, 1, 0, 0, 0, '', 'Free the ghost wolf after Alliance blossoms are burned'),
(22, 0, 163338, 0, 1, 60, 0, 59969, 397336, 1, 0, 0, 0, '', 'Free the ghost wolf after Horde blossoms are burned'),
(22, 1, 163209, 0, 0, 2, 0, 174947, 1, 0, 0, 0, 0, '', 'Summon the voidwalker once the old grimoire is in the bag'),
(22, 1, 167478, 0, 0, 2, 0, 174947, 1, 0, 0, 0, 0, '', 'Summon the voidwalker once the old grimoire is in the bag');
UPDATE `creature` SET `PhaseId` = 0 WHERE `id` = 160664 AND `map` = 2261;
UPDATE `creature` SET `PhaseId` = 0 WHERE `id` = 166583 AND `map` = 2369;
UPDATE `trainer_spell` SET `ReqSkillLine` = 0, `ReqSkillRank` = 0 WHERE `ReqSkillLine` = 129;
DELETE FROM `gossip_menu` WHERE `MenuID` = 27999;
INSERT INTO `gossip_menu` (`MenuID`, `TextID`, `VerifiedBuild`) VALUES (27999, 1, 69875);
UPDATE `vehicle_template_accessory` SET `summontype` = 8 WHERE `summontype` = 0;
DELETE FROM `game_event` WHERE `eventEntry` = 152;
INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`)
VALUES (152, '2024-01-01 00:00:00', '2035-01-01 00:00:00', 5184000, 315360000, 0, 0, 'Arena Season 39', 0, 2);
DELETE FROM `game_event_arena_seasons` WHERE `season` = 39;
INSERT INTO `game_event_arena_seasons` (`eventEntry`, `season`) VALUES (152, 39);
DELETE FROM `spell_script_names` WHERE `spell_id` = 321628 AND `ScriptName` = 'spell_giant_boar_charge_321627';
UPDATE `creature_template` SET `ScriptName` = 'npc_tushui_leading_trainee' WHERE `entry` IN (54587, 65471);
UPDATE `areatrigger_create_properties` SET `ScriptName` = 'at_boss_the_coaglamation_blood_surge' WHERE `Id` = 34362 AND `IsCustom` = 0;
DELETE FROM `conversation_actors` WHERE `ConversationId` IN (12078, 12086, 12087, 12088, 12090, 13712) AND `Idx` IN (0, 1);
INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `ConversationActorGuid`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`) VALUES
(12078, 0, 0, 0, 149899, 0, 1, 0),
(12078, 0, 0, 1, 0, 0, 0, 1),
(12086, 0, 0, 0, 0, 0, 0, 1),
(12086, 0, 0, 1, 149899, 0, 1, 0),
(12087, 0, 0, 0, 0, 0, 0, 1),
(12087, 0, 0, 1, 149899, 0, 1, 0),
(12088, 0, 0, 0, 0, 0, 0, 1),
(12088, 0, 0, 1, 149899, 0, 1, 0),
(12090, 0, 0, 0, 0, 0, 0, 1),
(12090, 0, 0, 1, 156280, 0, 1, 0),
(13712, 0, 0, 0, 151091, 0, 1, 0),
(13712, 0, 0, 1, 0, 0, 0, 1);
-- The summoned Giant Boar (156267) is the vehicle the player rides.
-- It had no action-bar spell, so Trample never appeared and the button did nothing.
DELETE FROM `creature_template_spell` WHERE `CreatureID` = 156267 AND `Index` = 0;
INSERT INTO `creature_template_spell` (`CreatureID`, `Index`, `Spell`, `VerifiedBuild`) VALUES
(156267, 0, 305557, 69875);
INSERT INTO `quest_template_addon` (`ID`, `PrevQuestID`, `NextQuestID`, `ExclusiveGroup`, `BreadcrumbForQuestId`) VALUES
(54933, 0, 0, 0, 0), -- Freeing the Light
(54951, 55122, 54952, 0, 0), -- Emergency First Aid (Alliance)
(54952, 54951, 55174, 0, 0), -- Finding the Lost Expedition (Alliance)
(55122, 58208, 54951, 0, 0), -- Murloc Mania (Alliance)
(55173, 55174, 0, 0, 0), -- Northbound (Alliance)
(55174, 54952, 0, 0, 0), -- Cooking Meat (Alliance)
(55184, 55173, 55193, -55193, 0), -- Quilboar Shadow Magic (Alliance)
(55186, 55173, 55193, -55193, 0), -- Down with the Quilboar (Alliance)
(55193, 0, 56034, 0, 0), -- The Scout-o-Matic 5000 (Alliance)
(55194, 55879, 0, 0, 0), -- Stocking Up on Supplies (Alliance)
(55196, 55194, 0, 0, 0), -- The Harpy Problem (Alliance)
(55639, 55965, 85678, 0, 0), -- Who Lurks in the Pit (Alliance)
(55763, 55196, 55882, -55882, 0), -- The Rescue of Meredy Huntswell (Alliance)
(55764, 55196, 55882, -55882, 0), -- Harpy Culling (Alliance)
(55879, 56034, 55194, 0, 0), -- Ride of the Scientifically Enhanced Boar (Alliance)
(55881, 55196, 55882, -55882, 0), -- Purge the Totems (Alliance)
(55882, 0, 0, 0, 0), -- Message to Base (Alliance)
(55965, 55194, 55639, 0, 0), -- Westward Bound (Alliance)
(55981, 56344, 0, 0, 0), -- Right Beneath Their Eyes (Alliance)
(55988, 55981, 55992, -55992, 0), -- Like Ogres to the Slaughter (Alliance)
(55989, 55981, 55992, -55992, 0), -- Catapult Destruction (Alliance)
(55990, 55981, 55992, -55992, 0), -- Controlling their Stones (Alliance)
(55991, 55992, 0, 0, 0), -- An End to Beginnings (Alliance)
(55992, 0, 55991, 0, 0), -- Dungeon: Darkmaul Citadel (Alliance)
(56034, 55193, 55879, 0, 0), -- Re-sizing the Situation (Alliance)
(56344, 55882, 55981, 0, 0), -- To Darkmaul Citadel (Alliance)
(56775, 0, 58209, 0, 0), -- Warming Up (Alliance)
(56839, 0, 0, 0, 0), -- Killclaw the Terrible
(58208, 58209, 55122, 0, 0), -- Brace for Impact (Alliance)
(58209, 56775, 58208, 0, 0), -- Stand Your Ground (Alliance)
(58914, 55639, 58915, 0, 0), -- A Warrior's End (Alliance)
(58915, 58914, 0, 0, 0), -- Hjalmar's Final Execution (Alliance)
(58917, 55194, 58933, 0, 0), -- A Rogue's End (Alliance)
(58923, 55194, 58946, 0, 0), -- A Paladin's Service (Alliance)
(58933, 58917, 0, 0, 0), -- The Deadliest of Poisons (Alliance)
(58946, 58923, 0, 0, 0), -- The Divine's Shield (Alliance)
(58953, 55194, 58960, 0, 0), -- A Priest's End (Alliance)
(58960, 58953, 0, 0, 0), -- Resurrecting the Recruits (Alliance)
(58962, 55639, 0, 0, 0), -- A Warlock's Bargain (Alliance)
(59002, 55639, 0, 0, 0), -- A Shaman's Duty (Alliance)
(59254, 55174, 0, 0, 0), -- Enhanced Combat Tactics (Alliance)
(59339, 55174, 0, 0, 0), -- Enhanced Combat Tactics (Alliance)
(59342, 55173, 0, 0, 0), -- Taming the Wilds (Alliance)
(59347, 55882, 59349, 0, 0), -- A Monk's Focus (Alliance)
(59349, 59347, 0, 0, 0), -- One Last Spar (Alliance)
(59350, 55639, 0, 0, 0), -- A Druid's Form (Alliance)
(59352, 55882, 59354, 0, 0), -- A Mage's Knowledge (Alliance)
(59354, 59352, 0, 0, 0), -- The Best Way to Use Sheep (Alliance)
(59355, 55882, 59356, 0, 0), -- A Hunter's Trap (Alliance)
(59356, 59355, 60168, 0, 0), -- Hunting the Stalker (Alliance)
(59926, 0, 59927, 0, 0), -- Warming Up (Horde)
(59927, 59926, 59928, 0, 0), -- Stand Your Ground (Horde)
(59928, 59927, 59929, 0, 0), -- Brace for Impact (Horde)
(59929, 59928, 59930, 0, 0), -- Murloc Mania (Horde)
(59930, 59929, 59931, 0, 0), -- Emergency First Aid (Horde)
(59931, 59930, 59932, 0, 0), -- Finding the Lost Expedition (Horde)
(59932, 59931, 0, 0, 0), -- Cooking Meat (Horde)
(59933, 59932, 0, 0, 0), -- Enhanced Combat Tactics (Horde)
(59934, 59932, 0, 0, 0), -- Enhanced Combat Tactics (Horde)
(59935, 59932, 0, 0, 0), -- Northbound (Horde)
(59937, 59935, 0, 0, 0), -- Taming the Wilds (Horde)
(59938, 59935, 59940, -59940, 0), -- Down with the Quilboar (Horde)
(59939, 59935, 59940, -59940, 0), -- Forbidden Quillboar Shadow Magic (Horde)
(59940, 0, 59941, 0, 0), -- The Choppy Booster Mk. 5 (Horde)
(59941, 59940, 59942, 0, 0), -- Re-sizing the Situation (Horde)
(59942, 59941, 59950, 0, 0), -- The Re-Deather (Horde)
(59943, 59950, 0, 0, 0), -- The Harpy Problem (Horde)
(59944, 59943, 59947, -59947, 0), -- The Rescue of Herbert Gloomburst (Horde)
(59945, 59943, 59947, -59947, 0), -- Harpy Culling (Horde)
(59946, 59943, 59947, -59947, 0), -- Purge the Totems (Horde)
(59947, 0, 0, 0, 0), -- Message to Base (Horde)
(59948, 59950, 59949, 0, 0), -- Westward Bound (Horde)
(59949, 59948, 85679, 0, 0), -- Who Lurks in the Pit (Horde)
(59950, 59942, 0, 0, 0), -- Stocking Up on Supplies (Horde)
(59951, 59949, 0, 0, 0), -- A Druid's Form (Horde)
(59952, 59947, 59953, 0, 0), -- A Hunter's Trap (Horde)
(59953, 59952, 60162, 0, 0), -- Hunting the Stalker (Horde)
(59954, 59947, 59955, 0, 0), -- A Mage's Knowledge (Horde)
(59955, 59954, 0, 0, 0), -- The Best Way to Use Sheep (Horde)
(59956, 59947, 59957, 0, 0), -- A Monk's Focus (Horde)
(59957, 59956, 0, 0, 0), -- One Last Spar (Horde)
(59958, 59950, 60174, 0, 0), -- A Paladin's Service (Horde)
(59961, 59950, 59965, 0, 0), -- A Priest's End (Horde)
(59965, 59961, 0, 0, 0), -- Resurrecting the Recruits (Horde)
(59967, 59950, 59968, 0, 0), -- A Rogue's End (Horde)
(59968, 59967, 0, 0, 0), -- The Deadliest of Poisons (Horde)
(59969, 59949, 0, 0, 0), -- A Shaman's Duty (Horde)
(59970, 59950, 0, 0, 0), -- A Warlock's Bargain (Horde)
(59971, 59950, 59972, 0, 0), -- A Warrior's End (Horde)
(59972, 59971, 0, 0, 0), -- Hjalmar's Final Execution (Horde)
(59975, 59947, 59978, 0, 0), -- To Darkmaul Citadel (Horde)
(59978, 59975, 0, 0, 0), -- Right Beneath Their Eyes (Horde)
(59979, 59978, 59984, -59984, 0), -- Like Ogres to the Slaughter (Horde)
(59980, 59978, 59984, -59984, 0), -- Catapult Destruction (Horde)
(59981, 59978, 59984, -59984, 0), -- Controlling their Stones (Horde)
(59984, 0, 59985, 0, 0), -- Dungeon: Darkmaul Citadel (Horde)
(59985, 59984, 0, 0, 0), -- An End to Beginnings (Horde)
(60162, 59953, 0, 0, 0), -- The Art of Taming (Horde)
(60168, 59356, 0, 0, 0), -- The Art of Taming (Alliance)
(60174, 59958, 0, 0, 0), -- The Divine's Shield (Horde)
(66349, 0, 0, 0, 0), -- Training Rock
(85678, 55639, 0, 0, 0), -- Repair Yourself (Alliance)
(85679, 59949, 0, 0, 0); -- Repair Yourself (Horde)
ON DUPLICATE KEY UPDATE
`PrevQuestID` = VALUES(`PrevQuestID`),
`NextQuestID` = VALUES(`NextQuestID`),
`ExclusiveGroup` = VALUES(`ExclusiveGroup`),
`BreadcrumbForQuestId` = VALUES(`BreadcrumbForQuestId`);
-- Retail quest givers and turn-ins that were missing. The creature and quest pairs are the
-- sniffed rows of TrinityCore TDB 1210.26091, so every quest can be picked up and handed in
-- at the phase copy retail uses. Rows already present stay; only these are added.
-- 26 givers.
DELETE FROM `creature_queststarter` WHERE (`id`, `quest`) IN (
(156626, 54951), -- Lady Jaina Proudmoore: Emergency First Aid (Alliance)
(156626, 54952), -- Lady Jaina Proudmoore: Finding the Lost Expedition (Alliance)
(156626, 55122), -- Lady Jaina Proudmoore: Murloc Mania (Alliance)
(175031, 55173), -- Alaria: Northbound (Alliance)
(156651, 55174), -- Captain Garrick: Cooking Meat (Alliance)
(154327, 55184), -- Austin Huxworth: Quilboar Shadow Magic (Alliance)
(154327, 55186), -- Austin Huxworth: Down with the Quilboar (Alliance)
(149899, 55193), -- Lindie Springstock: The Scout-o-Matic 5000 (Alliance)
(156807, 55194), -- Lady Jaina Proudmoore: Stocking Up on Supplies (Alliance)
(156280, 55879), -- Lady Jaina Proudmoore: Ride of the Scientifically Enhanced Boar (Alliance)
(154300, 55965), -- Bjorn Stouthands: Westward Bound (Alliance)
(149899, 56034), -- Lindie Springstock: Re-sizing the Situation (Alliance)
(160664, 58208), -- Private Cole: Brace for Impact (Alliance)
(166583, 59928), -- Grunt Throg: Brace for Impact (Horde)
(166782, 59929), -- Thrall: Murloc Mania (Horde)
(166782, 59930), -- Thrall: Emergency First Aid (Horde)
(166782, 59931), -- Thrall: Finding the Lost Expedition (Horde)
(166906, 59932), -- Warlord Breka Grimaxe: Cooking Meat (Horde)
(175030, 59935), -- Won'sa: Northbound (Horde)
(166996, 59938), -- Mithdran Dawntracker: Down with the Quilboar (Horde)
(166996, 59939), -- Mithdran Dawntracker: Forbidden Quillboar Shadow Magic (Horde)
(167019, 59940), -- Cork Fizzlepop: The Choppy Booster Mk. 5 (Horde)
(167019, 59941), -- Cork Fizzlepop: Re-sizing the Situation (Horde)
(167019, 59942), -- Cork Fizzlepop: The Re-Deather (Horde)
(167221, 59948), -- Lana Jordan: Westward Bound (Horde)
(167212, 59950) -- Thrall: Stocking Up on Supplies (Horde)
);
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES
(156626, 54951, 69875), -- Lady Jaina Proudmoore: Emergency First Aid (Alliance)
(156626, 54952, 69875), -- Lady Jaina Proudmoore: Finding the Lost Expedition (Alliance)
(156626, 55122, 69875), -- Lady Jaina Proudmoore: Murloc Mania (Alliance)
(175031, 55173, 69875), -- Alaria: Northbound (Alliance)
(156651, 55174, 69875), -- Captain Garrick: Cooking Meat (Alliance)
(154327, 55184, 69875), -- Austin Huxworth: Quilboar Shadow Magic (Alliance)
(154327, 55186, 69875), -- Austin Huxworth: Down with the Quilboar (Alliance)
(149899, 55193, 69875), -- Lindie Springstock: The Scout-o-Matic 5000 (Alliance)
(156807, 55194, 69875), -- Lady Jaina Proudmoore: Stocking Up on Supplies (Alliance)
(156280, 55879, 69875), -- Lady Jaina Proudmoore: Ride of the Scientifically Enhanced Boar (Alliance)
(154300, 55965, 69875), -- Bjorn Stouthands: Westward Bound (Alliance)
(149899, 56034, 69875), -- Lindie Springstock: Re-sizing the Situation (Alliance)
(160664, 58208, 69875), -- Private Cole: Brace for Impact (Alliance)
(166583, 59928, 69875), -- Grunt Throg: Brace for Impact (Horde)
(166782, 59929, 69875), -- Thrall: Murloc Mania (Horde)
(166782, 59930, 69875), -- Thrall: Emergency First Aid (Horde)
(166782, 59931, 69875), -- Thrall: Finding the Lost Expedition (Horde)
(166906, 59932, 69875), -- Warlord Breka Grimaxe: Cooking Meat (Horde)
(175030, 59935, 69875), -- Won'sa: Northbound (Horde)
(166996, 59938, 69875), -- Mithdran Dawntracker: Down with the Quilboar (Horde)
(166996, 59939, 69875), -- Mithdran Dawntracker: Forbidden Quillboar Shadow Magic (Horde)
(167019, 59940, 69875), -- Cork Fizzlepop: The Choppy Booster Mk. 5 (Horde)
(167019, 59941, 69875), -- Cork Fizzlepop: Re-sizing the Situation (Horde)
(167019, 59942, 69875), -- Cork Fizzlepop: The Re-Deather (Horde)
(167221, 59948, 69875), -- Lana Jordan: Westward Bound (Horde)
(167212, 59950, 69875); -- Thrall: Stocking Up on Supplies (Horde)
-- 44 turn-ins.
DELETE FROM `creature_questender` WHERE (`id`, `quest`) IN (
(157114, 54933), -- Lightspawn: Freeing the Light
(156626, 54951), -- Lady Jaina Proudmoore: Emergency First Aid (Alliance)
(156607, 54952), -- Alaria: Finding the Lost Expedition (Alliance)
(156626, 55122), -- Lady Jaina Proudmoore: Murloc Mania (Alliance)
(154327, 55173), -- Austin Huxworth: Northbound (Alliance)
(156607, 55174), -- Alaria: Cooking Meat (Alliance)
(149915, 55184), -- Austin Huxworth: Quilboar Shadow Magic (Alliance)
(149899, 55186), -- Lindie Springstock: Down with the Quilboar (Alliance)
(149899, 55193), -- Lindie Springstock: The Scout-o-Matic 5000 (Alliance)
(156807, 55194), -- Lady Jaina Proudmoore: Stocking Up on Supplies (Alliance)
(156799, 55879), -- Wrathion: Ride of the Scientifically Enhanced Boar (Alliance)
(156891, 55965), -- Bjorn Stouthands: Westward Bound (Alliance)
(156280, 56034), -- Lady Jaina Proudmoore: Re-sizing the Situation (Alliance)
(155733, 56839), -- Hidden Treasure Chest: Killclaw the Terrible
(166782, 59929), -- Thrall: Murloc Mania (Horde)
(166782, 59930), -- Thrall: Emergency First Aid (Horde)
(166854, 59931), -- Won'sa: Finding the Lost Expedition (Horde)
(166906, 59931), -- Warlord Breka Grimaxe: Finding the Lost Expedition (Horde)
(166854, 59932), -- Won'sa: Cooking Meat (Horde)
(166996, 59935), -- Mithdran Dawntracker: Northbound (Horde)
(167019, 59938), -- Cork Fizzlepop: Down with the Quilboar (Horde)
(167020, 59939), -- Mithdran Dawntracker: Forbidden Quillboar Shadow Magic (Horde)
(167019, 59940), -- Cork Fizzlepop: The Choppy Booster Mk. 5 (Horde)
(167021, 59941), -- Thrall: Re-sizing the Situation (Horde)
(167126, 59942), -- Wrathion: The Re-Deather (Horde)
(167128, 59942), -- Wrathion: The Re-Deather (Horde)
(167291, 59943), -- Bo: The Harpy Problem (Horde)
(167182, 59944), -- Herbert Gloomburst: The Rescue of Herbert Gloomburst (Horde)
(167291, 59945), -- Bo: Harpy Culling (Horde)
(167291, 59946), -- Bo: Purge the Totems (Horde)
(167212, 59947), -- Thrall: Message to Base (Horde)
(167225, 59948), -- Lana Jordan: Westward Bound (Horde)
(167212, 59949), -- Thrall: Who Lurks in the Pit (Horde)
(167212, 59950), -- Thrall: Stocking Up on Supplies (Horde)
(167596, 59975), -- Thrall: To Darkmaul Citadel (Horde)
(167633, 59978), -- Thrall: Right Beneath Their Eyes (Horde)
(167632, 59979), -- Breka Grimaxe: Like Ogres to the Slaughter (Horde)
(167630, 59980), -- Shuja Grimaxe: Catapult Destruction (Horde)
(167183, 59981), -- Warlord Mulgrin Thunderwalker: Controlling their Stones (Horde)
(167675, 59984), -- Thrall: Dungeon: Darkmaul Citadel (Horde)
(244496, 59985), -- Kalecgos: An End to Beginnings (Horde)
(167212, 85679), -- Thrall: Repair Yourself (Horde)
(244496, 90840), -- Kalecgos: What's Your Specialty? (Horde)
(244496, 90842) -- Kalecgos: Home Is Where the Hearth Is (Horde)
);
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES
(157114, 54933, 69875), -- Lightspawn: Freeing the Light
(156626, 54951, 69875), -- Lady Jaina Proudmoore: Emergency First Aid (Alliance)
(156607, 54952, 69875), -- Alaria: Finding the Lost Expedition (Alliance)
(156626, 55122, 69875), -- Lady Jaina Proudmoore: Murloc Mania (Alliance)
(154327, 55173, 69875), -- Austin Huxworth: Northbound (Alliance)
(156607, 55174, 69875), -- Alaria: Cooking Meat (Alliance)
(149915, 55184, 69875), -- Austin Huxworth: Quilboar Shadow Magic (Alliance)
(149899, 55186, 69875), -- Lindie Springstock: Down with the Quilboar (Alliance)
(149899, 55193, 69875), -- Lindie Springstock: The Scout-o-Matic 5000 (Alliance)
(156807, 55194, 69875), -- Lady Jaina Proudmoore: Stocking Up on Supplies (Alliance)
(156799, 55879, 69875), -- Wrathion: Ride of the Scientifically Enhanced Boar (Alliance)
(156891, 55965, 69875), -- Bjorn Stouthands: Westward Bound (Alliance)
(156280, 56034, 69875), -- Lady Jaina Proudmoore: Re-sizing the Situation (Alliance)
(155733, 56839, 69875), -- Hidden Treasure Chest: Killclaw the Terrible
(166782, 59929, 69875), -- Thrall: Murloc Mania (Horde)
(166782, 59930, 69875), -- Thrall: Emergency First Aid (Horde)
(166854, 59931, 69875), -- Won'sa: Finding the Lost Expedition (Horde)
(166906, 59931, 69875), -- Warlord Breka Grimaxe: Finding the Lost Expedition (Horde)
(166854, 59932, 69875), -- Won'sa: Cooking Meat (Horde)
(166996, 59935, 69875), -- Mithdran Dawntracker: Northbound (Horde)
(167019, 59938, 69875), -- Cork Fizzlepop: Down with the Quilboar (Horde)
(167020, 59939, 69875), -- Mithdran Dawntracker: Forbidden Quillboar Shadow Magic (Horde)
(167019, 59940, 69875), -- Cork Fizzlepop: The Choppy Booster Mk. 5 (Horde)
(167021, 59941, 69875), -- Thrall: Re-sizing the Situation (Horde)
(167126, 59942, 69875), -- Wrathion: The Re-Deather (Horde)
(167128, 59942, 69875), -- Wrathion: The Re-Deather (Horde)
(167291, 59943, 69875), -- Bo: The Harpy Problem (Horde)
(167182, 59944, 69875), -- Herbert Gloomburst: The Rescue of Herbert Gloomburst (Horde)
(167291, 59945, 69875), -- Bo: Harpy Culling (Horde)
(167291, 59946, 69875), -- Bo: Purge the Totems (Horde)
(167212, 59947, 69875), -- Thrall: Message to Base (Horde)
(167225, 59948, 69875), -- Lana Jordan: Westward Bound (Horde)
(167212, 59949, 69875), -- Thrall: Who Lurks in the Pit (Horde)
(167212, 59950, 69875), -- Thrall: Stocking Up on Supplies (Horde)
(167596, 59975, 69875), -- Thrall: To Darkmaul Citadel (Horde)
(167633, 59978, 69875), -- Thrall: Right Beneath Their Eyes (Horde)
(167632, 59979, 69875), -- Breka Grimaxe: Like Ogres to the Slaughter (Horde)
(167630, 59980, 69875), -- Shuja Grimaxe: Catapult Destruction (Horde)
(167183, 59981, 69875), -- Warlord Mulgrin Thunderwalker: Controlling their Stones (Horde)
(167675, 59984, 69875), -- Thrall: Dungeon: Darkmaul Citadel (Horde)
(244496, 59985, 69875), -- Kalecgos: An End to Beginnings (Horde)
(167212, 85679, 69875), -- Thrall: Repair Yourself (Horde)
(244496, 90840, 69875), -- Kalecgos: What's Your Specialty? (Horde)
(244496, 90842, 69875); -- Kalecgos: Home Is Where the Hearth Is (Horde)
-- Faction. Retail keeps the two versions of every step apart through the race mask, not through
-- conditions. Alliance 2973060173 and Horde 1309324210 are RACEMASK_ALLIANCE and RACEMASK_HORDE
-- of this core, so every playable race of that faction is included, allied races and Haranir too.
-- Freeing the Light, Killclaw the Terrible and Training Rock have no faction on retail.
UPDATE `quest_template` SET `AllowableRaces` = 2973060173 WHERE `ID` IN (
54951, 54952, 55122, 55173, 55174, 55184, 55186, 55193, 55194, 55196, 55639, 55763, 55764, 55879, 55881,
55882, 55965, 55981, 55988, 55989, 55990, 55991, 55992, 56034, 56344, 56775, 58208, 58209, 58914, 58915,
58917, 58923, 58933, 58946, 58953, 58960, 58962, 59002, 59254, 59339, 59342, 59347, 59349, 59350, 59352,
59354, 59355, 59356, 60168, 85678
);
UPDATE `quest_template` SET `AllowableRaces` = 1309324210 WHERE `ID` IN (
59926, 59927, 59928, 59929, 59930, 59931, 59932, 59933, 59934, 59935, 59937, 59938, 59939, 59940, 59941,
59942, 59943, 59944, 59945, 59946, 59947, 59948, 59949, 59950, 59951, 59952, 59953, 59954, 59955, 59956,
59957, 59958, 59961, 59965, 59967, 59968, 59969, 59970, 59971, 59972, 59975, 59978, 59979, 59980, 59981,
59984, 59985, 60162, 60174, 85679
);
UPDATE `quest_template` SET `AllowableRaces` = 4290772991 WHERE `ID` IN (54933, 56839, 66349);
-- Enhanced Combat Tactics is warrior, paladin, rogue, priest, shaman, mage, warlock and druid on
-- retail. Monks use their own version, hunters get Taming the Wilds, and death knights, demon
-- hunters and evokers get neither and walk straight to Northbound.
INSERT INTO `quest_template_addon` (`ID`, `AllowableClasses`) VALUES
(59254, 1499), -- Enhanced Combat Tactics (Alliance)
(59933, 1499) -- Enhanced Combat Tactics (Horde)
ON DUPLICATE KEY UPDATE `AllowableClasses` = VALUES(`AllowableClasses`);
-- The quest-available conditions that gated this zone are gone. Northbound sat behind a rewarded
-- tactics quest, which no death knight, demon hunter or evoker can ever satisfy, so the island
-- ended for them at the Abandoned Camp. Order now comes from the chain above and faction from the
-- race mask, which is how retail does it.
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 19 AND `ConditionTypeOrReference` IN (6, 8, 15) AND `SourceEntry` IN (
54933, 54951, 54952, 55122, 55173, 55174, 55184, 55186, 55193, 55194, 55196, 55639, 55763, 55764, 55879,
55881, 55882, 55965, 55981, 55988, 55989, 55990, 55991, 55992, 56034, 56344, 56775, 56839, 58208, 58209,
58914, 58915, 58917, 58923, 58933, 58946, 58953, 58960, 58962, 59002, 59254, 59339, 59342, 59347, 59349,
59350, 59352, 59354, 59355, 59356, 59926, 59927, 59928, 59929, 59930, 59931, 59932, 59933, 59934, 59935,
59937, 59938, 59939, 59940, 59941, 59942, 59943, 59944, 59945, 59946, 59947, 59948, 59949, 59950, 59951,
59952, 59953, 59954, 59955, 59956, 59957, 59958, 59961, 59965, 59967, 59968, 59969, 59970, 59971, 59972,
59975, 59978, 59979, 59980, 59981, 59984, 59985, 60162, 60168, 60174, 66349, 85678, 85679
);
@@ -0,0 +1,115 @@
-- Murloc Mania (55122 / 59929) collects First Aid Kit 170549, the kit that "drops from Murloc
-- Watershapers and Murloc Spearhunters at the Murloc Hideaway". Item 168410 is the other kit with
-- the same name: it is handed out by Emergency First Aid to bandage the three survivors and is not
-- a drop, so looting it did nothing for the quest.
DELETE FROM `creature_loot_template` WHERE `Item` IN (168410, 170549) AND `Entry` IN (150228, 150229);
INSERT INTO `creature_loot_template` (`Entry`, `ItemType`, `Item`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(150228, 0, 170549, 100, 1, 1, 0, 1, 1, 'Murloc Spearhunter - First Aid Kit'),
(150229, 0, 170549, 100, 1, 1, 0, 1, 1, 'Murloc Watershaper - First Aid Kit');
DELETE FROM `creature_questitem` WHERE (`CreatureEntry`, `ItemId`) IN ((150228, 170549), (150229, 170549));
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 150228, 0, IFNULL(`x`.`nextIdx`, 0), 170549, 69875 -- Murloc Spearhunter
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 150228 AND `DifficultyID` = 0) `x`;
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 150229, 0, IFNULL(`x`.`nextIdx`, 0), 170549, 69875 -- Murloc Watershaper
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 150229 AND `DifficultyID` = 0) `x`;
-- Controlling their Stones (55990 / 59981) needs the three ward stones. The wiki has one page per
-- stone and each names its ogre: Jugnug drops 168599, Wug drops 168600, Grunk drops 168601.
-- Nothing dropped them here, so the runestone never accepted the player: the gameobject script
-- checks all three items before it gives the credit. Both the citadel ogres and the cooking-area
-- copies the script summons carry the loot, so the quest works whichever version is up.
DELETE FROM `creature_loot_template` WHERE `Item` IN (168599, 168600, 168601)
AND `Entry` IN (153581, 153582, 153583, 154145, 154146, 154147);
INSERT INTO `creature_loot_template` (`Entry`, `ItemType`, `Item`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(153583, 0, 168599, 100, 1, 1, 0, 1, 1, 'Jugnug - Ward Stone'),
(153582, 0, 168600, 100, 1, 1, 0, 1, 1, 'Wug - Ward Stone'),
(153581, 0, 168601, 100, 1, 1, 0, 1, 1, 'Grunk - Ward Stone'),
(154147, 0, 168599, 100, 1, 1, 0, 1, 1, 'Jugnug (cooking area) - Ward Stone'),
(154146, 0, 168600, 100, 1, 1, 0, 1, 1, 'Wug (cooking area) - Ward Stone'),
(154145, 0, 168601, 100, 1, 1, 0, 1, 1, 'Grunk (cooking area) - Ward Stone');
DELETE FROM `creature_questitem` WHERE (`CreatureEntry`, `ItemId`) IN ((153583, 168599), (153582, 168600), (153581, 168601), (154147, 168599), (154146, 168600), (154145, 168601));
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 153583, 0, IFNULL(`x`.`nextIdx`, 0), 168599, 69875 -- Jugnug
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 153583 AND `DifficultyID` = 0) `x`;
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 153582, 0, IFNULL(`x`.`nextIdx`, 0), 168600, 69875 -- Wug
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 153582 AND `DifficultyID` = 0) `x`;
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 153581, 0, IFNULL(`x`.`nextIdx`, 0), 168601, 69875 -- Grunk
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 153581 AND `DifficultyID` = 0) `x`;
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 154147, 0, IFNULL(`x`.`nextIdx`, 0), 168599, 69875 -- Jugnug (cooking area)
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 154147 AND `DifficultyID` = 0) `x`;
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 154146, 0, IFNULL(`x`.`nextIdx`, 0), 168600, 69875 -- Wug (cooking area)
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 154146 AND `DifficultyID` = 0) `x`;
INSERT INTO `creature_questitem` (`CreatureEntry`, `DifficultyID`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 154145, 0, IFNULL(`x`.`nextIdx`, 0), 168601, 69875 -- Grunk (cooking area)
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `creature_questitem` WHERE `CreatureEntry` = 154145 AND `DifficultyID` = 0) `x`;
-- Class quest pickups. The wiki links each item to the object it sits in:
-- Veil Blossom 174968 from object 342366 at the Ogre Ruins (A Shaman's Duty)
-- Old Grimoire 174947 from objects 342259 and 350998 (A Warlock's Bargain)
-- Meredy's Spell Book 175975 from object 346273 (A Mage's Knowledge, Alliance)
-- Herbert's Spell Book 178229 from object 351335 (A Mage's Knowledge, Horde)
-- Old Spring 175980 from object 346277 at the Ogre Ruins (A Hunter's Trap)
-- The item is only added to the loot id the object already carries, and only when that loot does
-- not have it yet. An object with no loot id is left alone: inventing one would write into a
-- loot table that may belong to something else.
INSERT INTO `gameobject_loot_template` (`Entry`, `ItemType`, `Item`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`)
SELECT DISTINCT `t`.`Data1`, 0, `m`.`item`, 100, 1, 1, 0, 1, 1, `m`.`comment`
FROM (
SELECT 342366 AS `object`, 174968 AS `item`, 'Veil Blossom' AS `comment`
UNION ALL SELECT 342259, 174947, 'Old Grimoire'
UNION ALL SELECT 350998, 174947, 'Old Grimoire'
UNION ALL SELECT 346273, 175975, 'Meredy''s Spell Book'
UNION ALL SELECT 351335, 178229, 'Herbert''s Spell Book'
UNION ALL SELECT 346277, 175980, 'Old Spring'
) `m`
JOIN `gameobject_template` `t` ON `t`.`entry` = `m`.`object` AND `t`.`type` = 3 AND `t`.`Data1` <> 0
WHERE NOT EXISTS (
SELECT 1 FROM `gameobject_loot_template` `l` WHERE `l`.`Entry` = `t`.`Data1` AND `l`.`Item` = `m`.`item`
);
DELETE FROM `gameobject_questitem` WHERE (`GameObjectEntry`, `ItemId`) IN ((342366, 174968), (342259, 174947), (350998, 174947), (346273, 175975), (351335, 178229), (346277, 175980));
INSERT INTO `gameobject_questitem` (`GameObjectEntry`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 342366, IFNULL(`x`.`nextIdx`, 0), 174968, 69875 -- Veil Blossom
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `gameobject_questitem` WHERE `GameObjectEntry` = 342366) `x`
WHERE EXISTS (SELECT 1 FROM `gameobject_template` WHERE `entry` = 342366);
INSERT INTO `gameobject_questitem` (`GameObjectEntry`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 342259, IFNULL(`x`.`nextIdx`, 0), 174947, 69875 -- Old Grimoire
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `gameobject_questitem` WHERE `GameObjectEntry` = 342259) `x`
WHERE EXISTS (SELECT 1 FROM `gameobject_template` WHERE `entry` = 342259);
INSERT INTO `gameobject_questitem` (`GameObjectEntry`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 350998, IFNULL(`x`.`nextIdx`, 0), 174947, 69875 -- Old Grimoire
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `gameobject_questitem` WHERE `GameObjectEntry` = 350998) `x`
WHERE EXISTS (SELECT 1 FROM `gameobject_template` WHERE `entry` = 350998);
INSERT INTO `gameobject_questitem` (`GameObjectEntry`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 346273, IFNULL(`x`.`nextIdx`, 0), 175975, 69875 -- Meredy's Spell Book
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `gameobject_questitem` WHERE `GameObjectEntry` = 346273) `x`
WHERE EXISTS (SELECT 1 FROM `gameobject_template` WHERE `entry` = 346273);
INSERT INTO `gameobject_questitem` (`GameObjectEntry`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 351335, IFNULL(`x`.`nextIdx`, 0), 178229, 69875 -- Herbert's Spell Book
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `gameobject_questitem` WHERE `GameObjectEntry` = 351335) `x`
WHERE EXISTS (SELECT 1 FROM `gameobject_template` WHERE `entry` = 351335);
INSERT INTO `gameobject_questitem` (`GameObjectEntry`, `Idx`, `ItemId`, `VerifiedBuild`)
SELECT 346277, IFNULL(`x`.`nextIdx`, 0), 175980, 69875 -- Old Spring
FROM (SELECT MAX(`Idx`) + 1 AS `nextIdx` FROM `gameobject_questitem` WHERE `GameObjectEntry` = 346277) `x`
WHERE EXISTS (SELECT 1 FROM `gameobject_template` WHERE `entry` = 346277);
-- Still open: Withering Hemlock 174916 for A Rogue's End. The wiki places the plant by the pond at
-- Killclaw's Lair but publishes no object id for it, and Rusted Chain 175981 has the same gap.
-- Neither is guessed here.
-- Swamplord Musel'ek and his bear Claw in The Underbog. The boss had no script in this core.
-- The script file is TrinityCore's boss_swamplord_muselek.cpp, which our tree was missing while
-- the other three Underbog bosses were present.
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'boss_swamplord_muselek' WHERE `entry` = 17826;
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_claw' WHERE `entry` = 17827;
DELETE FROM `spell_script_names` WHERE `spell_id` = 31564 AND `ScriptName` = 'spell_swamplord_muselek_move_away_primer';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(31564, 'spell_swamplord_muselek_move_away_primer');
+21 -12
View File
@@ -1229,7 +1229,7 @@ enum CharacterRestrictionFlags : uint32
CHARACTER_RESTRICTION_FLAG_EXPANSION_TRIAL = 0x00080000,
};
// Languages.db2 (12.0.1.66838)
// Languages.db2 (12.1.5.69952)
enum Language
{
LANG_UNIVERSAL = 0,
@@ -3292,7 +3292,7 @@ enum GameObjectDestructibleState
GO_DESTRUCTIBLE_REBUILDING = 3
};
// EmotesText.db2 (12.0.5.67186)
// EmotesText.db2 (12.1.5.69952)
enum TextEmotes
{
TEXT_EMOTE_AGREE = 1,
@@ -3565,7 +3565,7 @@ enum TextEmotes
TEXT_EMOTE_LEAN = 633,
};
// Emotes.db2 (12.0.7.68453)
// Emotes.db2 (12.1.5.69952)
// EnumUtils: DESCRIBE THIS
enum Emote : uint32
{
@@ -4056,6 +4056,11 @@ enum Emote : uint32
EMOTE_STATE_WORK_ZULAMAN_HAMMERING_SOUND = 1131,
EMOTE_ATTACK1H_ZONE2_BREAKING_STUFF_SOUND = 1132,
EMOTE_ONESHOT_OFFER_LOOP = 1141,
EMOTE_ONESHOT_EXCLAMATION_NOSHEATHE = 1145,
EMOTE_ONESHOT_QUESTION_NOSHEATHE = 1146,
EMOTE_STATE_MOUNTSPECIAL = 1149,
EMOTE_STATE_WORK_CHOPMEAT_NOSHEATHE_2 = 1151,
EMOTE_STATE_WORK_CHOP = 1152,
};
// AnimationData.db2 (6.0.2.18988)
@@ -4893,7 +4898,7 @@ enum LockKeyType
LOCK_KEY_SPELL = 3,
};
// LockType.db2 (12.0.7.68453)
// LockType.db2 (12.1.5.69952)
enum LockType
{
LOCKTYPE_LOCKPICKING = 1,
@@ -5012,7 +5017,7 @@ enum TrainerType
TRAINER_TYPE_CLASS = 0,
};
// CreatureType.dbc (9.0.2.37176)
// CreatureType.dbc (12.1.5.69952)
enum CreatureType
{
CREATURE_TYPE_BEAST = 1,
@@ -5036,7 +5041,7 @@ uint32 const CREATURE_TYPEMASK_DEMON_OR_UNDEAD = (1 << (CREATURE_TYPE_DEMON-1))
uint32 const CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD = (1 << (CREATURE_TYPE_HUMANOID-1)) | (1 << (CREATURE_TYPE_UNDEAD-1));
uint32 const CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL = (1 << (CREATURE_TYPE_MECHANICAL-1)) | (1 << (CREATURE_TYPE_ELEMENTAL-1));
// CreatureFamily.dbc (12.0.5.67602)
// CreatureFamily.dbc (12.1.5.69952)
enum CreatureFamily
{
CREATURE_FAMILY_NONE = 0,
@@ -5551,7 +5556,7 @@ enum QuestType
QUEST_TYPE_TASK_IN_PROGRESS = 5
};
// QuestInfo.db2 (12.0.7.68367)
// QuestInfo.db2 (12.1.5.69952)
enum QuestInfo
{
QUEST_INFO_GROUP = 1,
@@ -5636,10 +5641,11 @@ enum QuestInfo
QUEST_INFO_IMPORTANT_QUEST_NO_ABANDON = 292,
QUEST_INFO_PREY_WORLD_QUEST = 295,
QUEST_INFO_WORLD_QUEST_SHORT_DURATION = 296,
QUEST_INFO_IMPORTANT_QUEST_RAID = 297
QUEST_INFO_IMPORTANT_QUEST_RAID = 297,
QUEST_INFO_LAIR_WORLD_QUEST = 298,
};
// QuestSort.db2 (12.0.7.68367)
// QuestSort.db2 (12.1.5.69952)
enum QuestSort
{
QUEST_SORT_EPIC = 1,
@@ -5862,7 +5868,7 @@ constexpr uint8 ClassByQuestSort(int32 QuestSort)
return 0;
}
// SkillLine.db2 (12.1.0.69404)
// SkillLine.db2 (12.1.5.69952)
enum SkillType
{
SKILL_NONE = 0,
@@ -6388,7 +6394,7 @@ enum SkillCategory
SKILL_CATEGORY_GENERIC = 12
};
// TotemCategory.db2 (11.2.5.62687)
// TotemCategory.db2 (12.1.5.69952)
enum TotemCategory
{
TC_SKINNING_SKIFE_OLD = 1,
@@ -6924,7 +6930,7 @@ enum PvPTeamId : uint8
uint8 constexpr PVP_TEAMS_COUNT = 2;
// Indexes of BattlemasterList.db2 (9.0.2.37176)
// Indexes of BattlemasterList.db2 (12.1.5.69952)
enum BattlegroundTypeId : uint32
{
BATTLEGROUND_TYPE_NONE = 0, // None
@@ -7029,6 +7035,9 @@ enum BattlegroundTypeId : uint32
BATTLEGROUND_CC3 = 1117, // Cage of Carnage
BATTLEGROUND_SLAYERS_RISE = 1141, // Slayer's Rise (Midnight S1, 40v40) [DB2 BattlemasterList 1141]
BATTLEGROUND_TRAINING_GROUNDS = 1145, // Training Grounds (solo unrated PvP practice)
BATTLEGROUND_TRAINING_GROUND_SILVERSHARD = 1146, // Training Grounds (solo unrated PvP practice, Silvershard Mines map)
BATTLEGROUND_TRAINING_GROUND_ARATHI_BASSIN = 1147, // Training Grounds (solo unrated PvP practice, Arathi Basin map)
BATTLEGROUND_TRAINING_GROUND_NAGRAND_ARENA = 1165, // Training Grounds (solo unrated PvP practice, Nagrand Arena map)
};
#define MAX_BATTLEGROUND_TYPE_ID 845
+7 -3
View File
@@ -154,10 +154,14 @@ void WorldQuestMgr::Update(uint32 diff)
void WorldQuestMgr::FillActiveWorldQuests(std::vector<WorldPackets::Quest::WorldQuestUpdateInfo>& updates) const
{
updates.reserve(updates.size() + _active.size());
time_t const now = GameTime::GetGameTime();
for (auto const& [questId, active] : _active)
{
// Timer is the full active duration; the client derives remaining time from LastUpdate + Timer.
updates.emplace_back(active.StartTime, active.QuestID,
uint32(active.EndTime - active.StartTime), active.VariableID, active.Value);
// Retail contract: the client derives remaining time from LastUpdate + Timer, so Timer must be
// the REMAINING time (EndTime - now), not the full active duration. Sending EndTime - StartTime
// pins the client countdown at full forever; the quest never visibly ticks toward expiry and
// this file's own comment on SMSG_WORLD_QUEST_UPDATE_RESPONSE explicitly says the opposite.
uint32 remaining = active.EndTime > now ? uint32(active.EndTime - now) : 0;
updates.emplace_back(active.StartTime, active.QuestID, remaining, active.VariableID, active.Value);
}
}
+3 -1
View File
@@ -2611,7 +2611,9 @@ InstanceMapScript::InstanceMapScript(char const* name, uint32 mapId) noexcept
if (!GetEntry())
TC_LOG_ERROR("scripts", "Invalid InstanceMapScript for {}; no such map ID.", mapId);
if (GetEntry() && !GetEntry()->IsDungeon())
// A map with an instance_template is intentionally scripted even when Map.db2
// does not flag it as a dungeon (the Arathi catch-up map is one of these).
if (GetEntry() && !GetEntry()->IsDungeon() && !sObjectMgr->GetInstanceTemplate(mapId))
TC_LOG_ERROR("scripts", "InstanceMapScript for map {} is invalid.", mapId);
ScriptRegistry<InstanceMapScript>::Instance()->AddScript(this);
@@ -53,12 +53,12 @@ public:
{
player->CastSpell(player, SPELL_CADAVER_KILL_CREDIT);
if (player->GetQuestObjectiveProgress(QUEST_H_THE_REDEATHER, 2) == 8)
if (player->GetQuestObjectiveData(QUEST_H_THE_REDEATHER, 397279) == 8)
{
player->CastSpell(player, SPELL_CADAVER_CREDIT_CHECK_CHOPPY_MALFUNCTION, true);
}
if (player->GetQuestObjectiveProgress(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, 2) == 8)
if (player->GetQuestObjectiveData(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, 396499) == 8)
{
player->CastSpell(player, SPELL_GIANT_BOAR_PING_VEHICLE, true);
}
@@ -366,15 +366,30 @@ struct npc_exiles_reach_darkmaul_plains_156267 : public VehicleAI
void IsSummonedBy(WorldObject* summoner) override
{
// The summoned boar had no creature spell, so the Trample button was not on the bar.
if (!me->m_spells[0])
me->m_spells[0] = SPELL_GIANT_BOAR_TRAMPLE;
if (Player* player = summoner->ToPlayer())
{
if (me->GetAreaId() == AREA_DARKMAUL_PLAINS && me->GetVehicleKit())
if (me->GetVehicleKit())
{
if (Creature* garrick = player->GetSummonedCreatureByEntry(NPC_OGRE_RUINS_TORGOK_FIGHTER_A))
garrick->EnterVehicle(me, 1);
}
}
}
void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
{
if (!apply || !passenger->IsPlayer())
return;
if (!me->m_spells[0])
me->m_spells[0] = SPELL_GIANT_BOAR_TRAMPLE;
passenger->ToPlayer()->VehicleSpellInitialize();
}
};
// Cork Fizzlepop, Lindie Springstock (Darkmaul Plains) (Re-Sizing the Situation)
@@ -1061,16 +1076,19 @@ namespace
if (creature->GetEntry() == NPC_OGRE_RUINS_MONSTROUS_CADAVER)
{
uint32 const before = player->GetQuestObjectiveProgress(questId, 2);
// Objective 396499 / 397279 counts creature 165150, not the cadaver the player hits.
uint32 const objectiveId = ExileUsesHorde(player) ? 397279u : 396499u;
int32 const before = player->GetQuestObjectiveData(questId, objectiveId);
Unit::Kill(player, creature);
if (before < 8 && player->GetQuestObjectiveProgress(questId, 2) == before)
player->CastSpell(player, SPELL_CADAVER_KILL_CREDIT, true);
if (before < 8 && player->GetQuestObjectiveData(questId, objectiveId) == before)
player->KilledMonsterCredit(NPC_OGRE_RUINS_CADAVER_KILL_CREDIT);
}
else
Unit::Kill(player, creature);
}
if (player->GetQuestObjectiveProgress(questId, 2) >= 8)
uint32 const objectiveId = ExileUsesHorde(player) ? 397279u : 396499u;
if (player->GetQuestObjectiveData(questId, objectiveId) >= 8)
player->CastSpell(player, SPELL_GIANT_BOAR_PING_VEHICLE, true);
}
}
@@ -32,10 +32,13 @@ void ArriveExileBeach(Player* player)
return;
uint32 const area = player->GetAreaId();
if (area != AREA_NORTH_SEA_A && area != AREA_NORTH_SEA_H && area != AREA_MURLOC_HIDEAWAY)
// Brace for Impact ends on the deck. The crash movie has to move the
// player onto the beach even when the ship is not inside the North Sea subzone.
bool const aboardExileShip = player->GetTransport() != nullptr;
if (!aboardExileShip && area != AREA_NORTH_SEA_A && area != AREA_NORTH_SEA_H && area != AREA_MURLOC_HIDEAWAY)
return;
if (area == AREA_NORTH_SEA_A || area == AREA_NORTH_SEA_H)
if (aboardExileShip || area == AREA_NORTH_SEA_A || area == AREA_NORTH_SEA_H)
{
player->TeleportTo(MAP_EXILES_REACH, -462.722f, -2620.544f, 0.472f, 0.760f);
player->CastSpell(player, player->IsInHorde() ? SPELL_H_SHIP_CRASH : SPELL_A_SHIP_CRASH, true);
@@ -35,7 +35,12 @@ public:
if (player->GetMapId() == MAP_EXILES_REACH)
{
uint32 const area = player->GetAreaId();
if (area != AREA_NORTH_SEA_A && area != AREA_NORTH_SEA_H)
// New characters stand on the faction ship (transport), whose world
// area is often the parent zone or the other faction's North Sea.
// Gating the deck on the subzone hid Private Cole / Grunt Throg,
// so Stand Your Ground had nobody to accept or turn in.
bool const aboardExileShip = player->GetTransport() != nullptr;
if (!aboardExileShip && area != AREA_NORTH_SEA_A && area != AREA_NORTH_SEA_H)
{
// The deck phases are only updated while the player is still on the ship.
// Leaving them on shows Jaina (and the Horde officers) a second time on the beach.
@@ -62,7 +67,11 @@ public:
return;
}
switch (area)
uint32 const phaseArea = aboardExileShip
? (ExileUsesHorde(player) ? AREA_NORTH_SEA_H : AREA_NORTH_SEA_A)
: area;
switch (phaseArea)
{
case AREA_NORTH_SEA_H:
{
@@ -0,0 +1,450 @@
/*
* 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/>.
*/
/*
* Timers requires to be revisited
* What does SPELL_NOTIFY_OF_DEATH is unknown
* What does Script Effect of spell SPELL_HUNTERS_MARK is unknown
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellInfo.h"
#include "MotionMaster.h"
#include "Player.h"
#include "the_underbog.h"
enum MuselekTexts
{
SAY_COMMAND = 0,
SAY_AGGRO = 1,
SAY_SLAY = 2,
SAY_DEATH = 3
};
enum MuselekSpells
{
// Musel'ek - Combat - Ranged
SPELL_SHOOT = 22907,
SPELL_MULTI_SHOT = 34974,
// Musel'ek - Combat - Melee
SPELL_KNOCK_AWAY = 18813,
SPELL_BEAR_COMMAND = 34662,
SPELL_RAPTOR_STRIKE = 31566,
SPELL_DETERRENCE = 31567,
// Musel'ek - Combat - Sequence
SPELL_HUNTERS_MARK = 31615,
SPELL_FREEZING_TRAP = 31946,
SPELL_PACIFY_SELF = 19951,
SPELL_MOVE_AWAY_PRIMER = 31564,
SPELL_FACE_HIGHEST_THREAT = 32425,
SPELL_AIMED_SHOT = 31623,
// Musel'ek - Combat - Death
SPELL_NOTIFY_OF_DEATH = 31547,
// Claw
SPELL_ECHOING_ROAR = 31429,
SPELL_MAUL = 34298,
SPELL_FRENZY = 34971,
SPELL_FERAL_CHARGE = 39435
};
enum MuselekEvents
{
// Ranged
EVENT_SHOOT = 1,
EVENT_MULTI_SHOT,
// Melee
EVENT_KNOCK_AWAY,
EVENT_BEAR_COMMAND,
EVENT_RAPTOR_STRIKE,
// Sequence
EVENT_COMBAT_SEQUENCE_1,
EVENT_COMBAT_SEQUENCE_2,
EVENT_COMBAT_SEQUENCE_3,
// Claw
EVENT_ECHOING_ROAR,
EVENT_MAUL,
EVENT_COMMAND_RESPONSE,
EVENT_FERAL_CHARGE,
EVENT_OUTRO_1,
EVENT_OUTRO_2,
EVENT_OUTRO_3
};
enum MuselekMisc
{
FACTION_CENARION_EXP = 1660,
NPC_CLAW = 17827,
NPC_WINDCALLER_CLAW = 17894,
POINT_OUTRO_1 = 1,
POINT_OUTRO_2 = 2,
POINT_MOVE_AWAY = 1
};
enum MuselekPhases : uint8
{
PHASE_NONE = 0,
PHASE_HEALTH_70,
PHASE_HEALTH_30
};
Position const OutroPos[2] =
{
{ 290.53226f, -125.35236f, 29.697079f, 0.0f },
{ 295.05692f, -123.32802f, 29.659490f, 0.0f }
};
// 17826 - Swamplord Musel'ek
struct boss_swamplord_muselek : public BossAI
{
boss_swamplord_muselek(Creature* creature) : BossAI(creature, DATA_SWAMPLORD_MUSELEK), _phase(PHASE_NONE) { }
void Reset() override
{
_Reset();
_phase = PHASE_NONE;
me->SetReactState(REACT_AGGRESSIVE);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SHOOT, 0s);
events.ScheduleEvent(EVENT_MULTI_SHOT, 20s, 30s);
events.ScheduleEvent(EVENT_KNOCK_AWAY, 35s, 40s);
events.ScheduleEvent(EVENT_BEAR_COMMAND, 10s);
events.ScheduleEvent(EVENT_RAPTOR_STRIKE, 10s, 20s);
}
void AttackStart(Unit* who) override
{
ScriptedAI::AttackStartCaster(who, 30.0f);
}
void DamageTaken(Unit* /*killer*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
if (_phase < PHASE_HEALTH_70 && me->HealthBelowPctDamaged(70, damage))
{
_phase++;
events.ScheduleEvent(EVENT_COMBAT_SEQUENCE_1, 0s);
}
if (_phase < PHASE_HEALTH_30 && me->HealthBelowPctDamaged(30, damage))
{
_phase++;
events.ScheduleEvent(EVENT_COMBAT_SEQUENCE_1, 0s);
}
}
void OnSpellCast(SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_BEAR_COMMAND)
Talk(SAY_COMMAND);
}
void MovementInform(uint32 type, uint32 pointId) override
{
if (type != POINT_MOTION_TYPE)
return;
if (pointId == POINT_MOVE_AWAY)
events.ScheduleEvent(EVENT_COMBAT_SEQUENCE_3, 1s);
}
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_FACE_HIGHEST_THREAT)
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat))
me->SetFacingToObject(target);
}
void KilledUnit(Unit* /*victim*/) override
{
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
if (Creature* claw = me->FindNearestCreature(NPC_CLAW, 100.0f))
DoCast(claw, SPELL_NOTIFY_OF_DEATH);
}
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)
{
// Ranged
case EVENT_SHOOT:
DoCastVictim(SPELL_SHOOT);
events.Repeat(2s, 4s);
break;
case EVENT_MULTI_SHOT:
DoCastVictim(SPELL_MULTI_SHOT);
events.Repeat(25s, 35s);
break;
// Melee
case EVENT_KNOCK_AWAY:
DoCastVictim(SPELL_KNOCK_AWAY);
events.Repeat(30s, 40s);
break;
case EVENT_BEAR_COMMAND:
DoCastSelf(SPELL_BEAR_COMMAND);
events.Repeat(25s);
break;
case EVENT_RAPTOR_STRIKE:
DoCastVictim(SPELL_RAPTOR_STRIKE);
events.Repeat(10s, 20s);
break;
// Sequence
case EVENT_COMBAT_SEQUENCE_1:
DoCastSelf(SPELL_HUNTERS_MARK);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
DoCast(target, SPELL_FREEZING_TRAP);
me->SetReactState(REACT_PASSIVE);
events.ScheduleEvent(EVENT_COMBAT_SEQUENCE_2, 2s);
break;
case EVENT_COMBAT_SEQUENCE_2:
DoCastSelf(SPELL_PACIFY_SELF);
DoCastSelf(SPELL_MOVE_AWAY_PRIMER);
// Not always? Or wrong place? This is based only on one cast in sniff, need more info
if (roll_chance(50))
DoCastSelf(SPELL_DETERRENCE);
break;
case EVENT_COMBAT_SEQUENCE_3:
DoCastSelf(SPELL_FACE_HIGHEST_THREAT);
me->RemoveAurasDueToSpell(SPELL_PACIFY_SELF);
me->SetReactState(REACT_AGGRESSIVE);
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat))
DoCast(target, SPELL_AIMED_SHOT);
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
}
private:
uint8 _phase;
};
// 17827 - Claw
struct npc_claw : public ScriptedAI
{
npc_claw(Creature* creature) : ScriptedAI(creature), _canPerformOutro(false), _chargeCounter(0), _currentChargeCount(0) { }
void Reset() override
{
_events.Reset();
_chargeCounter = 0;
_currentChargeCount = 0;
}
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(EVENT_ECHOING_ROAR, 20s, 25s);
_events.ScheduleEvent(EVENT_MAUL, 5s, 10s);
}
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_BEAR_COMMAND)
_events.ScheduleEvent(EVENT_COMMAND_RESPONSE, 0s);
}
bool OnGossipHello(Player* player) override
{
player->KilledMonsterCredit(NPC_WINDCALLER_CLAW);
return false;
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
// This CAN occur even if Musel'ek is NOT yet dead
if (!_canPerformOutro && me->HealthBelowPctDamaged(20, damage))
{
_canPerformOutro = true;
me->SetFaction(FACTION_CENARION_EXP);
me->SetImmuneToAll(true);
EnterEvadeMode();
}
}
void JustReachedHome() override
{
if (_canPerformOutro)
_events.ScheduleEvent(EVENT_OUTRO_1, 0s);
ScriptedAI::JustReachedHome();
}
void MovementInform(uint32 type, uint32 pointId) override
{
if (type != POINT_MOTION_TYPE)
return;
switch (pointId)
{
case POINT_OUTRO_1:
_events.ScheduleEvent(EVENT_OUTRO_2, 0s);
break;
case POINT_OUTRO_2:
_events.ScheduleEvent(EVENT_OUTRO_3, 1s);
break;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
if (_canPerformOutro)
{
_events.Update(diff);
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_OUTRO_1:
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_OUTRO_1, OutroPos[0]);
me->UpdateEntry(NPC_WINDCALLER_CLAW);
/// !HACK: UpdateEntry here should be done without changing faction. Changing faction back
me->SetFaction(FACTION_CENARION_EXP);
/// !HACK: Removed after entry is updated. Changing back
me->SetImmuneToAll(true);
break;
case EVENT_OUTRO_2:
me->GetMotionMaster()->MovePoint(POINT_OUTRO_2, OutroPos[1]);
break;
case EVENT_OUTRO_3:
me->SetFacingTo(3.420845270156860351f);
me->SetStandState(UNIT_STAND_STATE_SIT);
break;
default:
break;
}
}
}
return;
}
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ECHOING_ROAR:
DoCastSelf(SPELL_ECHOING_ROAR);
_events.Repeat(10s, 20s);
break;
case EVENT_MAUL:
DoCastVictim(SPELL_MAUL);
_events.Repeat(10s, 15s);
break;
case EVENT_COMMAND_RESPONSE:
DoCastSelf(SPELL_FRENZY);
// 0 seems to be valid value. He doesn't obey always, perhaps. Or something is more tricky than it seems
_chargeCounter = RAND(0, 1, 2, 3, 4);
_currentChargeCount = 0;
_events.ScheduleEvent(EVENT_FERAL_CHARGE, 2s, 5s);
break;
case EVENT_FERAL_CHARGE:
if (_currentChargeCount < _chargeCounter)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
DoCast(target, SPELL_FERAL_CHARGE);
++_currentChargeCount;
_events.Repeat(2s, 5s);
}
break;
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
}
private:
EventMap _events;
bool _canPerformOutro;
uint8 _chargeCounter;
uint8 _currentChargeCount;
};
// 31564 - Move Away Primer
class spell_swamplord_muselek_move_away_primer : public SpellScript
{
void HandleDummy(SpellEffIndex /*effIndex*/)
{
GetCaster()->GetMotionMaster()->MovePoint(POINT_MOVE_AWAY, GetCaster()->GetNearPosition(frand(15.0f, 35.0f), frand(0.0f, 2.0f * float(M_PI))));
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_swamplord_muselek_move_away_primer::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
void AddSC_boss_swamplord_muselek()
{
RegisterTheUnderbogCreatureAI(boss_swamplord_muselek);
RegisterTheUnderbogCreatureAI(npc_claw);
RegisterSpellScript(spell_swamplord_muselek_move_away_primer);
}
@@ -81,6 +81,7 @@ void AddSC_boss_ahune();
void AddSC_instance_the_underbog();
void AddSC_boss_hungarfen();
void AddSC_boss_the_black_stalker();
void AddSC_boss_swamplord_muselek();
// Gruul's Lair
void AddSC_boss_gruul();
@@ -206,6 +207,7 @@ void AddOutlandScripts()
AddSC_instance_the_underbog();
AddSC_boss_hungarfen();
AddSC_boss_the_black_stalker();
AddSC_boss_swamplord_muselek();
// Gruul's Lair
AddSC_boss_gruul();
@@ -0,0 +1,130 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "Player.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "SpellAuraEffects.h"
#include "necrotic_wake.h"
enum Spells
{
SPELL_LAND_OF_THE_DEAD_CAST = 321226,
SPELL_LAND_OF_THE_DEAD_MISSILE = 319874,
SPELL_LAND_OF_THE_DEAD_MISSILE_SECOND = 319902,
SPELL_LAND_OF_THE_DEAD_MISSILE_THIRD = 333627,
SPELL_FINAL_HARVEST = 321247,
SPELL_FINAL_HARVEST_DAMAGE = 321253,
SPELL_NECROTIC_BOLT = 320170,
SPELL_UNHOLY_FRENZY = 320012,
SPELL_NECROTIC_BREATH_TRIGGER = 337074,
EVENT_LAND_OF_THE_DEAD = 1,
EVENT_NECROTIC_BREATH
};
//163157
struct boss_amarth : public BossAI
{
boss_amarth(Creature* creature) : BossAI(creature, DATA_AMARTH)
{
Vehicle* vehicle = me->GetVehicleKit();
}
void Reset() override
{
BossAI::Reset();
}
void JustEngagedWith(Unit* who) override
{
_JustEngagedWith(who);
Talk(0);
events.ScheduleEvent(SPELL_NECROTIC_BOLT, 3s);
events.ScheduleEvent(EVENT_LAND_OF_THE_DEAD, 5s);
events.ScheduleEvent(SPELL_FINAL_HARVEST, 8s);
events.ScheduleEvent(EVENT_NECROTIC_BREATH, 10s);
if (Creature* amarth = me->FindNearestCreature(NPC_AMARTH, 30.0f, true))
amarth->EnterVehicle(me);
}
void OnSuccessfulSpellCast(SpellInfo const* spellInfo)
{
switch (spellInfo->Id)
{
case SPELL_FINAL_HARVEST:
DoCastAOE(SPELL_FINAL_HARVEST_DAMAGE, true);
break;
}
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case SPELL_NECROTIC_BOLT:
DoCastVictim(SPELL_NECROTIC_BOLT, false);
events.Repeat(15s);
break;
case EVENT_LAND_OF_THE_DEAD:
me->CastSpell(nullptr, SPELL_LAND_OF_THE_DEAD_CAST, false);
me->CastSpell(me->GetRandomNearPosition(20.0f), SPELL_LAND_OF_THE_DEAD_MISSILE, true);
me->CastSpell(me->GetRandomNearPosition(20.0f), SPELL_LAND_OF_THE_DEAD_MISSILE_SECOND, true);
me->CastSpell(me->GetRandomNearPosition(20.0f), SPELL_LAND_OF_THE_DEAD_MISSILE_THIRD, true);
events.Repeat(20s);
break;
case SPELL_FINAL_HARVEST:
me->CastSpell(nullptr, SPELL_FINAL_HARVEST, false);
events.Repeat(25s);
break;
case EVENT_NECROTIC_BREATH:
SetCombatMovement(false);
me->AddAura(SPELL_NECROTIC_BREATH_TRIGGER, me);
events.Repeat(30s);
break;
}
}
void JustReachedHome() override
{
_JustReachedHome();
me->RemoveAllAreaTriggers();
}
void JustDied(Unit* /*who*/) override
{
_JustDied();
Talk(1);
me->RemoveAllAreaTriggers();
}
};
//162692
struct npc_amarth : public ScriptedAI
{
npc_amarth(Creature* c) : ScriptedAI(c) { }
void Reset() override
{
ScriptedAI::Reset();
me->SetReactState(REACT_PASSIVE);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
}
};
void AddSC_boss_amarth()
{
RegisterCreatureAI(boss_amarth);
RegisterCreatureAI(npc_amarth);
}
@@ -0,0 +1,224 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "Player.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "Spell.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "Map.h"
#include "necrotic_wake.h"
enum Spells
{
SPELL_CRUNCH = 320655,
SPELL_HEAVING_RETCH = 320596,
SPELL_HEAVING_RETCH_MISSILE = 320699,
SPELL_FETID_GAS_CREATE_AT = 320637,
SPELL_FETID_GAS_AURA = 320646,
//Carrion Worm
SPELL_BLOOD_GORGE = 320614,
SPELL_BLOOD_GORGE_BUFF = 320630,
SPELL_CARRION_ERUPTION = 320631,
};
enum blightboneTalks : uint8
{
TALK_AGGRO = 0,
TALK_DEATH = 1,
};
enum Events
{
EVENT_SPELL_CAST_START = 1,
EVENT_SPELL_PERIODIC_DAMAGE,
EVENT_SPELL_PERIODIC_MISSED,
EVENT_UNIT_SPELLCAST_START
};
//162691
struct boss_blightbone : public BossAI
{
boss_blightbone(Creature* creature) : BossAI(creature, DATA_BLIGHTBONE)
{
}
void InitializeAI() override
{
scheduler.ClearValidator();
BossAI::InitializeAI();
}
void Reset() override
{
events.Reset();
scheduler.CancelAll();
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
BossAI::Reset();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(TALK_AGGRO);
DoCastVictim(SPELL_HEAVING_RETCH);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
if (auto* encounterDoor = me->FindNearestGameObject(GO_BLIGHTBONE_EXIT, 100.0f))
encounterDoor->SetGoState(GO_STATE_READY);
events.ScheduleEvent(EVENT_SPELL_CAST_START, 3s);
events.ScheduleEvent(EVENT_SPELL_PERIODIC_DAMAGE, 5s);
events.ScheduleEvent(EVENT_SPELL_PERIODIC_MISSED, 10s);
events.ScheduleEvent(EVENT_UNIT_SPELLCAST_START, 15s);
}
void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
{
switch (spellInfo->Id)
{
case SPELL_HEAVING_RETCH:
if (target->IsUnit())
me->AddAura(SPELL_HEAVING_RETCH, target->ToUnit());
break;
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SPELL_CAST_START:
DoCastVictim(SPELL_CRUNCH, true);
SpellCastVisual();
DoCastRandom(SPELL_HEAVING_RETCH, true);
DoCastAOE(SPELL_HEAVING_RETCH);
events.Repeat(10s);
break;
case EVENT_SPELL_PERIODIC_DAMAGE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_HEAVING_RETCH);
}
events.Repeat(20s);
break;
case EVENT_SPELL_PERIODIC_MISSED:
me->CastSpell(nullptr, SPELL_FETID_GAS_CREATE_AT, false);
events.Repeat(18s);
break;
}
}
}
void JustReachedHome() override
{
_JustReachedHome();
me->RemoveAllAreaTriggers();
}
void JustDied(Unit* /*who*/) override
{
_JustDied();
Talk(TALK_DEATH);
me->RemoveAllAreaTriggers();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
if (auto* encounterDoor = me->FindNearestGameObject(GO_BLIGHTBONE_EXIT, 100.0f))
encounterDoor->SetGoState(GO_STATE_ACTIVE);
}
};
//23443
struct at_fetid_gas : public AreaTriggerAI
{
at_fetid_gas(AreaTrigger* at) : AreaTriggerAI(at) { }
void OnUnitEnter(Unit* target) override
{
if (!target->IsPlayer())
return;
if (!target->HasAura(SPELL_FETID_GAS_AURA))
at->GetCaster()->AddAura(SPELL_FETID_GAS_AURA, target);
}
void OnUnitExit(Unit* target, AreaTriggerExitReason /*reason*/) override
{
if (target->HasAura(SPELL_FETID_GAS_AURA))
target->RemoveAura(SPELL_FETID_GAS_AURA);
}
};
//164702
struct npc_carrion_worm_nw : public ScriptedAI
{
npc_carrion_worm_nw(Creature* c) : ScriptedAI(c) { }
void Reset() override
{
ScriptedAI::Reset();
}
void JustEngagedWith(Unit* /*who*/) override
{
_events.ScheduleEvent(SPELL_BLOOD_GORGE, 3s);
}
void ExecuteEvent(uint32 eventId) override
{
if (Aura const* gorge = me->GetAura(SPELL_BLOOD_GORGE_BUFF))
if (gorge->GetStackAmount() == 3)
{
me->RemoveAurasDueToSpell(SPELL_BLOOD_GORGE_BUFF);
me->CastSpell(nullptr, SPELL_CARRION_ERUPTION, false);
}
switch (eventId)
{
case SPELL_BLOOD_GORGE:
DoCastVictim(SPELL_BLOOD_GORGE, false);
me->AddAura(SPELL_BLOOD_GORGE_BUFF, me);
_events.Repeat(10s);
break;
}
}
void JustDied(Unit* /*who*/) override
{
if (IsMythic())
me->CastSpell(nullptr, SPELL_FETID_GAS_CREATE_AT, true);
}
private:
EventMap _events;
};
void AddSC_boss_blightbone()
{
RegisterCreatureAI(boss_blightbone);
RegisterAreaTriggerAI(at_fetid_gas);
RegisterCreatureAI(npc_carrion_worm_nw);
}
@@ -0,0 +1,117 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "Player.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "SpellAuraEffects.h"
#include "necrotic_wake.h"
enum Spells
{
SPELL_FINAL_HARVEST = 321247,
SPELL_LAND_OF_THE_DEAD = 321226,
SPELL_NECROTIC_BOLT = 320170,
SPELL_UNHOLY_FRENZY = 320012,
SPELL_FINAL_HARVEST_DAMAGE = 321253,
SPELL_LAND_OF_THE_DEAD_CAST = 321226,
SPELL_LAND_OF_THE_DEAD_MISSILE = 319874,
SPELL_LAND_OF_THE_DEAD_MISSILE_SECOND = 319902,
SPELL_LAND_OF_THE_DEAD_MISSILE_THIRD = 333627,
SPELL_NECROTIC_BREATH_TRIGGER = 337074,
EVENT_LAND_OF_THE_DEAD = 1,
EVENT_NECROTIC_BREATH
};
//166945
struct boss_nalthor : public BossAI
{
boss_nalthor(Creature* creature) : BossAI(creature, DATA_AMARTH)
{
Vehicle* vehicle = me->GetVehicleKit();
}
void Reset() override
{
BossAI::Reset();
}
void JustEngagedWith(Unit* who) override
{
_JustEngagedWith(who);
Talk(0);
events.ScheduleEvent(SPELL_NECROTIC_BOLT, 3s);
events.ScheduleEvent(EVENT_LAND_OF_THE_DEAD, 5s);
events.ScheduleEvent(SPELL_FINAL_HARVEST, 8s);
events.ScheduleEvent(EVENT_NECROTIC_BREATH, 10s);
}
void OnSpellFinished(SpellInfo const* spellInfo)
{
switch (spellInfo->Id)
{
case SPELL_FINAL_HARVEST:
DoCastAOE(SPELL_FINAL_HARVEST_DAMAGE, true);
break;
}
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case SPELL_NECROTIC_BOLT:
DoCastVictim(SPELL_NECROTIC_BOLT, false);
events.Repeat(15s);
break;
case EVENT_LAND_OF_THE_DEAD:
me->CastSpell(nullptr, SPELL_LAND_OF_THE_DEAD_CAST, false);
me->CastSpell(me->GetRandomNearPosition(20.0f), SPELL_LAND_OF_THE_DEAD_MISSILE, true);
me->CastSpell(me->GetRandomNearPosition(20.0f), SPELL_LAND_OF_THE_DEAD_MISSILE_SECOND, true);
me->CastSpell(me->GetRandomNearPosition(20.0f), SPELL_LAND_OF_THE_DEAD_MISSILE_THIRD, true);
events.Repeat(20s);
break;
case SPELL_FINAL_HARVEST:
me->CastSpell(nullptr, SPELL_FINAL_HARVEST, false);
events.Repeat(25s);
break;
case EVENT_NECROTIC_BREATH:
SetCombatMovement(false);
me->AddAura(SPELL_NECROTIC_BREATH_TRIGGER, me);
events.Repeat(30s);
break;
}
}
void JustReachedHome() override
{
_JustReachedHome();
me->RemoveAllAreaTriggers();
}
void JustDied(Unit* /*who*/) override
{
_JustDied();
Talk(1);
me->RemoveAllAreaTriggers();
}
};
void AddSC_boss_nalthor()
{
RegisterCreatureAI(boss_nalthor);
}
@@ -0,0 +1,171 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "Player.h"
#include "Creature.h"
#include "CreatureAI.h"
#include "GameObject.h"
#include "GameObjectAI.h"
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "SpellAuraEffects.h"
#include "Map.h"
#include "necrotic_wake.h"
enum SurgeonSpells
{
//Surgeon Stitchflesh
SPELL_NOXIOUS_FOG = 327100,
SPELL_EMBALMING_ICHOR = 327664,
SPELL_STITCHNEEDLE = 320200,
SPELL_SEVER_FLESH = 334488,
SPELL_MORBID_FIXATION = 343555,
SPELL_ESCAPE = 320359,
//Stitchflesh's Creation
SPELL_MEAT_HOOK = 320208,
SPELL_MEAT_HOOK_2 = 322548,
SPELL_MEAT_HOOK_3 = 322681,
SPELL_AWAKEN_CREATION = 320358,
SPELL_FESTERING_ROT = 348170,
SPELL_LETHARGY = 326868,
SPELL_MEERAHS_JUKEBOX = 288865,
SPELL_MUTILATE = 320376,
SPELL_SHATTERED_PSYCHE = 344663,
SPELL_SPELL_SEVER_FLESH = 334488,
};
enum SurgeonCreatures
{
NPC_STITCHFLESHS_CREATION = 164578,
NPC_STITCHING_ASSISTANT = 173044,
NPC_SEPARATION_ASSISTANT = 167731,
NPC_GOREGRIND_BITS = 163622,
NPC_GOREGRIND = 163621,
NPC_ROTSPEW = 163620,
NPC_ROTSPEW_LEFTOVERS = 163623,
};
//166882
struct boss_surgeon_stitchflesh : public BossAI
{
boss_surgeon_stitchflesh(Creature* creature) : BossAI(creature, DATA_SURGEON_STITCHFLESH) { }
void Reset() override
{
BossAI::Reset();
}
void JustEngagedWith(Unit* who) override
{
_JustEngagedWith(who);
Talk(0);
events.ScheduleEvent(SPELL_NOXIOUS_FOG, 3s);
events.ScheduleEvent(SPELL_EMBALMING_ICHOR, 5s);
events.ScheduleEvent(SPELL_STITCHNEEDLE, 10s);
events.ScheduleEvent(SPELL_SPELL_SEVER_FLESH, 3s);
events.ScheduleEvent(SPELL_MORBID_FIXATION, 3s);
events.ScheduleEvent(SPELL_ESCAPE, 3s);
}
void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
{
Unit* ptarget = me->GetVictim();
switch (spellInfo->Id)
{
case SPELL_NOXIOUS_FOG:
me->AddAura(SPELL_NOXIOUS_FOG, ptarget);
break;
case SPELL_EMBALMING_ICHOR:
me->AddAura(SPELL_EMBALMING_ICHOR, ptarget);
break;
case SPELL_STITCHNEEDLE:
me->AddAura(SPELL_STITCHNEEDLE, ptarget);
break;
case SPELL_SPELL_SEVER_FLESH:
me->AddAura(SPELL_SPELL_SEVER_FLESH, ptarget);
break;
case SPELL_MORBID_FIXATION:
me->AddAura(SPELL_MORBID_FIXATION, ptarget);
break;
case SPELL_ESCAPE:
me->AddAura(SPELL_ESCAPE, ptarget);
break;
}
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case SPELL_NOXIOUS_FOG:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_NOXIOUS_FOG), false;
}
events.Repeat(20s);
break;
case SPELL_EMBALMING_ICHOR:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_EMBALMING_ICHOR), false;
}
events.Repeat(20s);
break;
case SPELL_STITCHNEEDLE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_STITCHNEEDLE), false;
}
events.Repeat(20s);
break;
case SPELL_SEVER_FLESH:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_SEVER_FLESH), false;
}
events.Repeat(20s);
break;
case SPELL_MORBID_FIXATION:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_MORBID_FIXATION), false;
}
events.Repeat(20s);
break;
case SPELL_ESCAPE:
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0, 100.0f, true))
{
me->CastSpell(target, SPELL_ESCAPE), false;
}
events.Repeat(20s);
break;
}
}
void JustReachedHome() override
{
_JustReachedHome();
me->RemoveAllAreaTriggers();
}
void JustDied(Unit* /*who*/) override
{
_JustDied();
Talk(1);
me->RemoveAllAreaTriggers();
// if (auto* encounterDoor = me->FindNearestGameObject(GO_SURGEON_STITCHFLESH_EXIT, 100.0f))
// encounterDoor->SetGoState(GO_STATE_ACTIVE);
};
};
//166882
void AddSC_boss_surgeon_stitchflesh()
{
RegisterCreatureAI(boss_surgeon_stitchflesh);
}
@@ -0,0 +1,46 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "necrotic_wake.h"
#include "Conversation.h"
#include "Creature.h"
#include "ScriptMgr.h"
#include "Player.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "Map.h"
#include "Transport.h"
#include "TransportMgr.h"
class instance_necrotic_wake : public InstanceMapScript
{
public:
instance_necrotic_wake() : InstanceMapScript("instance_necrotic_wake", 2286) { }
struct instance_necrotic_wake_InstanceMapScript : public InstanceScript
{
instance_necrotic_wake_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
if (Transport* transport = sTransportMgr->CreateTransport(GO_NECROPOLIS_TRANSPORT, instance))
{
transport->SetDynamicFlag(GO_DYNFLAG_LO_STOPPED);
transport->SetFlag(GameObjectFlags(GO_FLAG_MAP_OBJECT | GO_FLAG_NODESPAWN | GO_FLAG_TRANSPORT));
}
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_necrotic_wake_InstanceMapScript(map);
}
};
void AddSC_instance_necrotic_wake()
{
new instance_necrotic_wake();
}
@@ -0,0 +1,61 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "AreaTrigger.h"
#include "AreaTriggerAI.h"
#include "necrotic_wake.h"
enum Spells
{
SPELL_ANIMA_MISSILE = 335159,
SPELL_ANIMA_CREATE_AT = 335160,
SPELL_ANIMA_BUFF = 335161,
SPELL_COLLAPSED_GOLIATH = 335155,
};
//171750
struct npc_malfunctioning_goliath : public ScriptedAI
{
npc_malfunctioning_goliath(Creature* c) : ScriptedAI(c) { }
void Reset() override
{
ScriptedAI::Reset();
me->SetNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
}
void OnSpellClick(Unit* clicker, bool result) override
{
me->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
me->RemoveAura(SPELL_COLLAPSED_GOLIATH);
for (uint16 i = 0; i < 16; i++)
{
me->CastSpell(me->GetRandomNearPosition(15.0f), SPELL_ANIMA_MISSILE, true);
}
}
};
//25432
struct at_anima_exhaust : public AreaTriggerAI
{
at_anima_exhaust(AreaTrigger* at) : AreaTriggerAI(at) { }
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
if (!unit->HasAura(SPELL_ANIMA_BUFF))
at->GetCaster()->AddAura(SPELL_ANIMA_BUFF, unit);
}
};
void AddSC_necrotic_wake()
{
RegisterCreatureAI(npc_malfunctioning_goliath);
RegisterAreaTriggerAI(at_anima_exhaust);
}
@@ -0,0 +1,29 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
enum Data
{
DATA_BLIGHTBONE = 1,
DATA_AMARTH,
DATA_SURGEON_STITCHFLESH,
DATA_NALTHOR
};
enum Creatures
{
NPC_BLIGHTBONE = 162691,
NPC_AMARTH = 162692,
NPC_AMARTH_MOUNT = 163157,
NPC_SURGEON_STITCHFLESH = 166882,
NPC_NALTHORN = 166945,
};
enum Gameobjects
{
GO_NECROPOLIS_TRANSPORT = 344772,
GO_BLIGHTBONE_EXIT = 352094,
};
@@ -0,0 +1,689 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms.
*/
#include "AreaTriggerAI.h"
#include "CellImpl.h"
#include "Containers.h"
#include "GameObject.h"
#include "GridNotifiersImpl.h"
#include "InstanceScript.h"
#include "ObjectAccessor.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "ecodome_aldani.h"
enum AzhiccarSpells
{
// Intro
SPELL_DEVOUR_INTRO = 1233112,
SPELL_DEVOUR_INTRO_SELECTOR = 1233116,
SPELL_DEVOUR_INSTAKILL = 1233147,
SPELL_KNOCKBACK = 1222792,
// Combat
SPELL_DEVOUR = 1217232,
SPELL_DEVOUR_AREATRIGGER = 1217240,
SPELL_DEVOUR_SELECTOR = 1217255,
SPELL_DEVOURER_VORTEX = 1227068,
SPELL_DIGESTIVE_SPITTLE = 1217446,
SPELL_ENERGY_CONTROLLER = 1217202,
SPELL_FEAST = 1217241,
SPELL_FEAST_HEAL = 1217247,
SPELL_FEAST_INSTAKILL = 1217252,
SPELL_INVADING_SHRIEK_DAMAGE = 1231850,
SPELL_INVADING_SHRIEK_DUMMY = 1217330,
SPELL_INVADING_SHRIEK_PERIODIC = 1217327,
SPELL_INVADING_SHRIEK_SUMMON = 1217331,
SPELL_PLAYER_DETECTION = 1217757,
SPELL_THRASH = 1217664,
SPELL_TOXIC_REGURGITATION_CAST = 1227745,
SPELL_TOXIC_REGURGITATION_MARKER = 1227748,
SPELL_TOXIC_REGURGITATION_MISSILE = 1217438,
SPELL_TOXIC_REGURGITATION_SELECTOR = 1217436
};
enum AzhiccarEvents
{
EVENT_INVADING_SHRIEK = 1,
EVENT_TOXIC_REGURGITATION,
EVENT_CHECK_ENERGY
};
enum AzhiccarActions
{
ACTION_START_INTRO = 1
};
enum AzhiccarTexts
{
SAY_DEVOUR = 0
};
enum AzhiccarMisc
{
ANIMKIT_NONE = 0,
ANIMKIT_EMERGE = 21290,
SPELL_VISUALKIT_ALARM = 222521,
POINT_AZHICCAR = 0,
SPELL_VISUAL_DEVOURED = 155836,
NPC_PORTAL_STALKER = 237454
};
static constexpr Position AzhiccarPosition = { 436.8889f, -746.0f, 1002.0926f };
static constexpr Position OrphanSpellVisualPosition = { 436.8889f, -746.0f, 1018.0926f };
// 234893 - Azhiccar
struct boss_azhiccar : public BossAI
{
boss_azhiccar(Creature* creature) : BossAI(creature, DATA_AZHICCAR), _invadingShriekCount(1), _toxicRegurgitationCount(1) {}
void JustAppeared() override
{
if (instance->GetData(DATA_AZHICCAR_INTRO) == DONE)
{
me->SetUninteractible(false);
me->SetImmuneToAll(false);
me->SetAIAnimKitId(ANIMKIT_NONE);
me->PlayOneShotAnimKitId(ANIMKIT_EMERGE);
}
me->SetPowerType(POWER_ENERGY);
me->SetPower(POWER_ENERGY, 0);
DoCastSelf(SPELL_DEVOURER_VORTEX);
}
void Reset() override
{
BossAI::Reset();
_invadingShriekCount = 1;
_toxicRegurgitationCount = 1;
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
DoCastSelf(SPELL_PLAYER_DETECTION);
DoCastSelf(SPELL_ENERGY_CONTROLLER);
events.ScheduleEvent(EVENT_TOXIC_REGURGITATION, 15400ms);
events.ScheduleEvent(EVENT_INVADING_SHRIEK, 5200ms);
if (IsHeroicOrHigher())
events.ScheduleEvent(EVENT_CHECK_ENERGY, 500s);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
summons.DespawnAll();
me->RemoveAllAreaTriggers();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
summons.DespawnAll();
me->RemoveAllAreaTriggers();
_EnterEvadeMode();
_DespawnAtEvade();
}
void OnSpellStart(SpellInfo const* spellInfo) override
{
switch (spellInfo->Id)
{
case SPELL_DEVOUR:
{
Talk(SAY_DEVOUR);
break;
}
default:
break;
}
}
void DoAction(int32 actionId) override
{
switch (actionId)
{
case ACTION_START_INTRO:
{
me->SetAIAnimKitId(ANIMKIT_NONE);
me->PlayOneShotAnimKitId(ANIMKIT_EMERGE);
scheduler.Schedule(2s + 170ms, [this](TaskContext context)
{
DoCastSelf(SPELL_KNOCKBACK);
DoCastSelf(SPELL_DEVOUR_INTRO);
context.Schedule(7s, [this](TaskContext)
{
me->SetUninteractible(false);
me->SetImmuneToAll(false);
instance->SetData(DATA_AZHICCAR_INTRO, DONE);
});
});
break;
}
default:
break;
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_INVADING_SHRIEK:
{
std::vector<float> portalAngles =
{
float(M_PI / 4.0f),
-float(M_PI / 4.0f),
-(3.0f * float(M_PI / 4.0f)),
(3.0f * float(M_PI / 4.0f))
};
Trinity::Containers::RandomResize(portalAngles, 3);
for (float angle : portalAngles)
{
angle += me->GetOrientation();
float dist = 30.0f;
Position pos = me->GetPosition();
me->MovePosition(pos, dist, angle);
me->SummonCreature(NPC_PORTAL_STALKER, pos, TEMPSUMMON_TIMED_DESPAWN, 4100ms);
}
DoCastSelf(SPELL_INVADING_SHRIEK_PERIODIC);
_invadingShriekCount++;
if (_invadingShriekCount % 2 == 0)
events.Repeat(37200ms);
else
events.Repeat(48500ms);
break;
}
case EVENT_TOXIC_REGURGITATION:
{
DoCastSelf(SPELL_TOXIC_REGURGITATION_SELECTOR);
_toxicRegurgitationCount++;
if (_toxicRegurgitationCount % 2 == 0)
events.Repeat(18200ms);
else
events.Repeat(67500ms);
break;
}
case EVENT_CHECK_ENERGY:
{
if (me->GetPower(POWER_ENERGY) >= 100)
{
DoCastSelf(SPELL_DEVOUR);
if (IsMythic() || IsMythicPlus())
events.ScheduleEvent(EVENT_INVADING_SHRIEK, 2500ms);
}
else
events.Repeat(500ms);
break;
}
default:
break;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
}
}
private:
uint32 _invadingShriekCount;
uint32 _toxicRegurgitationCount;
};
// 1217202 - Energy Controller
class spell_azhiccar_energy_controller : public AuraScript
{
static constexpr std::array<uint8, 3> AzhiccarEnergizeCycle = { 1, 2, 2 };
void PeriodicTick(AuraEffect const* aurEff) const
{
if (GetTarget()->HasAura(SPELL_DEVOUR))
return;
uint8 cycleIdx = aurEff->GetTickNumber() % AzhiccarEnergizeCycle.size();
GetTarget()->ModifyPower(POWER_ENERGY, AzhiccarEnergizeCycle[cycleIdx]);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_azhiccar_energy_controller::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
// 1217436 - Toxic Regurgitation
class spell_azhiccar_toxic_regurgitation_selector : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TOXIC_REGURGITATION_MARKER, SPELL_TOXIC_REGURGITATION_CAST });
}
void HandleHitTarget(SpellEffIndex /*effIndex*/) const
{
Unit* caster = GetCaster();
CastSpellExtraArgs args;
args.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR;
args.TriggeringSpell = GetSpell();
caster->CastSpell(caster, SPELL_TOXIC_REGURGITATION_CAST, args);
caster->CastSpell(GetHitUnit(), SPELL_TOXIC_REGURGITATION_MARKER, args);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_azhiccar_toxic_regurgitation_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 1227745 - Toxic Regurgitation
class spell_azhiccar_toxic_regurgitation_cast : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_TOXIC_REGURGITATION_MISSILE });
}
void HandleOnHit() const
{
Unit* caster = GetCaster();
std::list<Player*> players;
Trinity::UnitAuraCheck check(true, SPELL_TOXIC_REGURGITATION_MARKER);
Trinity::PlayerListSearcher<Trinity::UnitAuraCheck> searcher(caster, players, check);
Cell::VisitWorldObjects(caster, searcher, 200.0f);
for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
caster->CastSpell(*itr, SPELL_TOXIC_REGURGITATION_MISSILE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
}
void Register() override
{
OnHit += SpellHitFn(spell_azhiccar_toxic_regurgitation_cast::HandleOnHit);
}
};
// 1217327 - Invading Shriek
class spell_azhiccar_invading_shriek : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_INVADING_SHRIEK_DAMAGE });
}
void HandleAfterCast() const
{
Unit* caster = GetCaster();
caster->CastSpell(caster, SPELL_INVADING_SHRIEK_DAMAGE, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
}
void Register() override
{
AfterCast += SpellCastFn(spell_azhiccar_invading_shriek::HandleAfterCast);
}
};
class spell_azhiccar_invading_shriek_aura : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_INVADING_SHRIEK_DAMAGE });
}
void OnApply(AuraEffect const* /*auraEffect*/, AuraEffectHandleModes /*mode*/)
{
std::vector<Creature*> stalkers;
GetCaster()->GetCreatureListWithEntryInGrid(stalkers, NPC_PORTAL_STALKER, 150.0f);
Trinity::Containers::RandomShuffle(stalkers);
for (Creature* creature : stalkers)
_stalkerList.push(creature->GetGUID());
}
void OnPeriodic(AuraEffect const* aurEff)
{
if (aurEff->GetTickNumber() > 1)
{
Unit* caster = GetCaster();
ObjectGuid guid = _stalkerList.front();
_stalkerList.pop();
if (Creature* stalker = ObjectAccessor::GetCreature(*caster, guid))
caster->CastSpell(stalker->GetPosition(), SPELL_INVADING_SHRIEK_DUMMY, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringAura = aurEff
});
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_azhiccar_invading_shriek_aura::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_azhiccar_invading_shriek_aura::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
private:
std::queue<ObjectGuid> _stalkerList;
};
// 1217330 - Invading Shriek
class spell_azhiccar_invading_shriek_dummy : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_INVADING_SHRIEK_SUMMON });
}
void HandleHit(SpellEffIndex /*effIndex*/) const
{
GetCaster()->CastSpell(GetHitDest()->GetPosition(), SPELL_INVADING_SHRIEK_SUMMON, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
}
void Register() override
{
OnEffectHit += SpellEffectFn(spell_azhiccar_invading_shriek_dummy::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 1217758 - Player Detection (SERVERSIDE)
class spell_azhiccar_player_detection : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_THRASH });
}
void HandlePlayerDetection() const
{
Unit* caster = GetCaster();
int64 const targetsHit = GetUnitTargetCountForEffect(EFFECT_0);
if (targetsHit > 0)
return;
Spell* currentChanneledSpell = caster->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
if (currentChanneledSpell && (currentChanneledSpell->GetSpellInfo()->Id == SPELL_DEVOUR))
return;
if (caster->HasAura(SPELL_DEVOUR))
return;
caster->CastSpell(caster, SPELL_THRASH, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
void Register() override
{
AfterCast += SpellCastFn(spell_azhiccar_player_detection::HandlePlayerDetection);
}
};
// 1217232 - Devour
class spell_azhiccar_devour : public AuraScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_DEVOUR_AREATRIGGER });
}
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetCaster()->CastSpell(GetCaster(), SPELL_DEVOUR_AREATRIGGER, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
GetCaster()->CastSpell(GetCaster(), SPELL_DEVOUR_SELECTOR, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
void Register() override
{
AfterEffectApply += AuraEffectRemoveFn(spell_azhiccar_devour::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// 1217255 - Devour
class spell_azhiccar_devour_selector : public SpellScript
{
void HandleHitTarget(SpellEffIndex /*effIndex*/) const
{
Unit* target = GetHitUnit();
std::function<void(Movement::MoveSplineInit&)> initializer = [](Movement::MoveSplineInit& init)
{
init.SetBackward();
init.MoveTo(AzhiccarPosition.GetPositionX(), AzhiccarPosition.GetPositionY(), AzhiccarPosition.GetPositionZ(), false);
};
target->SendPlaySpellVisualKit(SPELL_VISUALKIT_ALARM, 4, 9000);
target->GetMotionMaster()->LaunchMoveSpline(std::move(initializer), POINT_AZHICCAR, MOTION_PRIORITY_NORMAL, POINT_MOTION_TYPE);
target->SetSpeed(MOVE_RUN_BACK, 12.0f);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_azhiccar_devour_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
// 1217241 - Feast
// 1217252 - Feast
class spell_azhiccar_feast : public SpellScript
{
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_FEAST_HEAL });
}
void HandleHit(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
caster->CastSpell(caster, SPELL_FEAST_HEAL, CastSpellExtraArgsInit{
.TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
.TriggeringSpell = GetSpell()
});
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_azhiccar_feast::HandleHit, EFFECT_0, SPELL_EFFECT_ANY);
}
};
// 1217441 - Digestive Spittle
// Id - 36181
struct at_azhiccar_digestive_spittle : AreaTriggerAI
{
using AreaTriggerAI::AreaTriggerAI;
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
Unit* caster = at->GetCaster();
if (!caster)
return;
caster->CastSpell(unit, SPELL_DIGESTIVE_SPITTLE, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
{
unit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_SPITTLE);
}
};
// 1217240 Devour
// Id - 38188
struct at_azhiccar_devour_force : AreaTriggerAI
{
using AreaTriggerAI::AreaTriggerAI;
void OnUnitEnter(Unit* unit) override
{
if (!unit->IsPlayer())
return;
unit->ApplyMovementForce(at->GetGUID(), at->GetPosition(), 3.0f, MovementForceType::Gravity);
}
void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
{
unit->RemoveMovementForce(at->GetGUID());
}
};
// 1217240 Devour
// Id - 38189
struct at_azhiccar_devour : AreaTriggerAI
{
using AreaTriggerAI::AreaTriggerAI;
void OnUnitEnter(Unit* unit) override
{
Unit* caster = at->GetCaster();
if (!caster)
return;
if (unit->IsPlayer())
caster->CastSpell(unit, SPELL_FEAST, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
else if (unit->HasAura(SPELL_DEVOUR_SELECTOR))
caster->CastSpell(unit, SPELL_FEAST_INSTAKILL, TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR);
}
};
// Id - XXX
struct at_azhiccar_intro : AreaTriggerAI
{
at_azhiccar_intro(AreaTrigger* areatrigger) : AreaTriggerAI(areatrigger) {}
void OnUnitEnter(Unit* unit) override
{
InstanceScript* instance = at->GetInstanceScript();
if (!instance)
return;
Player* player = unit->ToPlayer();
if (!player || player->IsGameMaster())
return;
if (Creature* azhiccar = instance->GetCreature(DATA_AZHICCAR))
azhiccar->AI()->DoAction(ACTION_START_INTRO);
at->Remove();
}
};
// 245411 - Ravaging Scavenger
// 245412 - Voracious Gorger
struct npc_azhiccar_intro_creature : public ScriptedAI
{
npc_azhiccar_intro_creature(Creature* creature) : ScriptedAI(creature) {}
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_DEVOUR_INTRO_SELECTOR)
{
_scheduler.Schedule(2000ms, 4500ms, [this](TaskContext)
{
me->SendPlayOrphanSpellVisual(OrphanSpellVisualPosition, me->GetPosition(), SPELL_VISUAL_DEVOURED, 45.0f, false);
DoCastSelf(SPELL_DEVOUR_INSTAKILL);
me->DespawnOrUnsummon(5s);
});
}
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
};
// 1233116 - Devour
class spell_azhiccar_devour_intro_selector : public SpellScript
{
void HandleHitTarget(SpellEffIndex /*effIndex*/) const
{
Unit* target = GetHitUnit();
std::function<void(Movement::MoveSplineInit&)> initializer = [](Movement::MoveSplineInit& init)
{
init.SetBackward();
init.MoveTo(AzhiccarPosition.GetPositionX(), AzhiccarPosition.GetPositionY(), AzhiccarPosition.GetPositionZ(), false);
};
target->SendPlaySpellVisualKit(SPELL_VISUALKIT_ALARM, 4, 9000);
target->GetMotionMaster()->LaunchMoveSpline(std::move(initializer), POINT_AZHICCAR, MOTION_PRIORITY_NORMAL, POINT_MOTION_TYPE);
target->SetSpeed(MOVE_RUN_BACK, 16.0f);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_azhiccar_devour_intro_selector::HandleHitTarget, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
void AddSC_boss_azhiccar()
{
RegisterEcodomeAldaniCreatureAI(boss_azhiccar);
RegisterSpellScript(spell_azhiccar_energy_controller);
RegisterSpellScript(spell_azhiccar_toxic_regurgitation_selector);
RegisterSpellScript(spell_azhiccar_toxic_regurgitation_cast);
RegisterSpellAndAuraScriptPair(spell_azhiccar_invading_shriek, spell_azhiccar_invading_shriek_aura);
RegisterSpellScript(spell_azhiccar_invading_shriek_dummy);
RegisterSpellScript(spell_azhiccar_player_detection);
RegisterSpellScript(spell_azhiccar_devour);
RegisterSpellScript(spell_azhiccar_devour_selector);
RegisterSpellScript(spell_azhiccar_feast);
RegisterAreaTriggerAI(at_azhiccar_digestive_spittle);
RegisterAreaTriggerAI(at_azhiccar_devour_force);
RegisterAreaTriggerAI(at_azhiccar_devour);
// Intro
RegisterAreaTriggerAI(at_azhiccar_intro);
RegisterEcodomeAldaniCreatureAI(npc_azhiccar_intro_creature);
RegisterSpellScript(spell_azhiccar_devour_intro_selector);
}
@@ -0,0 +1,48 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms.
*/
#ifndef DEF_ECODOME_ALDANI_H_
#define DEF_ECODOME_ALDANI_H_
#include "CreatureAIImpl.h"
#define EAScriptName "instance_ecodome_aldani"
#define DataHeader "EcodomeAldani"
uint32 const EncounterCount = 3;
enum EcodomeAldaniDataTypes
{
// Encounters
DATA_AZHICCAR = 0,
DATA_TAAHBAT_AND_AWAZJ = 1,
DATA_SOUL_SCRIBE = 2,
DATA_TAAHBAT,
DATA_AWAZJ,
DATA_AZHICCAR_INTRO
};
enum EcodomeAldaniCreatureIds
{
// Bosses
BOSS_AZHICCAR = 234893,
BOSS_TAAHBAT = 234933,
BOSS_AWAZJ = 241375,
BOSS_SOUL_SCRIBE = 247283
};
template <class AI, class T>
inline AI* GetEcodomeAldaniAI(T* obj)
{
return GetInstanceAI<AI>(obj, EAScriptName);
}
#define RegisterEcodomeAldaniCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetEcodomeAldaniAI)
#endif
@@ -0,0 +1,82 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms.
*/
#include "Creature.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"
#include "ecodome_aldani.h"
static constexpr ObjectData creatureData[] =
{
{ BOSS_AZHICCAR, DATA_AZHICCAR },
{ BOSS_TAAHBAT, DATA_TAAHBAT },
{ BOSS_AWAZJ, DATA_AWAZJ },
{ BOSS_SOUL_SCRIBE, DATA_SOUL_SCRIBE }
};
DungeonEncounterData const encounters[] =
{
{ DATA_AZHICCAR, {{ 3107 }} },
{ DATA_TAAHBAT_AND_AWAZJ, {{ 3108 }} },
{ DATA_SOUL_SCRIBE, {{ 3109 }} }
};
class instance_ecodome_aldani : public InstanceMapScript
{
public:
instance_ecodome_aldani() : InstanceMapScript(EAScriptName, 2830) { }
struct instance_ecodome_aldani_InstanceMapScript: public InstanceScript
{
instance_ecodome_aldani_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, {});
LoadDungeonEncounterData(encounters);
_azhiccarIntroState = NOT_STARTED;
}
uint32 GetData(uint32 dataId) const override
{
switch (dataId)
{
case DATA_AZHICCAR_INTRO:
return _azhiccarIntroState;
default:
break;
}
return 0;
}
void SetData(uint32 dataId, uint32 value) override
{
switch (dataId)
{
case DATA_AZHICCAR_INTRO:
_azhiccarIntroState = value;
break;
default:
break;
}
}
private:
uint8 _azhiccarIntroState;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_ecodome_aldani_InstanceMapScript(map);
}
};
void AddSC_instance_ecodome_aldani()
{
new instance_ecodome_aldani();
}
@@ -0,0 +1,150 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "operation_floodgate.h"
#include "GameObject.h"
#include "Map.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
enum Spells
{
SPELL_JUMPSTART = 460156,
SPELL_EXCESSIVE_ELECTRIFICATION = 473287,
SPELL_SONIC_BOOM = 473220,
SPELL_SONIC_BOOM_EXPLOSION = 473240,
SPELL_MOBILIZE_MECHADRONES = 471585,
SPELL_ELECTROCRUSH = 473351,
SPELL_KILL_O_BLOCK_BARRIER = 469981,
SPELL_MAXIMUM_DISTORTION = 1214780,
SPELL_SHOOT = 460393,
SPELL_DOOM_STORM = 472452
};
enum Events
{
EVENT_ELECTROCRUSH = 1,
EVENT_SONIC_BOOM,
EVENT_KILL_O_BLOCK_BARRIER,
EVENT_MOBILIZE_MECHADRONES,
EVENT_CHECK_MECHADRONES
};
struct boss_big_momma : public BossAI
{
boss_big_momma(Creature* creature) : BossAI(creature, DATA_BIG_MOMMA)
{
Initialize();
}
void Initialize()
{
_activeMechadrones = 0;
_jumpstartActive = false;
}
void Reset() override
{
_Reset();
Initialize();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_ELECTROCRUSH, 10s);
events.ScheduleEvent(EVENT_SONIC_BOOM, 15s);
events.ScheduleEvent(EVENT_KILL_O_BLOCK_BARRIER, 30s);
events.ScheduleEvent(EVENT_MOBILIZE_MECHADRONES, 5s);
events.ScheduleEvent(EVENT_CHECK_MECHADRONES, 2s);
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
if (summon->GetEntry() == NPC_DARKFUSE_MECHADRONE)
{
_activeMechadrones--;
if (_activeMechadrones == 0 && !_jumpstartActive)
{
_jumpstartActive = true;
DoCastSelf(SPELL_JUMPSTART);
scheduler.Schedule(12s, [this](TaskContext)
{
DoCastAOE(SPELL_EXCESSIVE_ELECTRIFICATION);
_jumpstartActive = 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_ELECTROCRUSH:
DoCastVictim(SPELL_ELECTROCRUSH);
events.Repeat(20s);
break;
case EVENT_SONIC_BOOM:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
DoCast(target, SPELL_SONIC_BOOM);
events.Repeat(25s);
break;
case EVENT_KILL_O_BLOCK_BARRIER:
DoCastSelf(SPELL_KILL_O_BLOCK_BARRIER);
events.Repeat(45s);
break;
case EVENT_MOBILIZE_MECHADRONES:
DoCastAOE(SPELL_MOBILIZE_MECHADRONES);
SummonMechadrones();
events.Repeat(60s);
break;
case EVENT_CHECK_MECHADRONES:
events.Repeat(2s);
break;
default:
break;
}
}
}
private:
void SummonMechadrones()
{
for (uint8 i = 0; i < 4; ++i)
{
Position pos = me->GetRandomNearPosition(10.0f);
if (Creature* drone = me->SummonCreature(NPC_DARKFUSE_MECHADRONE, pos, TEMPSUMMON_CORPSE_DESPAWN))
{
_activeMechadrones++;
if (IsMythic())
drone->CastSpell(drone, SPELL_MAXIMUM_DISTORTION);
}
}
}
uint8 _activeMechadrones;
bool _jumpstartActive;
};
void AddSC_boss_big_momma()
{
RegisterOperationFloodgateCreatureAI(boss_big_momma);
}
@@ -0,0 +1,224 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "operation_floodgate.h"
#include "GameObject.h"
#include "Map.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
enum Spells
{
// Keeza
SPELL_QUICK_SHOT = 460602,
SPELL_BBBFG = 473594,
SPELL_BIG_BADA_BOOM = 460867,
SPELL_DEFLAGRATION = 460787,
SPELL_SHRAPNEL = 472755,
SPELL_KINETIC_GEL = 473690,
// Bront
SPELL_WALLOP = 459799,
SPELL_BARRELING_CHARGE = 459779,
SPELL_DIVIDED_DUO = 470090,
SPELL_DAMAGE_INCREASE = 470091
};
enum Events
{
// Keeza
EVENT_QUICK_SHOT = 1,
EVENT_BBBFG,
EVENT_BIG_BADA_BOOM,
EVENT_KINETIC_GEL,
// Bront
EVENT_WALLOP,
EVENT_BARRELING_CHARGE,
ACTION_PARTNER_DIED
};
struct boss_keeza_quickfuse : public BossAI
{
boss_keeza_quickfuse(Creature* creature) : BossAI(creature, DATA_DEMOLITION_DUO)
{
Initialize();
}
void Initialize()
{
_partnerDead = false;
}
void Reset() override
{
_Reset();
Initialize();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
if (Creature* bront = instance->GetCreature(DATA_BRONT))
DoZoneInCombat(bront);
events.ScheduleEvent(EVENT_QUICK_SHOT, 5s);
events.ScheduleEvent(EVENT_BBBFG, 15s);
events.ScheduleEvent(EVENT_BIG_BADA_BOOM, 20s);
if (IsMythic())
events.ScheduleEvent(EVENT_KINETIC_GEL, 25s);
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
{
if (damage >= me->GetHealth())
{
if (Creature* bront = instance->GetCreature(DATA_BRONT))
{
if (bront->IsAlive())
{
bront->AI()->DoAction(ACTION_PARTNER_DIED);
_partnerDead = true;
}
}
}
}
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_QUICK_SHOT:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
DoCast(target, SPELL_QUICK_SHOT);
events.Repeat(10s);
break;
case EVENT_BBBFG:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
DoCast(target, SPELL_BBBFG);
events.Repeat(25s);
break;
case EVENT_BIG_BADA_BOOM:
DoCastAOE(SPELL_BIG_BADA_BOOM);
events.Repeat(30s);
break;
case EVENT_KINETIC_GEL:
if (IsMythic())
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
DoCast(target, SPELL_KINETIC_GEL);
events.Repeat(35s);
break;
default:
break;
}
}
}
private:
bool _partnerDead;
};
struct boss_bront : public BossAI
{
boss_bront(Creature* creature) : BossAI(creature, DATA_BRONT)
{
Initialize();
}
void Initialize()
{
_partnerDead = false;
_increaseDamageTimer = 4000;
}
void Reset() override
{
_Reset();
Initialize();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_WALLOP, 8s);
events.ScheduleEvent(EVENT_BARRELING_CHARGE, 15s);
}
void DoAction(int32 action) override
{
if (action == ACTION_PARTNER_DIED)
{
_partnerDead = true;
DoCastSelf(SPELL_DIVIDED_DUO);
events.ScheduleEvent(EVENT_WALLOP, 3s);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (_partnerDead)
{
if (_increaseDamageTimer <= diff)
{
DoCastSelf(SPELL_DAMAGE_INCREASE);
_increaseDamageTimer = 4000;
}
else
_increaseDamageTimer -= diff;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_WALLOP:
DoCastVictim(SPELL_WALLOP);
events.Repeat(_partnerDead ? 5s : 15s);
break;
case EVENT_BARRELING_CHARGE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
DoCast(target, SPELL_BARRELING_CHARGE);
events.Repeat(20s);
break;
default:
break;
}
}
}
private:
bool _partnerDead;
uint32 _increaseDamageTimer;
};
void AddSC_boss_demolition_duo()
{
RegisterOperationFloodgateCreatureAI(boss_keeza_quickfuse);
RegisterOperationFloodgateCreatureAI(boss_bront);
}
@@ -0,0 +1,131 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "operation_floodgate.h"
#include "GameObject.h"
#include "Map.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
enum Spells
{
SPELL_TURBO_CHARGE = 465456,
SPELL_TURBO_BOLT = 466088,
SPELL_DAM_WATER = 468261,
SPELL_SHOCK_WATER = 468661,
SPELL_DAM_RUBBLE = 468606,
SPELL_LEAPING_SPARKS = 468846,
SPELL_GIGAZAP = 468812,
SPELL_THUNDER_PUNCH = 466197
};
enum Events
{
EVENT_TURBO_CHARGE = 1,
EVENT_TURBO_BOLT,
EVENT_DAM_WATER,
EVENT_DAM_RUBBLE,
EVENT_LEAPING_SPARKS,
EVENT_GIGAZAP,
EVENT_THUNDER_PUNCH
};
struct boss_geezle_gigazap : public BossAI
{
boss_geezle_gigazap(Creature* creature) : BossAI(creature, DATA_GEEZLE_GIGAZAP)
{
electricityPower = 0;
}
void Reset() override
{
_Reset();
electricityPower = 0;
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_TURBO_CHARGE, 10s);
events.ScheduleEvent(EVENT_DAM_WATER, 15s);
events.ScheduleEvent(EVENT_DAM_RUBBLE, 20s);
events.ScheduleEvent(EVENT_THUNDER_PUNCH, 5s);
}
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_TURBO_CHARGE:
DoCast(SPELL_TURBO_CHARGE);
electricityPower += 10;
events.ScheduleEvent(EVENT_TURBO_CHARGE, 45s);
events.ScheduleEvent(EVENT_TURBO_BOLT, 2s);
break;
case EVENT_TURBO_BOLT:
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
DoCast(target, SPELL_TURBO_BOLT);
break;
case EVENT_DAM_WATER:
DoCast(SPELL_DAM_WATER);
events.ScheduleEvent(EVENT_DAM_WATER, 25s);
break;
case EVENT_DAM_RUBBLE:
DoCast(SPELL_DAM_RUBBLE);
events.ScheduleEvent(EVENT_DAM_RUBBLE, 30s);
break;
case EVENT_LEAPING_SPARKS:
if (electricityPower >= 40)
{
DoCast(SPELL_LEAPING_SPARKS);
electricityPower -= 40;
}
events.ScheduleEvent(EVENT_LEAPING_SPARKS, 35s);
break;
case EVENT_GIGAZAP:
if (electricityPower >= 20)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
DoCast(target, SPELL_GIGAZAP);
electricityPower -= 20;
}
events.ScheduleEvent(EVENT_GIGAZAP, 15s);
break;
case EVENT_THUNDER_PUNCH:
if (electricityPower >= 10)
{
DoCastVictim(SPELL_THUNDER_PUNCH);
electricityPower -= 10;
}
events.ScheduleEvent(EVENT_THUNDER_PUNCH, 8s);
break;
default:
break;
}
}
}
private:
uint8 electricityPower;
};
void AddSC_boss_geezle_gigazap()
{
RegisterCreatureAI(boss_geezle_gigazap);
}
@@ -0,0 +1,149 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "operation_floodgate.h"
#include "GameObject.h"
#include "Map.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
enum Spells
{
SPELL_SLUDGE_CLAWS = 469478,
SPELL_MUDSLIDE = 473112,
SPELL_AWAKEN_THE_SWAMP = 473070,
SPELL_SKEWERING_ROOT = 473047,
SPELL_RUSHING_TIDE = 473052,
SPELL_RAZORCHOKE_VINES = 470039
};
enum Events
{
EVENT_SLUDGE_CLAWS = 1,
EVENT_MUDSLIDE,
EVENT_AWAKEN_THE_SWAMP,
EVENT_RAZORCHOKE_VINES
};
struct boss_swampface : public BossAI
{
boss_swampface(Creature* creature) : BossAI(creature, DATA_SWAMPFACE)
{
Initialize();
}
void Initialize()
{
_awakenPhase = false;
}
void Reset() override
{
_Reset();
Initialize();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_SLUDGE_CLAWS, 8s);
events.ScheduleEvent(EVENT_MUDSLIDE, 15s);
events.ScheduleEvent(EVENT_AWAKEN_THE_SWAMP, 30s);
if (IsMythic())
events.ScheduleEvent(EVENT_RAZORCHOKE_VINES, 20s);
}
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_SLUDGE_CLAWS:
DoCastVictim(SPELL_SLUDGE_CLAWS);
events.Repeat(15s);
break;
case EVENT_MUDSLIDE:
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
{
me->SetFacingToObject(target);
DoCast(SPELL_MUDSLIDE);
}
events.Repeat(20s);
break;
}
case EVENT_AWAKEN_THE_SWAMP:
{
_awakenPhase = true;
DoCastAOE(SPELL_AWAKEN_THE_SWAMP);
// Schedule Skewering Roots
scheduler.Schedule(1s, 4s, [this](TaskContext context)
{
if (_awakenPhase)
{
Position pos = me->GetRandomNearPosition(20.0f);
me->CastSpell(pos, SPELL_SKEWERING_ROOT, true);
// Rushing Tide after root
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
{
me->CastSpell(target, SPELL_RUSHING_TIDE, true);
}
context.Repeat(1s);
}
});
scheduler.Schedule(4s, [this](TaskContext)
{
_awakenPhase = false;
});
events.Repeat(45s);
break;
}
case EVENT_RAZORCHOKE_VINES:
{
if (IsMythic())
{
// Select two random players for vines
if (Unit* first = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
if (Unit* second = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true, true, -SPELL_RAZORCHOKE_VINES))
{
first->CastSpell(second, SPELL_RAZORCHOKE_VINES, true);
second->CastSpell(first, SPELL_RAZORCHOKE_VINES, true);
}
}
events.Repeat(35s);
break;
}
default:
break;
}
}
}
private:
bool _awakenPhase;
};
void AddSC_boss_swampface()
{
RegisterOperationFloodgateCreatureAI(boss_swampface);
}
@@ -0,0 +1,89 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "operation_floodgate.h"
#include "GameObject.h"
#include "Map.h"
#include "TemporarySummon.h"
#include "CreatureAI.h"
static constexpr ObjectData creatureData[] =
{
{ BOSS_BIG_MOMMA, DATA_BIG_MOMMA },
{ BOSS_DEMOLITION_DUO, DATA_DEMOLITION_DUO },
{ BOSS_SWAMPFACE, DATA_SWAMPFACE },
{ BOSS_GEEZLE_GIGAZAP, DATA_GEEZLE_GIGAZAP },
{ 0, 0 } // END
};
static constexpr DungeonEncounterData const encounters[] =
{
{ DATA_BIG_MOMMA, {{ 3020 }} },
{ DATA_DEMOLITION_DUO, {{ 3019 }} },
{ DATA_SWAMPFACE, {{ 3053 }} },
{ DATA_GEEZLE_GIGAZAP, {{ 3054 }} },
};
class instance_operation_floodgate : public InstanceMapScript
{
public:
instance_operation_floodgate() : InstanceMapScript(OPFGScriptName, 2773) { }
struct instance_operation_floodgate_InstanceMapScript : public InstanceScript
{
instance_operation_floodgate_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, {});
LoadDungeonEncounterData(encounters);
}
void OnPlayerEnter(Player* player) override
{
if (!player->GetGroup() || !player->GetGroup()->GetLeaderGUID())
return;
ObjectGuid leaderguid = player->GetGroup()->GetLeaderGUID();
if (!leaderguid)
return;
if (Player* leader = ObjectAccessor::GetPlayer(*player, leaderguid))
{
if (leader->GetTeam() == HORDE)
faction_group = HORDE;
else if (leader->GetTeam() == ALLIANCE)
faction_group = ALLIANCE;
else
faction_group = HORDE;
}
player->GetGroup()->AddFollowerModeBots(player);
}
void OnPlayerExit(Player* player)
{
player->GetGroup()->DespawnFollowerModeBots(player);
}
private:
bool faction_group = HORDE;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_operation_floodgate_InstanceMapScript(map);
}
};
void AddSC_instance_operation_floodgate()
{
new instance_operation_floodgate();
}
@@ -0,0 +1,48 @@
/*
* Copyright (C) WowCommunity Project
*
* This SourceCode is NOT free a software. Please hold everything Private
* and read our Terms
*/
#ifndef DEF_OPERATION_FLOODGATE_H_
#define DEF_OPERATION_FLOODGATE_H_
#include "CreatureAIImpl.h"
#define OPFGScriptName "instance_operation_floodgate"
#define DataHeader "OPFG"
constexpr uint32 EncounterCount = 4;
enum OperationFloodgateDataTypes
{
// Encounters
DATA_BIG_MOMMA = 0,
DATA_DEMOLITION_DUO,
DATA_SWAMPFACE,
DATA_GEEZLE_GIGAZAP,
DATA_BRONT
};
enum OperationFloodgateCreatureIds
{
// Bosses
BOSS_BIG_MOMMA = 226398,
BOSS_DEMOLITION_DUO = 226403,
BOSS_SWAMPFACE = 226396,
BOSS_GEEZLE_GIGAZAP = 242255,
//creature
NPC_DARKFUSE_MECHADRONE = 228424,
};
template <class AI, class T>
inline AI* GetOperationFloodgateAI(T* obj)
{
return GetInstanceAI<AI>(obj, OPFGScriptName);
}
#define RegisterOperationFloodgateCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetOperationFloodgateAI)
#endif
@@ -53,6 +53,25 @@ void AddSC_boss_blazikon();
void AddSC_boss_the_candle_king();
void AddSC_boss_the_darkness();
//Operation Floodgate
void AddSC_instance_operation_floodgate();
void AddSC_boss_big_momma();
void AddSC_boss_demolition_duo();
void AddSC_boss_geezle_gigazap();
void AddSC_boss_swampface();
//Eco Dome Aldani
void AddSC_instance_ecodome_aldani();
void AddSC_boss_azhiccar();
//The Necrotic Wake
void AddSC_instance_necrotic_wake();
void AddSC_boss_amarth();
void AddSC_boss_blightbone();
void AddSC_boss_nalthor();
void AddSC_boss_surgeon_stitchflesh();
void AddSC_necrotic_wake();
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
void AddWarWithinScripts()
@@ -100,4 +119,23 @@ void AddWarWithinScripts()
AddSC_boss_blazikon();
AddSC_boss_the_candle_king();
AddSC_boss_the_darkness();
//Operation Floodgate
AddSC_instance_operation_floodgate();
AddSC_boss_big_momma();
AddSC_boss_demolition_duo();
AddSC_boss_geezle_gigazap();
AddSC_boss_swampface();
//Eco Dome Aldani
AddSC_instance_ecodome_aldani();
AddSC_boss_azhiccar();
//The Necrotic Wake
AddSC_instance_necrotic_wake();
AddSC_boss_amarth();
AddSC_boss_blightbone();
AddSC_boss_nalthor();
AddSC_boss_surgeon_stitchflesh();
AddSC_necrotic_wake();
}