Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
-- DB update 2022_06_13_04 -> 2022_06_13_05
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_dbc` WHERE `ID` = 24081;
|
||||||
|
INSERT INTO `spell_dbc` (`ID`, `Category`, `DispelType`, `Mechanic`, `Attributes`, `AttributesEx`, `AttributesEx2`, `AttributesEx3`, `AttributesEx4`, `AttributesEx5`, `AttributesEx6`, `AttributesEx7`, `ShapeshiftMask`, `unk_320_2`, `ShapeshiftExclude`, `unk_320_3`, `Targets`, `TargetCreatureType`, `RequiresSpellFocus`, `FacingCasterFlags`, `CasterAuraState`, `TargetAuraState`, `ExcludeCasterAuraState`, `ExcludeTargetAuraState`, `CasterAuraSpell`, `TargetAuraSpell`, `ExcludeCasterAuraSpell`, `ExcludeTargetAuraSpell`, `CastingTimeIndex`, `RecoveryTime`, `CategoryRecoveryTime`, `InterruptFlags`, `AuraInterruptFlags`, `ChannelInterruptFlags`, `ProcTypeMask`, `ProcChance`, `ProcCharges`, `MaxLevel`, `BaseLevel`, `SpellLevel`, `DurationIndex`, `PowerType`, `ManaCost`, `ManaCostPerLevel`, `ManaPerSecond`, `ManaPerSecondPerLevel`, `RangeIndex`, `Speed`, `ModalNextSpell`, `CumulativeAura`, `Totem_1`, `Totem_2`, `Reagent_1`, `Reagent_2`, `Reagent_3`, `Reagent_4`, `Reagent_5`, `Reagent_6`, `Reagent_7`, `Reagent_8`, `ReagentCount_1`, `ReagentCount_2`, `ReagentCount_3`, `ReagentCount_4`, `ReagentCount_5`, `ReagentCount_6`, `ReagentCount_7`, `ReagentCount_8`, `EquippedItemClass`, `EquippedItemSubclass`, `EquippedItemInvTypes`, `Effect_1`, `Effect_2`, `Effect_3`, `EffectDieSides_1`, `EffectDieSides_2`, `EffectDieSides_3`, `EffectRealPointsPerLevel_1`, `EffectRealPointsPerLevel_2`, `EffectRealPointsPerLevel_3`, `EffectBasePoints_1`, `EffectBasePoints_2`, `EffectBasePoints_3`, `EffectMechanic_1`, `EffectMechanic_2`, `EffectMechanic_3`, `ImplicitTargetA_1`, `ImplicitTargetA_2`, `ImplicitTargetA_3`, `ImplicitTargetB_1`, `ImplicitTargetB_2`, `ImplicitTargetB_3`, `EffectRadiusIndex_1`, `EffectRadiusIndex_2`, `EffectRadiusIndex_3`, `EffectAura_1`, `EffectAura_2`, `EffectAura_3`, `EffectAuraPeriod_1`, `EffectAuraPeriod_2`, `EffectAuraPeriod_3`, `EffectMultipleValue_1`, `EffectMultipleValue_2`, `EffectMultipleValue_3`, `EffectChainTargets_1`, `EffectChainTargets_2`, `EffectChainTargets_3`, `EffectItemType_1`, `EffectItemType_2`, `EffectItemType_3`, `EffectMiscValue_1`, `EffectMiscValue_2`, `EffectMiscValue_3`, `EffectMiscValueB_1`, `EffectMiscValueB_2`, `EffectMiscValueB_3`, `EffectTriggerSpell_1`, `EffectTriggerSpell_2`, `EffectTriggerSpell_3`, `EffectPointsPerCombo_1`, `EffectPointsPerCombo_2`, `EffectPointsPerCombo_3`, `EffectSpellClassMaskA_1`, `EffectSpellClassMaskA_2`, `EffectSpellClassMaskA_3`, `EffectSpellClassMaskB_1`, `EffectSpellClassMaskB_2`, `EffectSpellClassMaskB_3`, `EffectSpellClassMaskC_1`, `EffectSpellClassMaskC_2`, `EffectSpellClassMaskC_3`, `SpellVisualID_1`, `SpellVisualID_2`, `SpellIconID`, `ActiveIconID`, `SpellPriority`, `Name_Lang_enUS`, `Name_Lang_enGB`, `Name_Lang_koKR`, `Name_Lang_frFR`, `Name_Lang_deDE`, `Name_Lang_enCN`, `Name_Lang_zhCN`, `Name_Lang_enTW`, `Name_Lang_zhTW`, `Name_Lang_esES`, `Name_Lang_esMX`, `Name_Lang_ruRU`, `Name_Lang_ptPT`, `Name_Lang_ptBR`, `Name_Lang_itIT`, `Name_Lang_Unk`, `Name_Lang_Mask`, `NameSubtext_Lang_enUS`, `NameSubtext_Lang_enGB`, `NameSubtext_Lang_koKR`, `NameSubtext_Lang_frFR`, `NameSubtext_Lang_deDE`, `NameSubtext_Lang_enCN`, `NameSubtext_Lang_zhCN`, `NameSubtext_Lang_enTW`, `NameSubtext_Lang_zhTW`, `NameSubtext_Lang_esES`, `NameSubtext_Lang_esMX`, `NameSubtext_Lang_ruRU`, `NameSubtext_Lang_ptPT`, `NameSubtext_Lang_ptBR`, `NameSubtext_Lang_itIT`, `NameSubtext_Lang_Unk`, `NameSubtext_Lang_Mask`, `Description_Lang_enUS`, `Description_Lang_enGB`, `Description_Lang_koKR`, `Description_Lang_frFR`, `Description_Lang_deDE`, `Description_Lang_enCN`, `Description_Lang_zhCN`, `Description_Lang_enTW`, `Description_Lang_zhTW`, `Description_Lang_esES`, `Description_Lang_esMX`, `Description_Lang_ruRU`, `Description_Lang_ptPT`, `Description_Lang_ptBR`, `Description_Lang_itIT`, `Description_Lang_Unk`, `Description_Lang_Mask`, `AuraDescription_Lang_enUS`, `AuraDescription_Lang_enGB`, `AuraDescription_Lang_koKR`, `AuraDescription_Lang_frFR`, `AuraDescription_Lang_deDE`, `AuraDescription_Lang_enCN`, `AuraDescription_Lang_zhCN`, `AuraDescription_Lang_enTW`, `AuraDescription_Lang_zhTW`, `AuraDescription_Lang_esES`, `AuraDescription_Lang_esMX`, `AuraDescription_Lang_ruRU`, `AuraDescription_Lang_ptPT`, `AuraDescription_Lang_ptBR`, `AuraDescription_Lang_itIT`, `AuraDescription_Lang_Unk`, `AuraDescription_Lang_Mask`, `ManaCostPct`, `StartRecoveryCategory`, `StartRecoveryTime`, `MaxTargetLevel`, `SpellClassSet`, `SpellClassMask_1`, `SpellClassMask_2`, `SpellClassMask_3`, `MaxTargets`, `DefenseType`, `PreventionType`, `StanceBarOrder`, `EffectChainAmplitude_1`, `EffectChainAmplitude_2`, `EffectChainAmplitude_3`, `MinFactionID`, `MinReputation`, `RequiredAuraVision`, `RequiredTotemCategoryID_1`, `RequiredTotemCategoryID_2`, `RequiredAreasID`, `SchoolMask`, `RuneCostID`, `SpellMissileID`, `PowerDisplayID`, `EffectBonusMultiplier_1`, `EffectBonusMultiplier_2`, `EffectBonusMultiplier_3`, `SpellDescriptionVariableID`, `SpellDifficultyID`) VALUES
|
||||||
|
(24081, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 28, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 15041, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Summon Spawn of Mar\'li', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_hatch_eggs', 'spell_enveloping_webs', 'spell_marli_transform');
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(24083, 'spell_hatch_eggs'),
|
||||||
|
(24110, 'spell_enveloping_webs'),
|
||||||
|
(24084, 'spell_marli_transform');
|
||||||
|
|
||||||
|
DELETE FROM `creature_text` WHERE `CreatureID` = 15041;
|
||||||
|
DELETE FROM `creature_text` WHERE `CreatureID` = 14510 AND `GroupID` = 4;
|
||||||
|
INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
|
||||||
|
(15041, 0, 0, '%s is fully grown!', 16, 0, 100, 0, 0, 0, 10445, 0, 'Spawn of Mar\'li - EMOTE_FULL_GROWN'),
|
||||||
|
(14510, 4, 0, 'The brood shall not fall!', 14, 0, 100, 0, 0, 0, 10444, 0, 'Mar\'li - SAY_TRANSFORM_BACK');
|
||||||
|
|
||||||
|
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` IN (24082, 24083);
|
||||||
|
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||||
|
(13, 1, 24082, 0, 0, 31, 0, 5, 179985, 0, 0, 0, 0, '', 'Hatch Spider Egg targets Spider Egg'),
|
||||||
|
(13, 1, 24083, 0, 0, 31, 0, 5, 179985, 0, 0, 0, 0, '', 'Hatch Eggs targets Spider Egg');
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2022_06_13_05 -> 2022_06_14_00
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id`=24684;
|
||||||
|
INSERT INTO `spell_script_names` VALUES
|
||||||
|
(24684,'spell_chain_burn');
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
-- DB update 2022_06_14_00 -> 2022_06_14_01
|
||||||
|
--
|
||||||
|
ALTER TABLE `gameobject_template_addon`
|
||||||
|
ADD COLUMN `artkit0` INT NOT NULL DEFAULT 0 AFTER `maxgold`,
|
||||||
|
ADD COLUMN `artkit1` INT NOT NULL DEFAULT 0 AFTER `artkit0`,
|
||||||
|
ADD COLUMN `artkit2` INT NOT NULL DEFAULT 0 AFTER `artkit1`,
|
||||||
|
ADD COLUMN `artkit3` INT NOT NULL DEFAULT 0 AFTER `artkit2`;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `gameobjectartkit_dbc`;
|
||||||
|
|
||||||
|
CREATE TABLE `gameobjectartkit_dbc`
|
||||||
|
(
|
||||||
|
`ID` INT NOT NULL DEFAULT 0,
|
||||||
|
`Texture_1` INT NOT NULL DEFAULT 0,
|
||||||
|
`Texture_2` INT NOT NULL DEFAULT 0,
|
||||||
|
`Texture_3` INT NOT NULL DEFAULT 0,
|
||||||
|
`Attach_Model_1` INT NOT NULL DEFAULT 0,
|
||||||
|
`Attach_Model_2` INT NOT NULL DEFAULT 0,
|
||||||
|
`Attach_Model_3` INT NOT NULL DEFAULT 0,
|
||||||
|
`Attach_Model_4` INT NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (`ID`)
|
||||||
|
) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Note: All of these should be targetable by spells 46904 and 46903, but conditions are only set for Stormwind (damn Horde fanatics)
|
||||||
|
UPDATE `gameobject_template_addon` SET `artkit0` = 121, `artkit1` = 122 WHERE `entry` IN (
|
||||||
|
188352, -- Flame of Shattrath
|
||||||
|
188129, -- Flame of Silvermoon
|
||||||
|
188128, -- Flame of the Exodar
|
||||||
|
181567, -- Flame of the Wetlands
|
||||||
|
181566, -- Flame of Hillsbrad
|
||||||
|
181565, -- Flame of Westfall
|
||||||
|
181564, -- Flame of Silverpine
|
||||||
|
181563, -- Flame of Darkshore
|
||||||
|
181562, -- Flame of Stonetalon
|
||||||
|
181561, -- Flame of Ashenvale
|
||||||
|
181560, -- Flame of the Barrens
|
||||||
|
181349, -- Flame of the Scholomance
|
||||||
|
181348, -- Flame of Stratholme
|
||||||
|
181347, -- Flame of Blackrock Spire
|
||||||
|
181346, -- Flame of Dire Maul
|
||||||
|
181345, -- Flame of the Hinterlands
|
||||||
|
181344, -- Flame of the Blasted Lands
|
||||||
|
181343, -- Flame of Un'Goro
|
||||||
|
181342, -- Flame of Azshara
|
||||||
|
181341, -- Flame of Searing Gorge
|
||||||
|
181340, -- Flame of Winterspring
|
||||||
|
181339, -- Flame of Silithus
|
||||||
|
181338, -- Flame of the Plaguelands
|
||||||
|
181337, -- Flame of Thunder Bluff
|
||||||
|
181336, -- Flame of Orgrimmar
|
||||||
|
181335, -- Flame of the Undercity
|
||||||
|
181334, -- Flame of Darnassus
|
||||||
|
181333, -- Flame of Ironforge
|
||||||
|
181332 -- Flame of Stormwind
|
||||||
|
);
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName`= "spell_banging_the_gong";
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
-- DB update 2022_06_14_01 -> 2022_06_14_02
|
||||||
|
--
|
||||||
|
UPDATE `spell_target_position` SET `PositionX`=-11688.5, `PositionY`=-1737.74, `PositionZ`=8.409842 WHERE `id` IN (24325, 24593);
|
||||||
|
DELETE FROM `event_scripts` WHERE `id`=9104;
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id`=24325;
|
||||||
|
INSERT INTO `spell_script_names` VALUES
|
||||||
|
(24325, 'spell_pagles_point_cast');
|
||||||
|
|
||||||
|
DELETE FROM `waypoint_data` WHERE `id`=151140;
|
||||||
|
INSERT INTO `waypoint_data` VALUES
|
||||||
|
(151140,1,-11697.263,-1759.001,10.364448,0,0,0,0,100,0),
|
||||||
|
(151140,2,-11689.899,-1776.087,12.593142,6.098,0,0,0,100,0);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2022_06_14_02 -> 2022_06_14_03
|
||||||
|
-- Update movement for Tarindralla
|
||||||
|
UPDATE `creature` SET `wander_distance` = 7, `MovementType` = 1 WHERE `guid` = 47347 AND `id1` = 1992;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2022_06_14_03 -> 2022_06_14_04
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 1540201) AND (`source_type` = 9) AND (`id` IN (4, 5, 6));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(1540201, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 15958, 4, 15000, 0, 0, 0, 8, 0, 0, 0, 0, 8750.1, -7129.7, 35.2976, 3.8041, 'Apprentice Mirveda - Actionlist - Summon Creature \'Gharsul the Remorseless\''),
|
||||||
|
(1540201, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 15656, 4, 15000, 0, 0, 0, 8, 0, 0, 0, 0, 8753.61, -7133.15, 35, 3.8576, 'Apprentice Mirveda - Actionlist - Summon Creature \'Angershade\''),
|
||||||
|
(1540201, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 12, 15656, 4, 15000, 0, 0, 0, 8, 0, 0, 0, 0, 8747.14, -7125.71, 35.848, 3.8576, 'Apprentice Mirveda - Actionlist - Summon Creature \'Angershade\'');
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- DB update 2022_06_14_04 -> 2022_06_14_05
|
||||||
|
--
|
||||||
|
DELETE FROM `creature_text` WHERE `CreatureID`=15111 AND `GroupID` IN (0,1);
|
||||||
|
INSERT INTO `creature_text` (`CreatureID`, `ID`, `Text`, `Type`, `Probability`, `BroadcastTextId`) VALUES
|
||||||
|
(15111, 0, 'I gonna make you into mojo!', 12, 100, 10435),
|
||||||
|
(15111, 1, 'Troll mojo da strongest mojo!', 12, 100, 10437);
|
||||||
|
|
||||||
|
DELETE FROM `creature_template_spell` WHERE (`CreatureID` = 15111) AND (`Index` IN (0, 1));
|
||||||
|
INSERT INTO `creature_template_spell` (`CreatureID`, `Index`, `Spell`, `VerifiedBuild`) VALUES
|
||||||
|
(15111, 0, 24611, 0),
|
||||||
|
(15111, 1, 24612, 0);
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 15111;
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 15111) AND (`source_type` = 0) AND (`id` IN (3));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(15111, 0, 3, 0, 4, 0, 15, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Mad Servant - On Aggro - Say Line GroupID 0');
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2022_06_14_05 -> 2022_06_14_06
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_group` WHERE `spell_id` IN (8042,20005);
|
||||||
|
INSERT INTO `spell_group` VALUES
|
||||||
|
(1014,8042,0),
|
||||||
|
(1014,20005,0);
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- DB update 2022_06_14_06 -> 2022_06_14_07
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id`=29341;
|
||||||
|
INSERT INTO `spell_script_names` VALUES
|
||||||
|
(29341,'spell_warl_shadowburn');
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
-- DB update 2022_06_14_07 -> 2022_06_14_08
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 4966;
|
||||||
|
DELETE FROM `smart_scripts` WHERE ((`entryorguid` = 496603) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3))) OR ((`entryorguid` = 496600) AND (`source_type` = 9) AND (`id` IN (0, 1, 2, 3, 4, 5, 6))) OR ((`entryorguid` = 5184) AND (`source_type` = 0)) OR (`source_type` = 0 AND `entryorguid` = 4966 AND (`id` IN (0, 1, 2, 3, 4, 5, 6, 7)));
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(4966, 0, 0, 1, 11, 0, 100, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - On Respawn - Set Emote State 0'),
|
||||||
|
(4966, 0, 1, 2, 61, 0, 100, 512, 0, 0, 0, 0, 0, 82, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - On Respawn - Add Npc Flags Questgiver'),
|
||||||
|
(4966, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - On Respawn - Reset Invincibility Hp'),
|
||||||
|
(4966, 0, 3, 0, 19, 0, 100, 512, 1324, 0, 0, 0, 0, 80, 496600, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - On Quest \'The Missing Diplomat\' Taken - Run Script'),
|
||||||
|
(4966, 0, 4, 0, 7, 1, 100, 513, 0, 0, 0, 0, 0, 80, 496603, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - On Evade - Run Script (Phase 1) (No Repeat)'),
|
||||||
|
(4966, 0, 6, 0, 2, 1, 100, 512, 0, 20, 300, 500, 0, 80, 496601, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Between 0-20% Health - Run Script (Phase 1)'),
|
||||||
|
(4966, 0, 7, 0, 40, 2, 100, 512, 1, 496600, 0, 0, 0, 80, 496602, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - On Waypoint 1 Reached - Run Script (Phase 2)'),
|
||||||
|
(496600, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 83, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Remove Npc Flags Questgiver'),
|
||||||
|
(496600, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Set Invincibility Hp 1'),
|
||||||
|
(496600, 9, 2, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 2, 168, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Set Faction 168'),
|
||||||
|
(496600, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 45, 1, 1, 0, 0, 0, 0, 11, 5184, 50, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Set Data 1 1'),
|
||||||
|
(496600, 9, 4, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Store Targetlist'),
|
||||||
|
(496600, 9, 5, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Start Attacking'),
|
||||||
|
(496600, 9, 6, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Set Event Phase 1'),
|
||||||
|
(5184, 0, 0, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 11, 7165, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Theramore Sentry - On Aggro - Cast \'Battle Stance\''),
|
||||||
|
(5184, 0, 1, 0, 38, 0, 100, 513, 3, 3, 1, 2, 0, 41, 60000, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Theramore Sentry - On Data Set 3 3 - Despawn In 60000 ms (No Repeat)'),
|
||||||
|
(496603, 9, 0, 0, 0, 0, 100, 0, 2000, 2000, 0, 0, 0, 41, 1, 300, 0, 0, 0, 0, 19, 5184, 50, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Despawn In 1000 ms'),
|
||||||
|
(496603, 9, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 6, 1324, 0, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Fail Quest \'The Missing Diplomat\''),
|
||||||
|
(496603, 9, 2, 0, 0, 0, 100, 0, 1000, 1000, 0, 0, 0, 41, 1, 300, 0, 0, 0, 0, 19, 5184, 50, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Despawn Instant'),
|
||||||
|
(496603, 9, 3, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 41, 1, 300, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Private Hendel - Actionlist - Despawn Instant');
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2022_06_14_08 -> 2022_06_15_00
|
||||||
|
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_gen_proc_once_per_cast';
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2022_06_15_00 -> 2022_06_15_01
|
||||||
|
-- Adjust drop rate of Ritual salve to 72% (based by a sniffer with 325 kills)
|
||||||
|
UPDATE `creature_loot_template` SET `Chance` = 72 WHERE `Entry` = 2953 AND `Item` = 6634;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2022_06_15_01 -> 2022_06_15_02
|
||||||
|
DELETE FROM `spell_script_names` WHERE `spell_id` = 24834;
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||||
|
(24834, 'spell_shadow_bolt_whirl');
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2022_06_15_02 -> 2022_06_16_00
|
||||||
|
UPDATE `quest_template_addon` SET `RewardMailTemplateID` = 107 WHERE (`ID` = 5237);
|
||||||
|
UPDATE `quest_template_addon` SET `RewardMailTemplateID` = 101 WHERE (`ID` = 5238);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
-- DB update 2022_06_16_00 -> 2022_06_16_01
|
||||||
|
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 16332;
|
||||||
|
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 16332);
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
|
||||||
|
(16332, 0, 0, 1, 1, 0, 100, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Out of Combat - Disable Combat Movement'),
|
||||||
|
(16332, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Out of Combat - Stop Attacking'),
|
||||||
|
(16332, 0, 2, 0, 4, 0, 100, 0, 0, 0, 0, 0, 0, 11, 6660, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - On Aggro - Cast \'Shoot\''),
|
||||||
|
(16332, 0, 3, 4, 9, 0, 100, 0, 5, 30, 2300, 3900, 0, 11, 6660, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 5-30 Range - Cast \'Shoot\''),
|
||||||
|
(16332, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 5-30 Range - Set Sheath Ranged'),
|
||||||
|
(16332, 0, 5, 6, 9, 0, 100, 0, 25, 80, 0, 0, 0, 21, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 25-80 Range - Enable Combat Movement'),
|
||||||
|
(16332, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 25-80 Range - Start Attacking'),
|
||||||
|
(16332, 0, 7, 8, 9, 0, 100, 0, 0, 5, 0, 0, 0, 21, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 0-5 Range - Enable Combat Movement'),
|
||||||
|
(16332, 0, 8, 9, 61, 0, 100, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 0-5 Range - Set Sheath Melee'),
|
||||||
|
(16332, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 0-5 Range - Start Attacking'),
|
||||||
|
(16332, 0, 10, 0, 9, 0, 100, 0, 5, 15, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 5-15 Range - Disable Combat Movement'),
|
||||||
|
(16332, 0, 11, 0, 9, 0, 100, 0, 0, 5, 5000, 9000, 0, 11, 11976, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Within 0-5 Range - Cast \'Strike\''),
|
||||||
|
(16332, 0, 12, 13, 2, 0, 100, 0, 0, 15, 0, 0, 0, 21, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Between 0-15% Health - Enable Combat Movement'),
|
||||||
|
(16332, 0, 13, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - Between 0-15% Health - Flee For Assist'),
|
||||||
|
(16332, 0, 14, 0, 7, 0, 100, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Darnassian Huntress - On Evade - Set Sheath Melee');
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- DB update 2022_06_16_01 -> 2022_06_16_02
|
||||||
|
UPDATE `creature_template` SET `unit_flags` = `unit_flags`&~33554432 WHERE `entry` = 14467;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- DB update 2022_06_16_02 -> 2022_06_16_03
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `unit_flags`=`unit_flags`|33554432,`flags_extra`=`flags_extra`|2 WHERE `entry`=13148;
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- DB update 2022_06_16_03 -> 2022_06_16_04
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 29, `BaseAttackTime` = 1100 WHERE (`entry` = 15114);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 27, `BaseAttackTime` = 1300 WHERE (`entry` = 15083);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 24, `BaseAttackTime` = 2000 WHERE (`entry` = 15085);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 23, `BaseAttackTime` = 1108 WHERE (`entry` = 15084);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 20 WHERE `entry` IN (14834, 15082);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 17 WHERE `entry` IN (11382, 11380);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 15 WHERE `entry` IN (14517, 14515);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 14 WHERE `entry` IN (14510, 14507);
|
||||||
|
UPDATE `creature_template` SET `DamageModifier` = 13 WHERE (`entry` = 14509);
|
||||||
|
UPDATE `creature_template` SET `BaseAttackTime` = 1108 WHERE (`entry` = 15084);
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
-- DB update 2022_06_16_04 -> 2022_06_16_05
|
||||||
|
--
|
||||||
|
DELETE FROM `game_event_gameobject` WHERE `guid`=28704;
|
||||||
|
INSERT INTO `game_event_gameobject` VALUES
|
||||||
|
(27,28704),
|
||||||
|
(28,28704),
|
||||||
|
(29,28704),
|
||||||
|
(30,28704);
|
||||||
|
|
||||||
|
UPDATE `gameobject_template` SET `ScriptName`='go_brazier_of_madness' WHERE `entry`=180327;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- DB update 2022_06_16_05 -> 2022_06_16_06
|
||||||
|
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|4194304 WHERE `entry` = 15261;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- DB update 2022_06_16_06 -> 2022_06_16_07
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `AIName`='SmartAI',`flags_extra`=2 WHERE `entry`=14989;
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid`= 14989 AND `source_type`= 0 AND `id`= 0;
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `event_type`, `event_flags`, `action_type`, `action_param1`, `target_type`, `comment`) VALUES
|
||||||
|
(14989, 54, 1, 11, 26744, 1, 'Poisonous Cloud - OOC - Cast \'Serverside - Poisonous Blood\'');
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid`= 11357 AND `source_type`= 0 AND `id`= 2;
|
||||||
|
INSERT INTO `smart_scripts` (`entryorguid`, `id`, `event_type`, `event_flags`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `target_type`, `comment`) VALUES
|
||||||
|
(11357, 2, 6, 512, 12, 14989, 3, 10000, 1, 'Son of Hakkar - On Just Died - Summon \'Poisonous Cloud\'');
|
||||||
|
|
||||||
@@ -134,14 +134,6 @@ void CreatureAI::DoZoneInCombat(Creature* creature /*= nullptr*/, float maxRange
|
|||||||
{
|
{
|
||||||
creature->AddThreat(player, 0.0f);
|
creature->AddThreat(player, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Causes certain things to never leave the threat list (Priest Lightwell, etc):
|
|
||||||
for (Unit::ControlSet::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr)
|
|
||||||
{
|
|
||||||
creature->SetInCombatWith(*itr);
|
|
||||||
(*itr)->SetInCombatWith(creature);
|
|
||||||
creature->AddThreat(*itr, 0.0f);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +153,7 @@ void CreatureAI::MoveInLineOfSight_Safe(Unit* who)
|
|||||||
|
|
||||||
void CreatureAI::MoveInLineOfSight(Unit* who)
|
void CreatureAI::MoveInLineOfSight(Unit* who)
|
||||||
{
|
{
|
||||||
if (me->GetVictim())
|
if (me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// pussywizard: civilian, non-combat pet or any other NOT HOSTILE TO ANYONE (!)
|
// pussywizard: civilian, non-combat pet or any other NOT HOSTILE TO ANYONE (!)
|
||||||
@@ -182,7 +174,7 @@ void CreatureAI::TriggerAlert(Unit const* who) const
|
|||||||
if (!who || who->GetTypeId() != TYPEID_PLAYER)
|
if (!who || who->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
// If this unit isn't an NPC, is already distracted, is in combat, is confused, stunned or fleeing, do nothing
|
// If this unit isn't an NPC, is already distracted, is in combat, is confused, stunned or fleeing, do nothing
|
||||||
if (me->GetTypeId() != TYPEID_UNIT || me->IsInCombat() || me->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED))
|
if (me->GetTypeId() != TYPEID_UNIT || me->IsEngaged() || me->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING | UNIT_STATE_DISTRACTED))
|
||||||
return;
|
return;
|
||||||
// Only alert for hostiles!
|
// Only alert for hostiles!
|
||||||
if (me->IsCivilian() || me->HasReactState(REACT_PASSIVE) || !me->IsHostileTo(who) || !me->_IsTargetAcceptable(who))
|
if (me->IsCivilian() || me->HasReactState(REACT_PASSIVE) || !me->IsHostileTo(who) || !me->_IsTargetAcceptable(who))
|
||||||
@@ -253,7 +245,7 @@ void CreatureAI::SetGazeOn(Unit* target)
|
|||||||
|
|
||||||
bool CreatureAI::UpdateVictimWithGaze()
|
bool CreatureAI::UpdateVictimWithGaze()
|
||||||
{
|
{
|
||||||
if (!me->IsInCombat())
|
if (!me->IsEngaged())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (me->HasReactState(REACT_PASSIVE))
|
if (me->HasReactState(REACT_PASSIVE))
|
||||||
@@ -271,7 +263,7 @@ bool CreatureAI::UpdateVictimWithGaze()
|
|||||||
|
|
||||||
bool CreatureAI::UpdateVictim()
|
bool CreatureAI::UpdateVictim()
|
||||||
{
|
{
|
||||||
if (!me->IsInCombat())
|
if (!me->IsEngaged())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!me->HasReactState(REACT_PASSIVE))
|
if (!me->HasReactState(REACT_PASSIVE))
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public:
|
|||||||
// Called for reaction at stopping attack at no attackers or targets
|
// Called for reaction at stopping attack at no attackers or targets
|
||||||
virtual void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER);
|
virtual void EnterEvadeMode(EvadeReason why = EVADE_REASON_OTHER);
|
||||||
|
|
||||||
// Called for reaction at enter to combat if not in combat yet (enemy can be nullptr)
|
// Called for reaction when initially engaged
|
||||||
virtual void EnterCombat(Unit* /*victim*/) {}
|
virtual void EnterCombat(Unit* /*victim*/) {}
|
||||||
|
|
||||||
// Called when the creature is killed
|
// Called when the creature is killed
|
||||||
@@ -196,6 +196,7 @@ public:
|
|||||||
virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }
|
virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }
|
||||||
|
|
||||||
virtual bool CanBeSeen(Player const* /*seer*/) { return true; }
|
virtual bool CanBeSeen(Player const* /*seer*/) { return true; }
|
||||||
|
virtual bool CanAlwaysBeDetectable(WorldObject const* /*seer*/) { return false; }
|
||||||
|
|
||||||
virtual void PetStopAttack() { }
|
virtual void PetStopAttack() { }
|
||||||
|
|
||||||
|
|||||||
@@ -574,7 +574,7 @@ void BossAI::TeleportCheaters()
|
|||||||
void BossAI::JustSummoned(Creature* summon)
|
void BossAI::JustSummoned(Creature* summon)
|
||||||
{
|
{
|
||||||
summons.Summon(summon);
|
summons.Summon(summon);
|
||||||
if (me->IsInCombat())
|
if (me->IsEngaged())
|
||||||
DoZoneInCombat(summon);
|
DoZoneInCombat(summon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4044,18 +4044,18 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax);
|
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax);
|
||||||
break;
|
break;
|
||||||
case SMART_EVENT_UPDATE_OOC:
|
case SMART_EVENT_UPDATE_OOC:
|
||||||
if (me && me->IsInCombat())
|
if (me && me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax);
|
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax);
|
||||||
break;
|
break;
|
||||||
case SMART_EVENT_UPDATE_IC:
|
case SMART_EVENT_UPDATE_IC:
|
||||||
if (!me || !me->IsInCombat())
|
if (!me || !me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax);
|
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax);
|
||||||
break;
|
break;
|
||||||
case SMART_EVENT_HEALTH_PCT:
|
case SMART_EVENT_HEALTH_PCT:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat() || !me->GetMaxHealth())
|
if (!me || !me->IsEngaged() || !me->GetMaxHealth())
|
||||||
return;
|
return;
|
||||||
uint32 perc = (uint32)me->GetHealthPct();
|
uint32 perc = (uint32)me->GetHealthPct();
|
||||||
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
||||||
@@ -4065,7 +4065,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_TARGET_HEALTH_PCT:
|
case SMART_EVENT_TARGET_HEALTH_PCT:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxHealth())
|
if (!me || !me->IsEngaged() || !me->GetVictim() || !me->GetVictim()->GetMaxHealth())
|
||||||
return;
|
return;
|
||||||
uint32 perc = (uint32)me->GetVictim()->GetHealthPct();
|
uint32 perc = (uint32)me->GetVictim()->GetHealthPct();
|
||||||
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
||||||
@@ -4075,7 +4075,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_MANA_PCT:
|
case SMART_EVENT_MANA_PCT:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat() || !me->GetMaxPower(POWER_MANA))
|
if (!me || !me->IsEngaged() || !me->GetMaxPower(POWER_MANA))
|
||||||
return;
|
return;
|
||||||
uint32 perc = uint32(me->GetPowerPct(POWER_MANA));
|
uint32 perc = uint32(me->GetPowerPct(POWER_MANA));
|
||||||
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
||||||
@@ -4085,7 +4085,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_TARGET_MANA_PCT:
|
case SMART_EVENT_TARGET_MANA_PCT:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxPower(POWER_MANA))
|
if (!me || !me->IsEngaged() || !me->GetVictim() || !me->GetVictim()->GetMaxPower(POWER_MANA))
|
||||||
return;
|
return;
|
||||||
uint32 perc = uint32(me->GetVictim()->GetPowerPct(POWER_MANA));
|
uint32 perc = uint32(me->GetVictim()->GetPowerPct(POWER_MANA));
|
||||||
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min)
|
||||||
@@ -4095,7 +4095,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_RANGE:
|
case SMART_EVENT_RANGE:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat() || !me->GetVictim())
|
if (!me || !me->IsEngaged() || !me->GetVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max))
|
if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max))
|
||||||
@@ -4106,7 +4106,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_VICTIM_CASTING:
|
case SMART_EVENT_VICTIM_CASTING:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat())
|
if (!me || !me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit* victim = me->GetVictim();
|
Unit* victim = me->GetVictim();
|
||||||
@@ -4124,7 +4124,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_FRIENDLY_HEALTH:
|
case SMART_EVENT_FRIENDLY_HEALTH:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat())
|
if (!me || !me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealth.radius, e.event.friendlyHealth.hpDeficit);
|
Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealth.radius, e.event.friendlyHealth.hpDeficit);
|
||||||
@@ -4139,7 +4139,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_FRIENDLY_IS_CC:
|
case SMART_EVENT_FRIENDLY_IS_CC:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat())
|
if (!me || !me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::list<Creature*> pList;
|
std::list<Creature*> pList;
|
||||||
@@ -4285,7 +4285,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_OOC_LOS:
|
case SMART_EVENT_OOC_LOS:
|
||||||
{
|
{
|
||||||
if (!me || me->IsInCombat())
|
if (!me || me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
//can trigger if closer than fMaxAllowedRange
|
//can trigger if closer than fMaxAllowedRange
|
||||||
float range = (float)e.event.los.maxDist;
|
float range = (float)e.event.los.maxDist;
|
||||||
@@ -4309,7 +4309,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_IC_LOS:
|
case SMART_EVENT_IC_LOS:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat())
|
if (!me || !me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
//can trigger if closer than fMaxAllowedRange
|
//can trigger if closer than fMaxAllowedRange
|
||||||
float range = (float)e.event.los.maxDist;
|
float range = (float)e.event.los.maxDist;
|
||||||
@@ -4507,7 +4507,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
}
|
}
|
||||||
case SMART_EVENT_FRIENDLY_HEALTH_PCT:
|
case SMART_EVENT_FRIENDLY_HEALTH_PCT:
|
||||||
{
|
{
|
||||||
if (!me || !me->IsInCombat())
|
if (!me || !me->IsEngaged())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit* target = nullptr;
|
Unit* target = nullptr;
|
||||||
@@ -4701,10 +4701,10 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
|
|||||||
if (e.event.event_phase_mask && !IsInPhase(e.event.event_phase_mask))
|
if (e.event.event_phase_mask && !IsInPhase(e.event.event_phase_mask))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e.GetEventType() == SMART_EVENT_UPDATE_IC && (!me || !me->IsInCombat()))
|
if (e.GetEventType() == SMART_EVENT_UPDATE_IC && (!me || !me->IsEngaged()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e.GetEventType() == SMART_EVENT_UPDATE_OOC && (me && me->IsInCombat()))//can be used with me=nullptr (go script)
|
if (e.GetEventType() == SMART_EVENT_UPDATE_OOC && (me && me->IsEngaged()))//can be used with me=nullptr (go script)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (e.timer < diff)
|
if (e.timer < diff)
|
||||||
@@ -4982,7 +4982,7 @@ void SmartScript::OnMoveInLineOfSight(Unit* who)
|
|||||||
if (!me)
|
if (!me)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ProcessEventsFor(me->IsInCombat() ? SMART_EVENT_IC_LOS : SMART_EVENT_OOC_LOS, who);
|
ProcessEventsFor(me->IsEngaged() ? SMART_EVENT_IC_LOS : SMART_EVENT_OOC_LOS, who);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ static FactionTeamMap sFactionTeamMap;
|
|||||||
DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
|
DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
|
||||||
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
|
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
|
||||||
|
|
||||||
|
DBCStorage <GameObjectArtKitEntry> sGameObjectArtKitStore(GameObjectArtKitfmt);
|
||||||
|
|
||||||
DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt);
|
DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt);
|
||||||
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
|
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
|
||||||
DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
|
DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
|
||||||
@@ -306,6 +308,7 @@ void LoadDBCStores(const std::string& dataPath)
|
|||||||
LOAD_DBC(sEmotesTextSoundStore, "EmotesTextSound.dbc", "emotetextsound_dbc");
|
LOAD_DBC(sEmotesTextSoundStore, "EmotesTextSound.dbc", "emotetextsound_dbc");
|
||||||
LOAD_DBC(sFactionStore, "Faction.dbc", "faction_dbc");
|
LOAD_DBC(sFactionStore, "Faction.dbc", "faction_dbc");
|
||||||
LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc", "factiontemplate_dbc");
|
LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc", "factiontemplate_dbc");
|
||||||
|
LOAD_DBC(sGameObjectArtKitStore, "GameObjectArtKit.dbc", "gameobjectartkit_dbc");
|
||||||
LOAD_DBC(sGameObjectDisplayInfoStore, "GameObjectDisplayInfo.dbc", "gameobjectdisplayinfo_dbc");
|
LOAD_DBC(sGameObjectDisplayInfoStore, "GameObjectDisplayInfo.dbc", "gameobjectdisplayinfo_dbc");
|
||||||
LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc", "gemproperties_dbc");
|
LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc", "gemproperties_dbc");
|
||||||
LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc", "glyphproperties_dbc");
|
LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc", "glyphproperties_dbc");
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ extern DBCStorage <EmotesTextEntry> sEmotesTextStore;
|
|||||||
extern DBCStorage <EmotesTextSoundEntry> sEmotesTextSoundStore;
|
extern DBCStorage <EmotesTextSoundEntry> sEmotesTextSoundStore;
|
||||||
extern DBCStorage <FactionEntry> sFactionStore;
|
extern DBCStorage <FactionEntry> sFactionStore;
|
||||||
extern DBCStorage <FactionTemplateEntry> sFactionTemplateStore;
|
extern DBCStorage <FactionTemplateEntry> sFactionTemplateStore;
|
||||||
|
extern DBCStorage <GameObjectArtKitEntry> sGameObjectArtKitStore;
|
||||||
extern DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore;
|
extern DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore;
|
||||||
extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
|
extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
|
||||||
extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
|
extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
|
||||||
|
|||||||
@@ -704,7 +704,7 @@ void Creature::Update(uint32 diff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// periodic check to see if the creature has passed an evade boundary
|
// periodic check to see if the creature has passed an evade boundary
|
||||||
if (IsAIEnabled && !IsInEvadeMode() && IsInCombat())
|
if (IsAIEnabled && !IsInEvadeMode() && IsEngaged())
|
||||||
{
|
{
|
||||||
if (diff >= m_boundaryCheckTime)
|
if (diff >= m_boundaryCheckTime)
|
||||||
{
|
{
|
||||||
@@ -1810,6 +1810,21 @@ bool Creature::CanAlwaysSee(WorldObject const* obj) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Creature::IsAlwaysDetectableFor(WorldObject const* seer) const
|
||||||
|
{
|
||||||
|
if (Unit::IsAlwaysDetectableFor(seer))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAIEnabled && AI()->CanAlwaysBeDetectable(seer))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Creature::CanStartAttack(Unit const* who) const
|
bool Creature::CanStartAttack(Unit const* who) const
|
||||||
{
|
{
|
||||||
if (IsCivilian())
|
if (IsCivilian())
|
||||||
@@ -1839,7 +1854,7 @@ bool Creature::CanStartAttack(Unit const* who) const
|
|||||||
// pussywizard: at this point we are either hostile to who or friendly to who->getAttackerForHelper()
|
// pussywizard: at this point we are either hostile to who or friendly to who->getAttackerForHelper()
|
||||||
// pussywizard: if who is in combat and has an attacker, help him if the distance is right (help because who is hostile or help because attacker is friendly)
|
// pussywizard: if who is in combat and has an attacker, help him if the distance is right (help because who is hostile or help because attacker is friendly)
|
||||||
bool assist = false;
|
bool assist = false;
|
||||||
if (who->IsInCombat() && IsWithinDist(who, ATTACK_DISTANCE))
|
if (who->IsEngaged() && IsWithinDist(who, ATTACK_DISTANCE))
|
||||||
if (Unit* victim = who->getAttackerForHelper())
|
if (Unit* victim = who->getAttackerForHelper())
|
||||||
if (IsWithinDistInMap(victim, sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS)))
|
if (IsWithinDistInMap(victim, sWorld->getFloatConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS)))
|
||||||
assist = true;
|
assist = true;
|
||||||
@@ -2358,7 +2373,7 @@ bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// skip fighting creature
|
// skip fighting creature
|
||||||
if (IsInCombat())
|
if (IsEngaged())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// only free creature
|
// only free creature
|
||||||
@@ -2409,11 +2424,10 @@ bool Creature::_IsTargetAcceptable(Unit const* target) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit const* myVictim = getAttackerForHelper();
|
|
||||||
Unit const* targetVictim = target->getAttackerForHelper();
|
Unit const* targetVictim = target->getAttackerForHelper();
|
||||||
|
|
||||||
// if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
|
// if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
|
||||||
if (myVictim == target || targetVictim == this || IsHostileTo(target))
|
if (IsEngagedBy(target) || IsHostileTo(target))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// if the target's victim is friendly, and the target is neutral, the target is acceptable
|
// if the target's victim is friendly, and the target is neutral, the target is acceptable
|
||||||
|
|||||||
@@ -443,6 +443,7 @@ protected:
|
|||||||
|
|
||||||
[[nodiscard]] bool IsInvisibleDueToDespawn() const override;
|
[[nodiscard]] bool IsInvisibleDueToDespawn() const override;
|
||||||
bool CanAlwaysSee(WorldObject const* obj) const override;
|
bool CanAlwaysSee(WorldObject const* obj) const override;
|
||||||
|
bool IsAlwaysDetectableFor(WorldObject const* seer) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ForcedDespawn(uint32 timeMSToDespawn = 0, Seconds forcedRespawnTimer = 0s);
|
void ForcedDespawn(uint32 timeMSToDespawn = 0, Seconds forcedRespawnTimer = 0s);
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ void CreatureGroup::RemoveMember(Creature* member)
|
|||||||
member->SetFormation(nullptr);
|
member->SetFormation(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureGroup::MemberAttackStart(Creature* member, Unit* target)
|
void CreatureGroup::MemberEngagingTarget(Creature* member, Unit* target)
|
||||||
{
|
{
|
||||||
uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
|
uint8 const groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()].groupAI;
|
||||||
if (member == m_leader)
|
if (member == m_leader)
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public:
|
|||||||
void FormationReset(bool dismiss, bool initMotionMaster);
|
void FormationReset(bool dismiss, bool initMotionMaster);
|
||||||
|
|
||||||
void LeaderMoveTo(float x, float y, float z, bool run);
|
void LeaderMoveTo(float x, float y, float z, bool run);
|
||||||
void MemberAttackStart(Creature* member, Unit* target);
|
void MemberEngagingTarget(Creature* member, Unit* target);
|
||||||
void MemberEvaded(Creature* member);
|
void MemberEvaded(Creature* member);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
class GameObjectAI;
|
class GameObjectAI;
|
||||||
class Transport;
|
class Transport;
|
||||||
@@ -676,6 +677,7 @@ struct GameObjectTemplateAddon
|
|||||||
uint32 flags;
|
uint32 flags;
|
||||||
uint32 mingold;
|
uint32 mingold;
|
||||||
uint32 maxgold;
|
uint32 maxgold;
|
||||||
|
std::array<uint32, 4> artKits = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Benchmarked: Faster than std::map (insert/find)
|
// Benchmarked: Faster than std::map (insert/find)
|
||||||
@@ -736,6 +738,35 @@ enum GOState
|
|||||||
|
|
||||||
#define MAX_GO_STATE 3
|
#define MAX_GO_STATE 3
|
||||||
|
|
||||||
|
enum class GameObjectActions : uint32
|
||||||
|
{
|
||||||
|
// Name from client executable // Comments
|
||||||
|
None, // -NONE-
|
||||||
|
AnimateCustom0, // Animate Custom0
|
||||||
|
AnimateCustom1, // Animate Custom1
|
||||||
|
AnimateCustom2, // Animate Custom2
|
||||||
|
AnimateCustom3, // Animate Custom3
|
||||||
|
Disturb, // Disturb // Triggers trap
|
||||||
|
Unlock, // Unlock // Resets GO_FLAG_LOCKED
|
||||||
|
Lock, // Lock // Sets GO_FLAG_LOCKED
|
||||||
|
Open, // Open // Sets GO_STATE_ACTIVE
|
||||||
|
OpenAndUnlock, // Open + Unlock // Sets GO_STATE_ACTIVE and resets GO_FLAG_LOCKED
|
||||||
|
Close, // Close // Sets GO_STATE_READY
|
||||||
|
ToggleOpen, // Toggle Open
|
||||||
|
Destroy, // Destroy // Sets GO_STATE_DESTROYED
|
||||||
|
Rebuild, // Rebuild // Resets from GO_STATE_DESTROYED
|
||||||
|
Creation, // Creation
|
||||||
|
Despawn, // Despawn
|
||||||
|
MakeInert, // Make Inert // Disables interactions
|
||||||
|
MakeActive, // Make Active // Enables interactions
|
||||||
|
CloseAndLock, // Close + Lock // Sets GO_STATE_READY and sets GO_FLAG_LOCKED
|
||||||
|
UseArtKit0, // Use ArtKit0 // 46904: 121
|
||||||
|
UseArtKit1, // Use ArtKit1 // 36639: 81, 46903: 122
|
||||||
|
UseArtKit2, // Use ArtKit2
|
||||||
|
UseArtKit3, // Use ArtKit3
|
||||||
|
SetTapList, // Set Tap List
|
||||||
|
};
|
||||||
|
|
||||||
// from `gameobject`
|
// from `gameobject`
|
||||||
struct GameObjectData
|
struct GameObjectData
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ void Totem::InitStats(uint32 duration)
|
|||||||
|
|
||||||
void Totem::InitSummon()
|
void Totem::InitSummon()
|
||||||
{
|
{
|
||||||
|
Minion::InitSummon();
|
||||||
|
|
||||||
if (m_type == TOTEM_PASSIVE && GetSpell())
|
if (m_type == TOTEM_PASSIVE && GetSpell())
|
||||||
CastSpell(this, GetSpell(), true);
|
CastSpell(this, GetSpell(), true);
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,8 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
|||||||
|
|
||||||
_oldFactionId = 0;
|
_oldFactionId = 0;
|
||||||
|
|
||||||
|
_isWalkingBeforeCharm = false;
|
||||||
|
|
||||||
_lastExtraAttackSpell = 0;
|
_lastExtraAttackSpell = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10482,8 +10484,12 @@ void Unit::SetCharm(Unit* charm, bool apply)
|
|||||||
if (!charm->AddGuidValue(UNIT_FIELD_CHARMEDBY, GetGUID()))
|
if (!charm->AddGuidValue(UNIT_FIELD_CHARMEDBY, GetGUID()))
|
||||||
LOG_FATAL("entities.unit", "Unit {} is being charmed, but it already has a charmer {}", charm->GetEntry(), charm->GetCharmerGUID().ToString());
|
LOG_FATAL("entities.unit", "Unit {} is being charmed, but it already has a charmer {}", charm->GetEntry(), charm->GetCharmerGUID().ToString());
|
||||||
|
|
||||||
if (charm->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
|
_isWalkingBeforeCharm = charm->IsWalking();
|
||||||
|
if (_isWalkingBeforeCharm)
|
||||||
|
{
|
||||||
charm->SetWalk(false);
|
charm->SetWalk(false);
|
||||||
|
charm->SendMovementFlagUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
m_Controlled.insert(charm);
|
m_Controlled.insert(charm);
|
||||||
}
|
}
|
||||||
@@ -10521,6 +10527,12 @@ void Unit::SetCharm(Unit* charm, bool apply)
|
|||||||
charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0);
|
charm->SetByteValue(UNIT_FIELD_BYTES_2, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (charm->IsWalking() != _isWalkingBeforeCharm)
|
||||||
|
{
|
||||||
|
charm->SetWalk(_isWalkingBeforeCharm);
|
||||||
|
charm->SendMovementFlagUpdate(true); // send packet to self, to update movement state on player.
|
||||||
|
}
|
||||||
|
|
||||||
m_Controlled.erase(charm);
|
m_Controlled.erase(charm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13168,7 +13180,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy, uint32 duration)
|
|||||||
creature->AI()->EnterCombat(enemy);
|
creature->AI()->EnterCombat(enemy);
|
||||||
|
|
||||||
if (creature->GetFormation())
|
if (creature->GetFormation())
|
||||||
creature->GetFormation()->MemberAttackStart(creature, enemy);
|
creature->GetFormation()->MemberEngagingTarget(creature, enemy);
|
||||||
}
|
}
|
||||||
|
|
||||||
creature->RefreshSwimmingFlag();
|
creature->RefreshSwimmingFlag();
|
||||||
|
|||||||
@@ -1326,6 +1326,7 @@ public:
|
|||||||
bool IsWithinCombatRange(Unit const* obj, float dist2compare) const;
|
bool IsWithinCombatRange(Unit const* obj, float dist2compare) const;
|
||||||
bool IsWithinMeleeRange(Unit const* obj, float dist = 0.f) const;
|
bool IsWithinMeleeRange(Unit const* obj, float dist = 0.f) const;
|
||||||
float GetMeleeRange(Unit const* target) const;
|
float GetMeleeRange(Unit const* target) const;
|
||||||
|
[[nodiscard]] virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
|
||||||
bool GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, bool force = false) const;
|
bool GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, bool force = false) const;
|
||||||
uint32 m_extraAttacks;
|
uint32 m_extraAttacks;
|
||||||
bool m_canDualWield;
|
bool m_canDualWield;
|
||||||
@@ -1343,6 +1344,9 @@ public:
|
|||||||
if (GetVictim() != nullptr)
|
if (GetVictim() != nullptr)
|
||||||
return GetVictim();
|
return GetVictim();
|
||||||
|
|
||||||
|
if (!IsEngaged())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (!m_attackers.empty())
|
if (!m_attackers.empty())
|
||||||
return *(m_attackers.begin());
|
return *(m_attackers.begin());
|
||||||
|
|
||||||
@@ -1644,6 +1648,9 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); }
|
[[nodiscard]] bool IsInFlight() const { return HasUnitState(UNIT_STATE_IN_FLIGHT); }
|
||||||
|
|
||||||
|
bool IsEngaged() const { return IsInCombat(); }
|
||||||
|
bool IsEngagedBy(Unit const* who) const { return IsInCombatWith(who); }
|
||||||
|
|
||||||
[[nodiscard]] bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); }
|
[[nodiscard]] bool IsInCombat() const { return HasUnitFlag(UNIT_FLAG_IN_COMBAT); }
|
||||||
bool IsInCombatWith(Unit const* who) const;
|
bool IsInCombatWith(Unit const* who) const;
|
||||||
|
|
||||||
@@ -2105,6 +2112,7 @@ public:
|
|||||||
void TauntApply(Unit* victim);
|
void TauntApply(Unit* victim);
|
||||||
void TauntFadeOut(Unit* taunter);
|
void TauntFadeOut(Unit* taunter);
|
||||||
ThreatMgr& GetThreatMgr() { return m_ThreatMgr; }
|
ThreatMgr& GetThreatMgr() { return m_ThreatMgr; }
|
||||||
|
ThreatMgr const& GetThreatMgr() const { return m_ThreatMgr; }
|
||||||
void addHatedBy(HostileReference* pHostileReference) { m_HostileRefMgr.insertFirst(pHostileReference); };
|
void addHatedBy(HostileReference* pHostileReference) { m_HostileRefMgr.insertFirst(pHostileReference); };
|
||||||
void removeHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ }
|
void removeHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ }
|
||||||
HostileRefMgr& getHostileRefMgr() { return m_HostileRefMgr; }
|
HostileRefMgr& getHostileRefMgr() { return m_HostileRefMgr; }
|
||||||
@@ -2478,8 +2486,6 @@ protected:
|
|||||||
CharmInfo* m_charmInfo;
|
CharmInfo* m_charmInfo;
|
||||||
SharedVisionList m_sharedVision;
|
SharedVisionList m_sharedVision;
|
||||||
|
|
||||||
[[nodiscard]] virtual SpellSchoolMask GetMeleeDamageSchoolMask() const;
|
|
||||||
|
|
||||||
MotionMaster* i_motionMaster;
|
MotionMaster* i_motionMaster;
|
||||||
|
|
||||||
uint32 m_reactiveTimer[MAX_REACTIVE];
|
uint32 m_reactiveTimer[MAX_REACTIVE];
|
||||||
@@ -2549,6 +2555,7 @@ private:
|
|||||||
bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world
|
bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world
|
||||||
|
|
||||||
uint32 _oldFactionId; ///< faction before charm
|
uint32 _oldFactionId; ///< faction before charm
|
||||||
|
bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed?
|
||||||
|
|
||||||
[[nodiscard]] float processDummyAuras(float TakenTotalMod) const;
|
[[nodiscard]] float processDummyAuras(float TakenTotalMod) const;
|
||||||
|
|
||||||
|
|||||||
@@ -7183,8 +7183,8 @@ void ObjectMgr::LoadGameObjectTemplateAddons()
|
|||||||
{
|
{
|
||||||
uint32 oldMSTime = getMSTime();
|
uint32 oldMSTime = getMSTime();
|
||||||
|
|
||||||
// 0 1 2 3 4
|
// 0 1 2 3 4 5 6 7 8
|
||||||
QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold FROM gameobject_template_addon");
|
QueryResult result = WorldDatabase.Query("SELECT entry, faction, flags, mingold, maxgold, artkit0, artkit1, artkit2, artkit3 FROM gameobject_template_addon");
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
@@ -7215,6 +7215,21 @@ void ObjectMgr::LoadGameObjectTemplateAddons()
|
|||||||
gameObjectAddon.mingold = fields[3].Get<uint32>();
|
gameObjectAddon.mingold = fields[3].Get<uint32>();
|
||||||
gameObjectAddon.maxgold = fields[4].Get<uint32>();
|
gameObjectAddon.maxgold = fields[4].Get<uint32>();
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < gameObjectAddon.artKits.size(); i++)
|
||||||
|
{
|
||||||
|
uint32 artKitID = fields[5 + i].Get<uint32>();
|
||||||
|
if (!artKitID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!sGameObjectArtKitStore.LookupEntry(artKitID))
|
||||||
|
{
|
||||||
|
LOG_ERROR("sql.sql", "GameObject (Entry: {}) has invalid `artkit{}` {} defined, set to zero instead.", entry, i, artKitID);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gameObjectAddon.artKits[i] = artKitID;
|
||||||
|
}
|
||||||
|
|
||||||
// checks
|
// checks
|
||||||
if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
|
if (gameObjectAddon.faction && !sFactionTemplateStore.LookupEntry(gameObjectAddon.faction))
|
||||||
LOG_ERROR("sql.sql",
|
LOG_ERROR("sql.sql",
|
||||||
|
|||||||
@@ -2677,7 +2677,7 @@ void Spell::EffectDistract(SpellEffIndex /*effIndex*/)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Check for possible target
|
// Check for possible target
|
||||||
if (!unitTarget || unitTarget->IsInCombat())
|
if (!unitTarget || unitTarget->IsEngaged())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// target must be OK to do this
|
// target must be OK to do this
|
||||||
@@ -4263,7 +4263,7 @@ void Spell::EffectSummonPlayer(SpellEffIndex /*effIndex*/)
|
|||||||
player->GetSession()->SendPacket(&data);
|
player->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/)
|
void Spell::EffectActivateObject(SpellEffIndex effIndex)
|
||||||
{
|
{
|
||||||
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
|
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
|
||||||
return;
|
return;
|
||||||
@@ -4271,17 +4271,74 @@ void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/)
|
|||||||
if (!gameObjTarget)
|
if (!gameObjTarget)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player* player = m_caster->GetTypeId() == TYPEID_PLAYER ? m_caster->ToPlayer() : m_caster->GetCharmerOrOwnerPlayerOrPlayerItself();
|
GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
|
||||||
gameObjTarget->Use(player ? player : m_caster);
|
switch (action)
|
||||||
|
{
|
||||||
|
case GameObjectActions::AnimateCustom0:
|
||||||
|
case GameObjectActions::AnimateCustom1:
|
||||||
|
case GameObjectActions::AnimateCustom2:
|
||||||
|
case GameObjectActions::AnimateCustom3:
|
||||||
|
gameObjTarget->SendCustomAnim(uint32(action) - uint32(GameObjectActions::AnimateCustom0));
|
||||||
|
break;
|
||||||
|
case GameObjectActions::Disturb: // What's the difference with Open?
|
||||||
|
case GameObjectActions::Open:
|
||||||
|
if (Unit* unitCaster = m_caster->ToUnit())
|
||||||
|
gameObjTarget->Use(unitCaster);
|
||||||
|
break;
|
||||||
|
case GameObjectActions::OpenAndUnlock:
|
||||||
|
if (Unit* unitCaster = m_caster->ToUnit())
|
||||||
|
gameObjTarget->UseDoorOrButton(0, false, unitCaster);
|
||||||
|
[[fallthrough]];
|
||||||
|
case GameObjectActions::Unlock:
|
||||||
|
case GameObjectActions::Lock:
|
||||||
|
gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED, action == GameObjectActions::Lock);
|
||||||
|
break;
|
||||||
|
case GameObjectActions::Close:
|
||||||
|
case GameObjectActions::Rebuild:
|
||||||
|
gameObjTarget->ResetDoorOrButton();
|
||||||
|
break;
|
||||||
|
case GameObjectActions::Despawn:
|
||||||
|
gameObjTarget->DespawnOrUnsummon();
|
||||||
|
break;
|
||||||
|
case GameObjectActions::MakeInert:
|
||||||
|
case GameObjectActions::MakeActive:
|
||||||
|
gameObjTarget->ApplyModFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE, action == GameObjectActions::MakeInert);
|
||||||
|
break;
|
||||||
|
case GameObjectActions::CloseAndLock:
|
||||||
|
gameObjTarget->ResetDoorOrButton();
|
||||||
|
gameObjTarget->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
||||||
|
break;
|
||||||
|
case GameObjectActions::Destroy:
|
||||||
|
if (Unit* unitCaster = m_caster->ToUnit())
|
||||||
|
gameObjTarget->UseDoorOrButton(0, true, unitCaster);
|
||||||
|
break;
|
||||||
|
case GameObjectActions::UseArtKit0:
|
||||||
|
case GameObjectActions::UseArtKit1:
|
||||||
|
case GameObjectActions::UseArtKit2:
|
||||||
|
case GameObjectActions::UseArtKit3:
|
||||||
|
{
|
||||||
|
GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
|
||||||
|
|
||||||
//ScriptInfo activateCommand;
|
uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
|
||||||
//activateCommand.command = SCRIPT_COMMAND_ACTIVATE_OBJECT;
|
|
||||||
|
|
||||||
// int32 unk = m_spellInfo->Effects[effIndex].MiscValue; // This is set for EffectActivateObject spells; needs research
|
uint32 artKitValue = 0;
|
||||||
|
if (templateAddon)
|
||||||
|
artKitValue = templateAddon->artKits[artKitIndex];
|
||||||
|
|
||||||
// xinef: pass player to allow gossip scripts to work
|
if (artKitValue == 0)
|
||||||
//
|
LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
|
||||||
//gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, 0, player ? player : m_caster, gameObjTarget);
|
else
|
||||||
|
gameObjTarget->SetGoArtKit(artKitValue);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GameObjectActions::None:
|
||||||
|
LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
|
void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ struct boss_priestess_lackey_commonAI : public ScriptedAI
|
|||||||
void EnterCombat(Unit* who) override
|
void EnterCombat(Unit* who) override
|
||||||
{
|
{
|
||||||
if (Creature* delrissa = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_DELRISSA)))
|
if (Creature* delrissa = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_DELRISSA)))
|
||||||
if (delrissa->IsAlive() && !delrissa->IsInCombat())
|
if (delrissa->IsAlive() && !delrissa->IsEngaged())
|
||||||
delrissa->AI()->AttackStart(who);
|
delrissa->AI()->AttackStart(who);
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_HELPER_HEALING_POTION, 1000);
|
events.ScheduleEvent(EVENT_SPELL_HELPER_HEALING_POTION, 1000);
|
||||||
|
|||||||
@@ -783,37 +783,9 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class spell_banging_the_gong : public SpellScriptLoader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
spell_banging_the_gong() : SpellScriptLoader("spell_banging_the_gong") { }
|
|
||||||
|
|
||||||
class spell_banging_the_gong_SpellScript : public SpellScript
|
|
||||||
{
|
|
||||||
PrepareSpellScript(spell_banging_the_gong_SpellScript);
|
|
||||||
|
|
||||||
void Activate(SpellEffIndex index)
|
|
||||||
{
|
|
||||||
PreventHitDefaultEffect(index);
|
|
||||||
GetHitGObj()->SendCustomAnim(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Register() override
|
|
||||||
{
|
|
||||||
OnEffectHitTarget += SpellEffectFn(spell_banging_the_gong_SpellScript::Activate, EFFECT_1, SPELL_EFFECT_ACTIVATE_OBJECT);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SpellScript* GetSpellScript() const override
|
|
||||||
{
|
|
||||||
return new spell_banging_the_gong_SpellScript();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddSC_zulaman()
|
void AddSC_zulaman()
|
||||||
{
|
{
|
||||||
new npc_forest_frog();
|
new npc_forest_frog();
|
||||||
new npc_zulaman_hostage();
|
new npc_zulaman_hostage();
|
||||||
new npc_harrison_jones();
|
new npc_harrison_jones();
|
||||||
new spell_banging_the_gong();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ enum Spells
|
|||||||
SPELL_FROSTBREATH = 16099,
|
SPELL_FROSTBREATH = 16099,
|
||||||
SPELL_MASSIVEGEYSER = 22421,
|
SPELL_MASSIVEGEYSER = 22421,
|
||||||
SPELL_SLAM = 24326,
|
SPELL_SLAM = 24326,
|
||||||
SPELL_THRASH = 3417 // Triggers 3391
|
SPELL_THRASH = 3417, // Triggers 3391
|
||||||
|
SPELL_SPLASH = 24593
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Events
|
enum Events
|
||||||
@@ -42,6 +43,11 @@ enum Events
|
|||||||
EVENT_SLAM = 3
|
EVENT_SLAM = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Misc
|
||||||
|
{
|
||||||
|
GAMEOBJECT_MUDSKUNK_LURE = 180346
|
||||||
|
};
|
||||||
|
|
||||||
class boss_gahzranka : public CreatureScript
|
class boss_gahzranka : public CreatureScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -51,6 +57,11 @@ public:
|
|||||||
{
|
{
|
||||||
boss_gahzrankaAI(Creature* creature) : BossAI(creature, DATA_GAHZRANKA) { }
|
boss_gahzrankaAI(Creature* creature) : BossAI(creature, DATA_GAHZRANKA) { }
|
||||||
|
|
||||||
|
void IsSummonedBy(Unit* /*summoner*/) override
|
||||||
|
{
|
||||||
|
me->GetMotionMaster()->MovePath(me->GetEntry() * 10, false);
|
||||||
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
@@ -147,8 +158,45 @@ private:
|
|||||||
bool _wipeThreat = false;
|
bool _wipeThreat = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class spell_pagles_point_cast : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_pagles_point_cast);
|
||||||
|
|
||||||
|
void OnEffect(SpellEffIndex /*effIndex*/)
|
||||||
|
{
|
||||||
|
if (Unit* caster = GetCaster())
|
||||||
|
{
|
||||||
|
if (InstanceScript* instanceScript = caster->GetInstanceScript())
|
||||||
|
{
|
||||||
|
if (!instanceScript->GetData(DATA_GAHZRANKA))
|
||||||
|
{
|
||||||
|
caster->m_Events.AddEventAtOffset([caster]()
|
||||||
|
{
|
||||||
|
if (GameObject* lure = caster->SummonGameObject(GAMEOBJECT_MUDSKUNK_LURE, -11688.5f, -1737.74f, 10.409842f, 1.f, 0.f, 0.f, 0.f, 0.f, 30 * IN_MILLISECONDS))
|
||||||
|
{
|
||||||
|
caster->m_Events.AddEventAtOffset([caster, lure]()
|
||||||
|
{
|
||||||
|
if (lure)
|
||||||
|
lure->DespawnOrUnsummon();
|
||||||
|
caster->CastSpell(caster, SPELL_SPLASH, true);
|
||||||
|
caster->SummonCreature(NPC_GAHZRANKA, -11688.5f, -1723.74f, -5.78f, 0.f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5 * DAY * IN_MILLISECONDS);
|
||||||
|
}, 5s);
|
||||||
|
}
|
||||||
|
}, 2s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectLaunch += SpellEffectFn(spell_pagles_point_cast::OnEffect, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_boss_gahzranka()
|
void AddSC_boss_gahzranka()
|
||||||
{
|
{
|
||||||
new boss_gahzranka();
|
new boss_gahzranka();
|
||||||
RegisterSpellScript(spell_gahzranka_slam);
|
RegisterSpellScript(spell_gahzranka_slam);
|
||||||
|
RegisterSpellScript(spell_pagles_point_cast);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,19 +24,25 @@ EndScriptData */
|
|||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "SpellScript.h"
|
||||||
#include "zulgurub.h"
|
#include "zulgurub.h"
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
{
|
{
|
||||||
SPELL_MANABURN = 26046,
|
SPELL_SLEEP = 24664,
|
||||||
SPELL_SLEEP = 24664
|
SPELL_EARTH_SHOCK = 24685,
|
||||||
|
SPELL_CHAIN_BURN = 24684,
|
||||||
|
SPELL_SUMMON_NIGHTMARE_ILLUSION_LEFT = 24681,
|
||||||
|
SPELL_SUMMON_NIGHTMARE_ILLUSION_BACK = 24728,
|
||||||
|
SPELL_SUMMON_NIGHTMARE_ILLUSION_RIGHT = 24729
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Events
|
enum Events
|
||||||
{
|
{
|
||||||
EVENT_MANABURN = 1,
|
EVENT_SLEEP = 1,
|
||||||
EVENT_SLEEP = 2,
|
EVENT_EARTH_SHOCK = 2,
|
||||||
EVENT_ILLUSIONS = 3
|
EVENT_CHAIN_BURN = 3,
|
||||||
|
EVENT_ILLUSIONS = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_hazzarah : public CreatureScript
|
class boss_hazzarah : public CreatureScript
|
||||||
@@ -48,22 +54,42 @@ public:
|
|||||||
{
|
{
|
||||||
boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||||
|
|
||||||
void Reset() override
|
void JustSummoned(Creature* summon) override
|
||||||
{
|
{
|
||||||
_Reset();
|
summons.Summon(summon);
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
summon->SetCorpseDelay(10);
|
||||||
{
|
summon->SetReactState(REACT_PASSIVE);
|
||||||
_JustDied();
|
summon->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||||
|
summon->SetVisible(false);
|
||||||
|
summon->m_Events.AddEventAtOffset([summon]()
|
||||||
|
{
|
||||||
|
summon->SetVisible(true);
|
||||||
|
}, 2s);
|
||||||
|
|
||||||
|
summon->m_Events.AddEventAtOffset([summon]()
|
||||||
|
{
|
||||||
|
summon->RemoveUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||||
|
summon->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
summon->SetInCombatWithZone();
|
||||||
|
}, 3500ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
void EnterCombat(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
_EnterCombat();
|
_EnterCombat();
|
||||||
events.ScheduleEvent(EVENT_MANABURN, urand(4000, 10000));
|
events.ScheduleEvent(EVENT_SLEEP, 12s, 15s);
|
||||||
events.ScheduleEvent(EVENT_SLEEP, urand(10000, 18000));
|
events.ScheduleEvent(EVENT_EARTH_SHOCK, 8s, 18s);
|
||||||
events.ScheduleEvent(EVENT_ILLUSIONS, urand(10000, 18000));
|
events.ScheduleEvent(EVENT_CHAIN_BURN, 12s, 28s);
|
||||||
|
events.ScheduleEvent(EVENT_ILLUSIONS, 16s, 24s);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanAIAttack(Unit const* target) const override
|
||||||
|
{
|
||||||
|
if (me->GetThreatMgr().getThreatList().size() > 1 && me->GetThreatMgr().getOnlineContainer().getMostHated()->getTarget() == target)
|
||||||
|
return !target->HasAura(SPELL_SLEEP);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
@@ -80,27 +106,26 @@ public:
|
|||||||
{
|
{
|
||||||
switch (eventId)
|
switch (eventId)
|
||||||
{
|
{
|
||||||
case EVENT_MANABURN:
|
|
||||||
DoCastVictim(SPELL_MANABURN, true);
|
|
||||||
events.ScheduleEvent(EVENT_MANABURN, urand(8000, 16000));
|
|
||||||
break;
|
|
||||||
case EVENT_SLEEP:
|
case EVENT_SLEEP:
|
||||||
DoCastVictim(SPELL_SLEEP, true);
|
DoCastVictim(SPELL_SLEEP, true);
|
||||||
events.ScheduleEvent(EVENT_SLEEP, urand(12000, 20000));
|
events.ScheduleEvent(EVENT_SLEEP, 24s, 32s);
|
||||||
|
return;
|
||||||
|
case EVENT_EARTH_SHOCK:
|
||||||
|
DoCastVictim(SPELL_EARTH_SHOCK);
|
||||||
|
events.ScheduleEvent(EVENT_EARTH_SHOCK, 8s, 18s);
|
||||||
|
break;
|
||||||
|
case EVENT_CHAIN_BURN:
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, [&](Unit* u) { return u && !u->IsPet() && u->getPowerType() == POWER_MANA; }))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_CHAIN_BURN, false);
|
||||||
|
}
|
||||||
|
events.ScheduleEvent(EVENT_CHAIN_BURN, 12s, 28s);
|
||||||
break;
|
break;
|
||||||
case EVENT_ILLUSIONS:
|
case EVENT_ILLUSIONS:
|
||||||
// We will summon 3 illusions that will spawn on a random gamer and attack this gamer
|
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_LEFT, true);
|
||||||
// We will just use one model for the beginning
|
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_BACK, true);
|
||||||
for (uint8 i = 0; i < 3; ++i)
|
DoCastSelf(SPELL_SUMMON_NIGHTMARE_ILLUSION_RIGHT, true);
|
||||||
{
|
events.ScheduleEvent(EVENT_ILLUSIONS, 16s, 24s);
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
|
||||||
{
|
|
||||||
Creature* Illusion = me->SummonCreature(NPC_NIGHTMARE_ILLUSION, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
|
|
||||||
if (Illusion)
|
|
||||||
Illusion->AI()->AttackStart(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
events.ScheduleEvent(EVENT_ILLUSIONS, urand(15000, 25000));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -117,7 +142,28 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class spell_chain_burn : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_chain_burn);
|
||||||
|
|
||||||
|
void FilterTargets(std::list<WorldObject*>& targets)
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
targets.remove_if([caster](WorldObject* target) -> bool
|
||||||
|
{
|
||||||
|
Unit* unit = target->ToUnit();
|
||||||
|
return !unit || unit->getPowerType() != POWER_MANA || caster->GetVictim() == unit;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_chain_burn::FilterTargets, EFFECT_0, TARGET_UNIT_TARGET_ENEMY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_boss_hazzarah()
|
void AddSC_boss_hazzarah()
|
||||||
{
|
{
|
||||||
new boss_hazzarah();
|
new boss_hazzarah();
|
||||||
|
RegisterSpellScript(spell_chain_burn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,23 @@ public:
|
|||||||
Talk(SAY_AGGRO);
|
Talk(SAY_AGGRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JustSummoned(Creature* summon) override
|
||||||
|
{
|
||||||
|
BossAI::JustSummoned(summon);
|
||||||
|
|
||||||
|
switch (summon->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_BRAIN_WASH_TOTEM:
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||||
|
{
|
||||||
|
summon->CastSpell(target, summon->m_spells[0], true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
{
|
{
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
|
|||||||
@@ -15,45 +15,72 @@
|
|||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ScriptData
|
#include "GameObjectAI.h"
|
||||||
SDName: Boss_Marli
|
#include "SpellScript.h"
|
||||||
SD%Complete: 80
|
|
||||||
SDComment: Charging healers and casters not working. Perhaps wrong Spell Timers.
|
|
||||||
SDCategory: Zul'Gurub
|
|
||||||
EndScriptData */
|
|
||||||
|
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
#include "zulgurub.h"
|
#include "zulgurub.h"
|
||||||
|
|
||||||
enum Says
|
enum Says
|
||||||
{
|
{
|
||||||
|
// Mar'li
|
||||||
SAY_AGGRO = 0,
|
SAY_AGGRO = 0,
|
||||||
SAY_TRANSFORM = 1,
|
SAY_TRANSFORM = 1,
|
||||||
SAY_SPIDER_SPAWN = 2,
|
SAY_SPIDER_SPAWN = 2,
|
||||||
SAY_DEATH = 3
|
SAY_DEATH = 3,
|
||||||
|
SAY_TRANSFORM_BACK = 4,
|
||||||
|
|
||||||
|
// Spawn of Mar'li
|
||||||
|
EMOTE_FULL_GROWN = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
{
|
{
|
||||||
|
// Spider form
|
||||||
SPELL_CHARGE = 22911,
|
SPELL_CHARGE = 22911,
|
||||||
SPELL_ASPECT_OF_MARLI = 24686, // A stun spell
|
SPELL_ENVELOPING_WEB = 24110,
|
||||||
SPELL_ENVOLWINGWEB = 24110,
|
SPELL_CORROSIVE_POISON = 24111,
|
||||||
|
SPELL_POISON_SHOCK = 24112,
|
||||||
|
|
||||||
|
//Troll form
|
||||||
SPELL_POISON_VOLLEY = 24099,
|
SPELL_POISON_VOLLEY = 24099,
|
||||||
|
SPELL_DRAIN_LIFE = 24300,
|
||||||
|
SPELL_ENLARGE = 24109,
|
||||||
|
SPELL_SPIDER_EGGS = 24082,
|
||||||
|
|
||||||
|
// All
|
||||||
SPELL_SPIDER_FORM = 24084,
|
SPELL_SPIDER_FORM = 24084,
|
||||||
// The Spider Spell
|
SPELL_TRANSFORM_BACK = 24085,
|
||||||
SPELL_LEVELUP = 24312 // Not right Spell.
|
SPELL_THRASH = 3391,
|
||||||
|
SPELL_HATCH_SPIDER_EGG = 24082,
|
||||||
|
SPELL_HATCH_EGGS = 24083,
|
||||||
|
|
||||||
|
// Spawn of Mar'li
|
||||||
|
SPELL_GROWTH = 24086,
|
||||||
|
SPELL_FULL_GROWN = 24088
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Events
|
enum Events
|
||||||
{
|
{
|
||||||
EVENT_SPAWN_START_SPIDERS = 1, // Phase 1
|
// Spider form
|
||||||
EVENT_POISON_VOLLEY = 2, // Phase All
|
EVENT_CHARGE_PLAYER = 7,
|
||||||
EVENT_SPAWN_SPIDER = 3, // Phase All
|
EVENT_ENVELOPING_WEB = 8,
|
||||||
EVENT_CHARGE_PLAYER = 4, // Phase 3
|
EVENT_CORROSIVE_POISON = 9,
|
||||||
EVENT_ASPECT_OF_MARLI = 5, // Phase 2
|
EVENT_POISON_SHOCK = 10,
|
||||||
EVENT_TRANSFORM = 6, // Phase 2
|
|
||||||
EVENT_TRANSFORM_BACK = 7 // Phase 3
|
// Troll form
|
||||||
|
EVENT_POISON_VOLLEY = 11,
|
||||||
|
EVENT_DRAIN_LIFE = 12,
|
||||||
|
EVENT_ENLARGE = 13,
|
||||||
|
|
||||||
|
// All
|
||||||
|
EVENT_SPAWN_START_SPIDERS = 1,
|
||||||
|
EVENT_TRANSFORM = 2,
|
||||||
|
EVENT_TRANSFORM_BACK = 3,
|
||||||
|
EVENT_HATCH_SPIDER_EGG = 4,
|
||||||
|
EVENT_THRASH = 5,
|
||||||
|
EVENT_TALK_FIRST_SPIDERS = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Phases
|
enum Phases
|
||||||
@@ -63,208 +90,269 @@ enum Phases
|
|||||||
PHASE_THREE = 3
|
PHASE_THREE = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_marli : public CreatureScript
|
enum Misc
|
||||||
{
|
{
|
||||||
public:
|
GO_SPIDER_EGGS = 179985,
|
||||||
boss_marli() : CreatureScript("boss_marli") { }
|
};
|
||||||
|
|
||||||
struct boss_marliAI : public BossAI
|
struct boss_marli : public BossAI
|
||||||
|
{
|
||||||
|
boss_marli(Creature* creature) : BossAI(creature, DATA_MARLI) { }
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
{
|
{
|
||||||
boss_marliAI(Creature* creature) : BossAI(creature, DATA_MARLI) { }
|
if (events.IsInPhase(PHASE_THREE))
|
||||||
|
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||||
|
|
||||||
void Reset() override
|
std::list<GameObject*> eggs;
|
||||||
|
me->GetGameObjectListWithEntryInGrid(eggs, GO_SPIDER_EGGS, DEFAULT_VISIBILITY_INSTANCE);
|
||||||
|
|
||||||
|
for (auto const& egg : eggs)
|
||||||
{
|
{
|
||||||
if (events.IsInPhase(PHASE_THREE))
|
egg->Respawn();
|
||||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
egg->UpdateObjectVisibility();
|
||||||
_Reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
BossAI::Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustDied(Unit* killer) override
|
||||||
|
{
|
||||||
|
BossAI::JustDied(killer);
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnterCombat(Unit* who) override
|
||||||
|
{
|
||||||
|
BossAI::EnterCombat(who);
|
||||||
|
events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE);
|
||||||
|
Talk(SAY_AGGRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
events.Update(diff);
|
||||||
|
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (uint32 eventId = events.ExecuteEvent())
|
||||||
{
|
{
|
||||||
_JustDied();
|
switch (eventId)
|
||||||
Talk(SAY_DEATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
|
||||||
{
|
|
||||||
_EnterCombat();
|
|
||||||
events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE);
|
|
||||||
Talk(SAY_AGGRO);
|
|
||||||
}
|
|
||||||
|
|
||||||
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_SPAWN_START_SPIDERS:
|
||||||
|
events.ScheduleEvent(EVENT_TALK_FIRST_SPIDERS, 500, 0, PHASE_TWO);
|
||||||
|
DoCastAOE(SPELL_HATCH_EGGS);
|
||||||
|
events.ScheduleEvent(EVENT_TRANSFORM, 60000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_HATCH_SPIDER_EGG, 30000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_DRAIN_LIFE, 30000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_THRASH, urand(4000, 6000)); // all phases
|
||||||
|
events.ScheduleEvent(EVENT_ENLARGE, urand(10000, 20000), 0, PHASE_TWO);
|
||||||
|
events.SetPhase(PHASE_TWO);
|
||||||
|
break;
|
||||||
|
case EVENT_TALK_FIRST_SPIDERS:
|
||||||
|
Talk(SAY_SPIDER_SPAWN);
|
||||||
|
break;
|
||||||
|
case EVENT_POISON_VOLLEY:
|
||||||
|
DoCastVictim(SPELL_POISON_VOLLEY, true);
|
||||||
|
events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000), 0, PHASE_TWO);
|
||||||
|
break;
|
||||||
|
case EVENT_HATCH_SPIDER_EGG:
|
||||||
|
DoCastSelf(SPELL_HATCH_SPIDER_EGG, true);
|
||||||
|
events.ScheduleEvent(EVENT_HATCH_SPIDER_EGG, 20000, 0, PHASE_TWO);
|
||||||
|
break;
|
||||||
|
case EVENT_DRAIN_LIFE:
|
||||||
|
DoCastRandomTarget(SPELL_DRAIN_LIFE);
|
||||||
|
events.ScheduleEvent(EVENT_DRAIN_LIFE, urand(20000, 50000), 0, PHASE_TWO);
|
||||||
|
break;
|
||||||
|
case EVENT_ENLARGE:
|
||||||
{
|
{
|
||||||
case EVENT_SPAWN_START_SPIDERS:
|
std::list<Creature*> targets = DoFindFriendlyMissingBuff(100.f, SPELL_ENLARGE);
|
||||||
|
if (targets.size() > 0)
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
DoCast(*(targets.begin()), SPELL_ENLARGE);
|
||||||
{
|
events.ScheduleEvent(EVENT_ENLARGE, urand(20000, 40000), 0, PHASE_TWO);
|
||||||
Talk(SAY_SPIDER_SPAWN);
|
break;
|
||||||
Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
|
||||||
if (Spider)
|
|
||||||
Spider->AI()->AttackStart(target);
|
|
||||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
|
||||||
if (Spider)
|
|
||||||
Spider->AI()->AttackStart(target);
|
|
||||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
|
||||||
if (Spider)
|
|
||||||
Spider->AI()->AttackStart(target);
|
|
||||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
|
||||||
if (Spider)
|
|
||||||
Spider->AI()->AttackStart(target);
|
|
||||||
}
|
|
||||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO);
|
|
||||||
events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
|
|
||||||
events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000);
|
|
||||||
events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000);
|
|
||||||
events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
|
|
||||||
events.SetPhase(PHASE_TWO);
|
|
||||||
break;
|
|
||||||
case EVENT_POISON_VOLLEY:
|
|
||||||
DoCastVictim(SPELL_POISON_VOLLEY, true);
|
|
||||||
events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000));
|
|
||||||
break;
|
|
||||||
case EVENT_ASPECT_OF_MARLI:
|
|
||||||
DoCastVictim(SPELL_ASPECT_OF_MARLI, true);
|
|
||||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, urand(13000, 18000), 0, PHASE_TWO);
|
|
||||||
break;
|
|
||||||
case EVENT_SPAWN_SPIDER:
|
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
|
||||||
{
|
|
||||||
Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
|
||||||
if (Spider)
|
|
||||||
Spider->AI()->AttackStart(target);
|
|
||||||
}
|
|
||||||
events.ScheduleEvent(EVENT_SPAWN_SPIDER, urand(12000, 17000));
|
|
||||||
break;
|
|
||||||
case EVENT_TRANSFORM:
|
|
||||||
{
|
|
||||||
Talk(SAY_TRANSFORM);
|
|
||||||
DoCast(me, SPELL_SPIDER_FORM); // SPELL_AURA_TRANSFORM
|
|
||||||
/*
|
|
||||||
CreatureTemplate const* cinfo = me->GetCreatureTemplate();
|
|
||||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
|
|
||||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
|
|
||||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
|
||||||
*/
|
|
||||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack
|
|
||||||
DoCastVictim(SPELL_ENVOLWINGWEB);
|
|
||||||
if (DoGetThreat(me->GetVictim()))
|
|
||||||
DoModifyThreatPercent(me->GetVictim(), -100);
|
|
||||||
events.ScheduleEvent(EVENT_CHARGE_PLAYER, 1500, 0, PHASE_THREE);
|
|
||||||
events.ScheduleEvent(EVENT_TRANSFORM_BACK, 25000, 0, PHASE_THREE);
|
|
||||||
events.SetPhase(PHASE_THREE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_CHARGE_PLAYER:
|
|
||||||
{
|
|
||||||
Unit* target = nullptr;
|
|
||||||
int i = 0;
|
|
||||||
while (i++ < 3) // max 3 tries to get a random target with power_mana
|
|
||||||
{
|
|
||||||
target = SelectTarget(SelectTargetMethod::Random, 1, 100, true); // not aggro leader
|
|
||||||
if (target && target->getPowerType() == POWER_MANA)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (target)
|
|
||||||
{
|
|
||||||
DoCast(target, SPELL_CHARGE);
|
|
||||||
AttackStart(target);
|
|
||||||
}
|
|
||||||
events.ScheduleEvent(EVENT_CHARGE_PLAYER, 8000, 0, PHASE_THREE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVENT_TRANSFORM_BACK:
|
|
||||||
{
|
|
||||||
me->RemoveAura(SPELL_SPIDER_FORM);
|
|
||||||
/*
|
|
||||||
CreatureTemplate const* cinfo = me->GetCreatureTemplate();
|
|
||||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1)));
|
|
||||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1)));
|
|
||||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
|
||||||
*/
|
|
||||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
|
||||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO);
|
|
||||||
events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
|
|
||||||
events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000);
|
|
||||||
events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000);
|
|
||||||
events.ScheduleEvent(EVENT_TRANSFORM, urand(35000, 60000), 0, PHASE_TWO);
|
|
||||||
events.SetPhase(PHASE_TWO);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
case EVENT_TRANSFORM:
|
||||||
|
Talk(SAY_TRANSFORM);
|
||||||
|
DoCastSelf(SPELL_SPIDER_FORM, true);
|
||||||
|
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack
|
||||||
|
events.ScheduleEvent(EVENT_ENVELOPING_WEB, 5000, 0, PHASE_THREE);
|
||||||
|
events.ScheduleEvent(EVENT_CHARGE_PLAYER, 6000, 0, PHASE_THREE);
|
||||||
|
events.ScheduleEvent(EVENT_CORROSIVE_POISON, 1000, 0, PHASE_THREE);
|
||||||
|
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(5000, 10000), 0, PHASE_THREE);
|
||||||
|
events.ScheduleEvent(EVENT_TRANSFORM_BACK, 60000, 0, PHASE_THREE);
|
||||||
|
events.SetPhase(PHASE_THREE);
|
||||||
|
break;
|
||||||
|
case EVENT_ENVELOPING_WEB:
|
||||||
|
DoCastAOE(SPELL_ENVELOPING_WEB);
|
||||||
|
events.ScheduleEvent(EVENT_CHARGE_PLAYER, 500, 0, PHASE_THREE);
|
||||||
|
events.ScheduleEvent(EVENT_ENVELOPING_WEB, urand(15000, 20000), 0, PHASE_THREE);
|
||||||
|
break;
|
||||||
|
case EVENT_CHARGE_PLAYER:
|
||||||
|
{
|
||||||
|
Unit* target = SelectTarget(SelectTargetMethod::Random, 0, [this](Unit* target) -> bool
|
||||||
|
{
|
||||||
|
if (target->GetTypeId() != TYPEID_PLAYER || target->getPowerType() != Powers::POWER_MANA)
|
||||||
|
return false;
|
||||||
|
if (me->IsWithinMeleeRange(target) || me->GetVictim() == target)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_CHARGE);
|
||||||
|
AttackStart(target);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EVENT_CORROSIVE_POISON:
|
||||||
|
DoCastVictim(SPELL_CORROSIVE_POISON);
|
||||||
|
events.ScheduleEvent(EVENT_CORROSIVE_POISON, urand(25000, 35000), 0, PHASE_THREE);
|
||||||
|
break;
|
||||||
|
case EVENT_POISON_SHOCK:
|
||||||
|
DoCastRandomTarget(SPELL_POISON_SHOCK);
|
||||||
|
events.ScheduleEvent(EVENT_POISON_SHOCK, 10000, 0, PHASE_THREE);
|
||||||
|
break;
|
||||||
|
case EVENT_TRANSFORM_BACK:
|
||||||
|
me->RemoveAura(SPELL_SPIDER_FORM);
|
||||||
|
DoCastSelf(SPELL_TRANSFORM_BACK, true);
|
||||||
|
Talk(SAY_TRANSFORM_BACK);
|
||||||
|
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||||
|
events.ScheduleEvent(EVENT_TRANSFORM, 60000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_HATCH_SPIDER_EGG, 30000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_DRAIN_LIFE, 30000, 0, PHASE_TWO);
|
||||||
|
events.ScheduleEvent(EVENT_ENLARGE, urand(10000, 20000), 0, PHASE_TWO);
|
||||||
|
events.SetPhase(PHASE_TWO);
|
||||||
|
break;
|
||||||
|
case EVENT_THRASH:
|
||||||
|
DoCastVictim(SPELL_THRASH);
|
||||||
|
events.ScheduleEvent(EVENT_THRASH, urand(10000, 20000));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
DoMeleeAttackIfReady();
|
||||||
{
|
|
||||||
return GetZulGurubAI<boss_marliAI>(creature);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Spawn of Marli
|
// Spawn of Mar'li
|
||||||
class npc_spawn_of_marli : public CreatureScript
|
struct npc_spawn_of_marli : public ScriptedAI
|
||||||
{
|
{
|
||||||
public:
|
npc_spawn_of_marli(Creature* creature) : ScriptedAI(creature) { }
|
||||||
npc_spawn_of_marli() : CreatureScript("npc_spawn_of_marli") { }
|
|
||||||
|
|
||||||
struct npc_spawn_of_marliAI : public ScriptedAI
|
void Reset() override
|
||||||
{
|
{
|
||||||
npc_spawn_of_marliAI(Creature* creature) : ScriptedAI(creature) { }
|
_scheduler.CancelAll();
|
||||||
|
}
|
||||||
|
|
||||||
uint32 LevelUp_Timer;
|
void EnterCombat(Unit* /*who*/) override
|
||||||
|
{
|
||||||
void Reset() override
|
_scheduler.Schedule(4s, [this](TaskContext context)
|
||||||
{
|
{
|
||||||
LevelUp_Timer = 3000;
|
if (context.GetRepeatCounter() < 5)
|
||||||
}
|
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
//Return since we have no target
|
|
||||||
if (!UpdateVictim())
|
|
||||||
return;
|
|
||||||
|
|
||||||
//LevelUp_Timer
|
|
||||||
if (LevelUp_Timer <= diff)
|
|
||||||
{
|
{
|
||||||
DoCast(me, SPELL_LEVELUP);
|
DoCastSelf(SPELL_GROWTH);
|
||||||
LevelUp_Timer = 3000;
|
context.Repeat(4s);
|
||||||
}
|
}
|
||||||
else LevelUp_Timer -= diff;
|
else
|
||||||
|
{
|
||||||
|
Talk(EMOTE_FULL_GROWN);
|
||||||
|
DoCastSelf(SPELL_FULL_GROWN);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
void UpdateAI(uint32 diff) override
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
return GetZulGurubAI<npc_spawn_of_marliAI>(creature);
|
//Return since we have no target
|
||||||
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
_scheduler.Update(diff, [this]
|
||||||
|
{
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 24083 - Hatch Eggs
|
||||||
|
class spell_hatch_eggs : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_hatch_eggs);
|
||||||
|
|
||||||
|
void HandleObjectAreaTargetSelect(std::list<WorldObject*>& targets)
|
||||||
|
{
|
||||||
|
targets.sort(Acore::ObjectDistanceOrderPred(GetCaster()));
|
||||||
|
targets.resize(GetSpellInfo()->MaxAffectedTargets);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hatch_eggs::HandleObjectAreaTargetSelect, EFFECT_0, TARGET_GAMEOBJECT_DEST_AREA);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 24110 - Enveloping Webs
|
||||||
|
class spell_enveloping_webs : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_enveloping_webs);
|
||||||
|
|
||||||
|
void HandleOnHit()
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
Unit* hitUnit = GetHitUnit();
|
||||||
|
if (caster && hitUnit && hitUnit->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
caster->GetThreatMgr().modifyThreatPercent(hitUnit, -100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnHit += SpellHitFn(spell_enveloping_webs::HandleOnHit);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 24084 - Mar'li Transform
|
||||||
|
class spell_marli_transform : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(spell_marli_transform);
|
||||||
|
|
||||||
|
void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
|
{
|
||||||
|
if (GetCaster() && GetCaster()->ToCreature())
|
||||||
|
GetCaster()->ToCreature()->LoadEquipment(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
|
{
|
||||||
|
if (GetCaster() && GetCaster()->ToCreature())
|
||||||
|
GetCaster()->ToCreature()->LoadEquipment(1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectApply += AuraEffectApplyFn(spell_marli_transform::HandleApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
|
||||||
|
OnEffectRemove += AuraEffectRemoveFn(spell_marli_transform::HandleRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_marli()
|
void AddSC_boss_marli()
|
||||||
{
|
{
|
||||||
new boss_marli();
|
RegisterCreatureAI(boss_marli);
|
||||||
new npc_spawn_of_marli();
|
RegisterCreatureAI(npc_spawn_of_marli);
|
||||||
|
RegisterSpellScript(spell_hatch_eggs);
|
||||||
|
RegisterSpellScript(spell_enveloping_webs);
|
||||||
|
RegisterSpellScript(spell_marli_transform);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,20 @@ EndScriptData */
|
|||||||
|
|
||||||
enum Spells
|
enum Spells
|
||||||
{
|
{
|
||||||
SPELL_AMBUSH = 34794,
|
SPELL_VANISH = 24699,
|
||||||
SPELL_THOUSANDBLADES = 34799
|
SPELL_AMBUSH = 24337,
|
||||||
|
SPELL_GOUGE = 24698,
|
||||||
|
SPELL_THOUSAND_BLADES = 24649,
|
||||||
|
SPELL_THRASH = 3417,
|
||||||
|
SPELL_ENRAGE = 8269
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Misc
|
enum Events
|
||||||
{
|
{
|
||||||
EQUIP_ID_MAIN_HAND = 0 //was item display id 31818, but this id does not exist
|
EVENT_VANISH = 1,
|
||||||
|
EVENT_AMBUSH = 2,
|
||||||
|
EVENT_GOUGE = 3,
|
||||||
|
EVENT_THOUSAND_BLADES = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_renataki : public CreatureScript
|
class boss_renataki : public CreatureScript
|
||||||
@@ -46,36 +53,67 @@ public:
|
|||||||
{
|
{
|
||||||
boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||||
|
|
||||||
uint32 Invisible_Timer;
|
|
||||||
uint32 Ambush_Timer;
|
|
||||||
uint32 Visible_Timer;
|
|
||||||
uint32 Aggro_Timer;
|
|
||||||
uint32 ThousandBlades_Timer;
|
|
||||||
|
|
||||||
bool Invisible;
|
|
||||||
bool Ambushed;
|
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
_Reset();
|
_Reset();
|
||||||
Invisible_Timer = urand(8000, 18000);
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
Ambush_Timer = 3000;
|
_enraged = false;
|
||||||
Visible_Timer = 4000;
|
_thousandBladesCount = urand(2, 5);
|
||||||
Aggro_Timer = urand(15000, 25000);
|
_thousandBladesTargets.clear();
|
||||||
ThousandBlades_Timer = urand(4000, 8000);
|
_dynamicFlags = me->GetDynamicFlags();
|
||||||
|
|
||||||
Invisible = false;
|
|
||||||
Ambushed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
|
||||||
{
|
|
||||||
_JustDied();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
void EnterCombat(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
_EnterCombat();
|
_EnterCombat();
|
||||||
|
events.ScheduleEvent(EVENT_VANISH, 23s, 25s);
|
||||||
|
events.ScheduleEvent(EVENT_GOUGE, 5s, 10s);
|
||||||
|
events.ScheduleEvent(EVENT_THOUSAND_BLADES, 15s, 20s);
|
||||||
|
|
||||||
|
DoCastSelf(SPELL_THRASH, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override
|
||||||
|
{
|
||||||
|
if (!_enraged && HealthBelowPct(30))
|
||||||
|
{
|
||||||
|
me->TextEmote("%s becomes enraged", me, false);
|
||||||
|
DoCast(me, SPELL_ENRAGE);
|
||||||
|
_enraged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanAIAttack(Unit const* target) const override
|
||||||
|
{
|
||||||
|
if (me->GetThreatMgr().getThreatList().size() > 1 && me->GetThreatMgr().getOnlineContainer().getMostHated()->getTarget() == target)
|
||||||
|
return !target->HasAura(SPELL_GOUGE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanBeSeen(Player const* /*player*/) override
|
||||||
|
{
|
||||||
|
return me->GetReactState() == REACT_AGGRESSIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanSeeAlways(WorldObject const* obj) override
|
||||||
|
{
|
||||||
|
if (me->GetReactState() == REACT_PASSIVE)
|
||||||
|
{
|
||||||
|
return obj->ToCreature() && obj->ToCreature()->IsPet();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanAlwaysBeDetectable(WorldObject const* seer) override
|
||||||
|
{
|
||||||
|
if (me->GetReactState() == REACT_PASSIVE)
|
||||||
|
{
|
||||||
|
return seer->ToCreature() && seer->ToCreature()->IsPet();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
@@ -83,86 +121,122 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//Invisible_Timer
|
events.Update(diff);
|
||||||
if (Invisible_Timer <= diff)
|
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (uint32 eventId = events.ExecuteEvent())
|
||||||
{
|
{
|
||||||
me->InterruptSpell(CURRENT_GENERIC_SPELL);
|
switch (eventId)
|
||||||
|
|
||||||
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
|
|
||||||
me->SetDisplayId(11686);
|
|
||||||
|
|
||||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
Invisible = true;
|
|
||||||
|
|
||||||
Invisible_Timer = urand(15000, 30000);
|
|
||||||
}
|
|
||||||
else Invisible_Timer -= diff;
|
|
||||||
|
|
||||||
if (Invisible)
|
|
||||||
{
|
|
||||||
if (Ambush_Timer <= diff)
|
|
||||||
{
|
{
|
||||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
|
case EVENT_VANISH:
|
||||||
if (target)
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
_dynamicFlags = me->GetDynamicFlags();
|
||||||
|
me->RemoveDynamicFlag(UNIT_DYNFLAG_TRACK_UNIT);
|
||||||
|
DoCastSelf(SPELL_VANISH);
|
||||||
|
events.DelayEvents(5s);
|
||||||
|
events.ScheduleEvent(EVENT_AMBUSH, 5s);
|
||||||
|
events.ScheduleEvent(EVENT_VANISH, 38s, 45s);
|
||||||
|
return;
|
||||||
|
case EVENT_AMBUSH:
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||||
|
{
|
||||||
|
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation());
|
||||||
|
DoCast(target, SPELL_AMBUSH, true);
|
||||||
|
}
|
||||||
|
me->SetDynamicFlag(_dynamicFlags);
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_VANISH);
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
break;
|
||||||
|
case EVENT_GOUGE:
|
||||||
|
DoCastAOE(SPELL_GOUGE);
|
||||||
|
events.ScheduleEvent(EVENT_GOUGE, 10s, 15s);
|
||||||
|
return;
|
||||||
|
case EVENT_THOUSAND_BLADES:
|
||||||
{
|
{
|
||||||
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation());
|
if (_thousandBladesTargets.empty())
|
||||||
DoCast(target, SPELL_AMBUSH);
|
{
|
||||||
}
|
std::vector<Unit*> targetList;
|
||||||
|
ThreatContainer::StorageType const& threatlist = me->GetThreatMgr().getThreatList();
|
||||||
|
for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
|
||||||
|
{
|
||||||
|
if (Unit* target = (*itr)->getTarget())
|
||||||
|
{
|
||||||
|
if (target->IsAlive() && target->IsWithinDist2d(me, 100.f))
|
||||||
|
{
|
||||||
|
targetList.push_back(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ambushed = true;
|
if (!targetList.empty())
|
||||||
Ambush_Timer = 3000;
|
{
|
||||||
|
Acore::Containers::RandomShuffle(targetList);
|
||||||
|
|
||||||
|
// First get ranged targets
|
||||||
|
for (Unit* target : targetList)
|
||||||
|
{
|
||||||
|
if (!target->IsWithinMeleeRange(me))
|
||||||
|
{
|
||||||
|
_thousandBladesTargets.push_back(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_thousandBladesTargets.size() < _thousandBladesCount)
|
||||||
|
{
|
||||||
|
// if still not enough, get melee targets
|
||||||
|
for (Unit* target : targetList)
|
||||||
|
{
|
||||||
|
if (target->IsWithinMeleeRange(me))
|
||||||
|
{
|
||||||
|
_thousandBladesTargets.push_back(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_thousandBladesTargets.empty())
|
||||||
|
{
|
||||||
|
Acore::Containers::RandomResize(_thousandBladesTargets, _thousandBladesCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_thousandBladesTargets.empty())
|
||||||
|
{
|
||||||
|
std::vector<Unit*>::iterator itr = _thousandBladesTargets.begin();
|
||||||
|
std::advance(itr, urand(0, _thousandBladesTargets.size() - 1));
|
||||||
|
|
||||||
|
if (Unit* target = *itr)
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_THOUSAND_BLADES, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_thousandBladesTargets.erase(itr);
|
||||||
|
|
||||||
|
events.ScheduleEvent(EVENT_THOUSAND_BLADES, 500ms);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_thousandBladesCount = urand(2, 5);
|
||||||
|
events.ScheduleEvent(EVENT_THOUSAND_BLADES, 15s, 22s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else Ambush_Timer -= diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ambushed)
|
if (me->GetReactState() == REACT_AGGRESSIVE)
|
||||||
{
|
DoMeleeAttackIfReady();
|
||||||
if (Visible_Timer <= diff)
|
|
||||||
{
|
|
||||||
me->InterruptSpell(CURRENT_GENERIC_SPELL);
|
|
||||||
|
|
||||||
me->SetDisplayId(15268);
|
|
||||||
SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
|
|
||||||
|
|
||||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
|
||||||
Invisible = false;
|
|
||||||
|
|
||||||
Visible_Timer = 4000;
|
|
||||||
}
|
|
||||||
else Visible_Timer -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Resetting some aggro so he attacks other gamers
|
|
||||||
if (!Invisible)
|
|
||||||
{
|
|
||||||
if (Aggro_Timer <= diff)
|
|
||||||
{
|
|
||||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 1);
|
|
||||||
|
|
||||||
if (DoGetThreat(me->GetVictim()))
|
|
||||||
{
|
|
||||||
DoModifyThreatPercent(me->GetVictim(), -50);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target)
|
|
||||||
{
|
|
||||||
AttackStart(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
Aggro_Timer = urand(7000, 20000);
|
|
||||||
}
|
|
||||||
else Aggro_Timer -= diff;
|
|
||||||
|
|
||||||
if (ThousandBlades_Timer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_THOUSANDBLADES);
|
|
||||||
ThousandBlades_Timer = urand(7000, 12000);
|
|
||||||
}
|
|
||||||
else ThousandBlades_Timer -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _enraged;
|
||||||
|
uint32 _dynamicFlags;
|
||||||
|
uint8 _thousandBladesCount;
|
||||||
|
std::vector<Unit*> _thousandBladesTargets;
|
||||||
};
|
};
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ SDComment: Missing reset function after killing a boss for Ohgan, Thekal.
|
|||||||
SDCategory: Zul'Gurub
|
SDCategory: Zul'Gurub
|
||||||
EndScriptData */
|
EndScriptData */
|
||||||
|
|
||||||
|
#include "GameObjectAI.h"
|
||||||
#include "InstanceScript.h"
|
#include "InstanceScript.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "zulgurub.h"
|
#include "zulgurub.h"
|
||||||
@@ -36,7 +37,8 @@ ObjectData const creatureData[] =
|
|||||||
{
|
{
|
||||||
{ NPC_HIGH_PRIEST_THEKAL, DATA_THEKAL },
|
{ NPC_HIGH_PRIEST_THEKAL, DATA_THEKAL },
|
||||||
{ NPC_ZEALOT_LORKHAN, DATA_LORKHAN },
|
{ NPC_ZEALOT_LORKHAN, DATA_LORKHAN },
|
||||||
{ NPC_ZEALOT_ZATH, DATA_ZATH }
|
{ NPC_ZEALOT_ZATH, DATA_ZATH },
|
||||||
|
{ NPC_PRIESTESS_MARLI, DATA_MARLI }
|
||||||
};
|
};
|
||||||
|
|
||||||
class instance_zulgurub : public InstanceMapScript
|
class instance_zulgurub : public InstanceMapScript
|
||||||
@@ -49,6 +51,7 @@ public:
|
|||||||
instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map)
|
instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||||
{
|
{
|
||||||
SetBossNumber(EncounterCount);
|
SetBossNumber(EncounterCount);
|
||||||
|
LoadObjectData(creatureData, nullptr);
|
||||||
LoadDoorData(doorData);
|
LoadDoorData(doorData);
|
||||||
LoadObjectData(creatureData, nullptr);
|
LoadObjectData(creatureData, nullptr);
|
||||||
}
|
}
|
||||||
@@ -71,7 +74,20 @@ public:
|
|||||||
case NPC_HAKKAR:
|
case NPC_HAKKAR:
|
||||||
_hakkarGUID = creature->GetGUID();
|
_hakkarGUID = creature->GetGUID();
|
||||||
break;
|
break;
|
||||||
|
case NPC_SPAWN_OF_MARLI:
|
||||||
|
if (Creature* marli = GetCreature(DATA_MARLI))
|
||||||
|
{
|
||||||
|
marli->AI()->JustSummoned(creature);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NPC_GAHZRANKA:
|
||||||
|
_gahzrankaGUID = creature->GetGUID();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstanceScript::OnCreatureCreate(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGameObjectCreate(GameObject* go) override
|
void OnGameObjectCreate(GameObject* go) override
|
||||||
@@ -109,6 +125,16 @@ public:
|
|||||||
return ObjectGuid::Empty;
|
return ObjectGuid::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 GetData(uint32 type) const override
|
||||||
|
{
|
||||||
|
if (type == DATA_GAHZRANKA)
|
||||||
|
{
|
||||||
|
return _gahzrankaGUID || GetBossState(DATA_GAHZRANKA) == DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetSaveData() override
|
std::string GetSaveData() override
|
||||||
{
|
{
|
||||||
OUT_SAVE_INST_DATA;
|
OUT_SAVE_INST_DATA;
|
||||||
@@ -160,6 +186,7 @@ public:
|
|||||||
ObjectGuid _arlokkGUID;
|
ObjectGuid _arlokkGUID;
|
||||||
ObjectGuid _goGongOfBethekkGUID;
|
ObjectGuid _goGongOfBethekkGUID;
|
||||||
ObjectGuid _hakkarGUID;
|
ObjectGuid _hakkarGUID;
|
||||||
|
ObjectGuid _gahzrankaGUID;
|
||||||
};
|
};
|
||||||
|
|
||||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||||
@@ -168,7 +195,56 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EdgeOfMadnessEnum
|
||||||
|
{
|
||||||
|
EVENT_EDGE_OF_MADNESS_GRILEK = 27,
|
||||||
|
EVENT_EDGE_OF_MADNESS_HAZZARAH = 28,
|
||||||
|
EVENT_EDGE_OF_MADNESS_RENATAKI = 29,
|
||||||
|
EVENT_EDGE_OF_MADNESS_WUSHOOLAY = 30
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::pair<uint32, uint32>> BrazierOfMadnessContainer =
|
||||||
|
{
|
||||||
|
{ EVENT_EDGE_OF_MADNESS_GRILEK, NPC_GRILEK },
|
||||||
|
{ EVENT_EDGE_OF_MADNESS_HAZZARAH, NPC_HAZZARAH },
|
||||||
|
{ EVENT_EDGE_OF_MADNESS_RENATAKI, NPC_RENATAKI },
|
||||||
|
{ EVENT_EDGE_OF_MADNESS_WUSHOOLAY, NPC_WUSHOOLAY }
|
||||||
|
};
|
||||||
|
|
||||||
|
Position const edgeOfMagnessSummonPos = { -11901.229f, -1906.366f, 65.358f, 0.942f };
|
||||||
|
|
||||||
|
struct go_brazier_of_madness : public GameObjectAI
|
||||||
|
{
|
||||||
|
go_brazier_of_madness(GameObject* go) : GameObjectAI(go) { }
|
||||||
|
|
||||||
|
bool GossipHello(Player* /*player*/, bool reportUse) override
|
||||||
|
{
|
||||||
|
if (reportUse)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 bossEntry = 0;
|
||||||
|
for (uint8 i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
if (sGameEventMgr->IsActiveEvent(BrazierOfMadnessContainer[i].first))
|
||||||
|
{
|
||||||
|
bossEntry = BrazierOfMadnessContainer[i].second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bossEntry)
|
||||||
|
{
|
||||||
|
me->SummonCreature(bossEntry, edgeOfMagnessSummonPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2 * HOUR * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_instance_zulgurub()
|
void AddSC_instance_zulgurub()
|
||||||
{
|
{
|
||||||
new instance_zulgurub();
|
new instance_zulgurub();
|
||||||
|
RegisterGameObjectAI(go_brazier_of_madness);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ enum CreatureIds
|
|||||||
NPC_ZULIAN_PROWLER = 15101, // Arlokk Event
|
NPC_ZULIAN_PROWLER = 15101, // Arlokk Event
|
||||||
NPC_ZEALOT_LORKHAN = 11347,
|
NPC_ZEALOT_LORKHAN = 11347,
|
||||||
NPC_ZEALOT_ZATH = 11348,
|
NPC_ZEALOT_ZATH = 11348,
|
||||||
|
NPC_PRIESTESS_MARLI = 14510,
|
||||||
|
NPC_SPAWN_OF_MARLI = 15041,
|
||||||
NPC_HIGH_PRIEST_THEKAL = 14509,
|
NPC_HIGH_PRIEST_THEKAL = 14509,
|
||||||
NPC_JINDO_THE_HEXXER = 11380,
|
NPC_JINDO_THE_HEXXER = 11380,
|
||||||
NPC_NIGHTMARE_ILLUSION = 15163,
|
NPC_NIGHTMARE_ILLUSION = 15163,
|
||||||
@@ -59,7 +61,13 @@ enum CreatureIds
|
|||||||
NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event
|
NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event
|
||||||
NPC_CHAINED_SPIRIT = 15117, // Mandokir Event
|
NPC_CHAINED_SPIRIT = 15117, // Mandokir Event
|
||||||
NPC_HAKKAR = 14834,
|
NPC_HAKKAR = 14834,
|
||||||
NPC_ZULGURUB_TIGER = 11361
|
NPC_ZULGURUB_TIGER = 11361,
|
||||||
|
NPC_BRAIN_WASH_TOTEM = 15112,
|
||||||
|
NPC_GAHZRANKA = 15114,
|
||||||
|
NPC_GRILEK = 15082,
|
||||||
|
NPC_HAZZARAH = 15083,
|
||||||
|
NPC_RENATAKI = 15084,
|
||||||
|
NPC_WUSHOOLAY = 15085
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GameobjectIds
|
enum GameobjectIds
|
||||||
|
|||||||
@@ -25,38 +25,9 @@ EndScriptData */
|
|||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
#include "ScriptedCreature.h"
|
#include "ScriptedCreature.h"
|
||||||
|
#include "TaskScheduler.h"
|
||||||
#include "temple_of_ahnqiraj.h"
|
#include "temple_of_ahnqiraj.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a 2 phases events. Here follows an explanation of the main events and transition between phases and sub-phases.
|
|
||||||
*
|
|
||||||
* The first phase is the EYE phase: the Eye of C'Thun is active and C'thun is not active.
|
|
||||||
* During this phase, the "Eye of C'Thun" alternates between 2 sub-phases:
|
|
||||||
* - PHASE_EYE_GREEN_BEAM:
|
|
||||||
* 50 sec phase during which the Eye mainly casts its Green Beam every 3 sec.
|
|
||||||
* - PHASE_EYE_RED_BEAM:
|
|
||||||
* 35 sec phase during which the Eye casts its red beam every sec.
|
|
||||||
* This EYE phase ends when the "Eye of C'Thun" is killed. Then starts the CTHUN phase.
|
|
||||||
*
|
|
||||||
* The second phase is the CTHUN phase. The Eye of C'Thun is not active and C'Thun is active.
|
|
||||||
* This phase starts with the transformation of the Eye into C'Thun (PHASE_CTHUN_TRANSITION).
|
|
||||||
* After the transformation, C'Thun alternates between 2 sub-phases:
|
|
||||||
* - PHASE_CTHUN_STOMACH:
|
|
||||||
* - C'Thun is almost insensible to all damage (99% damage reduction).
|
|
||||||
* - It spawns 2 tentacles in its stomach.
|
|
||||||
* - C'Thun swallows players.
|
|
||||||
* - This sub-phase ends when the 2 tentacles are killed. Swallowed players are regurgitate.
|
|
||||||
*
|
|
||||||
* - PHASE_CTHUN_WEAK:
|
|
||||||
* - weakened C'Thun takes normal damage.
|
|
||||||
* - This sub-phase ends after 45 secs.
|
|
||||||
*
|
|
||||||
* This CTHUN phase ends when C'Thun is killed
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* - the current phase is stored in the instance data to be easily shared between the eye and cthun.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum Phases
|
enum Phases
|
||||||
{
|
{
|
||||||
PHASE_NOT_STARTED = 0,
|
PHASE_NOT_STARTED = 0,
|
||||||
@@ -99,7 +70,7 @@ enum Spells
|
|||||||
//SAME AS PHASE1
|
//SAME AS PHASE1
|
||||||
|
|
||||||
//Giant Claw Tentacles
|
//Giant Claw Tentacles
|
||||||
SPELL_MASSIVE_GROUND_RUPTURE = 26100,
|
SPELL_MASSIVE_GROUND_RUPTURE = 26478,
|
||||||
|
|
||||||
//Also casts Hamstring
|
//Also casts Hamstring
|
||||||
SPELL_THRASH = 3391,
|
SPELL_THRASH = 3391,
|
||||||
@@ -111,6 +82,10 @@ enum Spells
|
|||||||
SPELL_MOUTH_TENTACLE = 26332,
|
SPELL_MOUTH_TENTACLE = 26332,
|
||||||
SPELL_EXIT_STOMACH_KNOCKBACK = 25383,
|
SPELL_EXIT_STOMACH_KNOCKBACK = 25383,
|
||||||
SPELL_DIGESTIVE_ACID = 26476,
|
SPELL_DIGESTIVE_ACID = 26476,
|
||||||
|
|
||||||
|
// Tentacles
|
||||||
|
SPELL_SUBMERGE_VISUAL = 26234,
|
||||||
|
SPELL_BIRTH = 26262
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Actions
|
enum Actions
|
||||||
@@ -142,6 +117,20 @@ const Position FleshTentaclePos[2] =
|
|||||||
{ -8525.0f, 1994.0f, -98.0f, 2.12f},
|
{ -8525.0f, 1994.0f, -98.0f, 2.12f},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NotInStomachSelector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NotInStomachSelector() { }
|
||||||
|
|
||||||
|
bool operator()(Unit* unit) const
|
||||||
|
{
|
||||||
|
if (unit->GetTypeId() != TYPEID_PLAYER || unit->HasAura(SPELL_DIGESTIVE_ACID))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//Kick out position
|
//Kick out position
|
||||||
const Position KickPos = { -8545.0f, 1984.0f, -96.0f, 0.0f};
|
const Position KickPos = { -8545.0f, 1984.0f, -96.0f, 0.0f};
|
||||||
|
|
||||||
@@ -917,32 +906,40 @@ public:
|
|||||||
{
|
{
|
||||||
eye_tentacleAI(Creature* creature) : ScriptedAI(creature)
|
eye_tentacleAI(Creature* creature) : ScriptedAI(creature)
|
||||||
{
|
{
|
||||||
if (Creature* pPortal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
if (Creature* portal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
||||||
{
|
{
|
||||||
pPortal->SetReactState(REACT_PASSIVE);
|
portal->SetReactState(REACT_PASSIVE);
|
||||||
Portal = pPortal->GetGUID();
|
_portalGUID = portal->GetGUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCombatMovement(false);
|
SetCombatMovement(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MindflayTimer;
|
|
||||||
uint32 KillSelfTimer;
|
|
||||||
ObjectGuid Portal;
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
if (Unit* p = ObjectAccessor::GetUnit(*me, Portal))
|
if (Unit* p = ObjectAccessor::GetUnit(*me, _portalGUID))
|
||||||
|
{
|
||||||
Unit::Kill(p, p);
|
Unit::Kill(p, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
//Mind flay half a second after we spawn
|
_scheduler.Schedule(500ms, [this](TaskContext /*task*/)
|
||||||
MindflayTimer = 500;
|
{
|
||||||
|
DoCastAOE(SPELL_GROUND_RUPTURE);
|
||||||
|
}).Schedule(5min, [this](TaskContext /*task*/)
|
||||||
|
{
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
}).Schedule(1s, 5s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, [&](Unit* u) { return u && u->GetTypeId() == TYPEID_PLAYER && !u->HasAura(SPELL_DIGESTIVE_ACID) && !u->HasAura(SPELL_MIND_FLAY); }))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_MIND_FLAY);
|
||||||
|
}
|
||||||
|
|
||||||
//This prevents eyes from overlapping
|
context.Repeat(10s, 15s);
|
||||||
KillSelfTimer = 35000;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
void EnterCombat(Unit* /*who*/) override
|
||||||
@@ -956,26 +953,12 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//KillSelfTimer
|
_scheduler.Update(diff);
|
||||||
if (KillSelfTimer <= diff)
|
|
||||||
{
|
|
||||||
Unit::Kill(me, me);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else KillSelfTimer -= diff;
|
|
||||||
|
|
||||||
//MindflayTimer
|
|
||||||
if (MindflayTimer <= diff)
|
|
||||||
{
|
|
||||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
|
|
||||||
if (target && !target->HasAura(SPELL_DIGESTIVE_ACID))
|
|
||||||
DoCast(target, SPELL_MIND_FLAY);
|
|
||||||
|
|
||||||
//Mindflay every 10 seconds
|
|
||||||
MindflayTimer = 10000;
|
|
||||||
}
|
|
||||||
else MindflayTimer -= diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
ObjectGuid _portalGUID;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -995,35 +978,41 @@ public:
|
|||||||
{
|
{
|
||||||
SetCombatMovement(false);
|
SetCombatMovement(false);
|
||||||
|
|
||||||
if (Creature* pPortal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
if (Creature* portal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
||||||
{
|
{
|
||||||
pPortal->SetReactState(REACT_PASSIVE);
|
portal->SetReactState(REACT_PASSIVE);
|
||||||
Portal = pPortal->GetGUID();
|
_portalGUID = portal->GetGUID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GroundRuptureTimer;
|
|
||||||
uint32 HamstringTimer;
|
|
||||||
uint32 EvadeTimer;
|
|
||||||
ObjectGuid Portal;
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
if (Unit* p = ObjectAccessor::GetUnit(*me, Portal))
|
if (Unit* p = ObjectAccessor::GetUnit(*me, _portalGUID))
|
||||||
|
{
|
||||||
Unit::Kill(p, p);
|
Unit::Kill(p, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
//First rupture should happen half a second after we spawn
|
_scheduler.Schedule(Milliseconds(500), [this](TaskContext /*task*/)
|
||||||
GroundRuptureTimer = 500;
|
{
|
||||||
HamstringTimer = 2000;
|
DoCastAOE(SPELL_GROUND_RUPTURE);
|
||||||
EvadeTimer = 5000;
|
}).Schedule(Minutes(5), [this](TaskContext /*task*/)
|
||||||
|
{
|
||||||
|
me->DespawnOrUnsummon();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
void EnterCombat(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
DoZoneInCombat();
|
DoZoneInCombat();
|
||||||
|
|
||||||
|
_scheduler.Schedule(2s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_HAMSTRING);
|
||||||
|
context.Repeat(5s);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
@@ -1032,62 +1021,14 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//EvadeTimer
|
_scheduler.Update(diff);
|
||||||
if (!me->IsWithinMeleeRange(me->GetVictim()))
|
|
||||||
{
|
|
||||||
if (EvadeTimer <= diff)
|
|
||||||
{
|
|
||||||
if (Unit* p = ObjectAccessor::GetUnit(*me, Portal))
|
|
||||||
Unit::Kill(p, p);
|
|
||||||
|
|
||||||
//Dissapear and reappear at new position
|
|
||||||
me->SetVisible(false);
|
|
||||||
|
|
||||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
Unit::Kill(me, me);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target->HasAura(SPELL_DIGESTIVE_ACID))
|
|
||||||
{
|
|
||||||
me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
|
|
||||||
if (Creature* pPortal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
|
||||||
{
|
|
||||||
pPortal->SetReactState(REACT_PASSIVE);
|
|
||||||
Portal = pPortal->GetGUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
GroundRuptureTimer = 500;
|
|
||||||
HamstringTimer = 2000;
|
|
||||||
EvadeTimer = 5000;
|
|
||||||
AttackStart(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
me->SetVisible(true);
|
|
||||||
}
|
|
||||||
else EvadeTimer -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
//GroundRuptureTimer
|
|
||||||
if (GroundRuptureTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_GROUND_RUPTURE);
|
|
||||||
GroundRuptureTimer = 30000;
|
|
||||||
}
|
|
||||||
else GroundRuptureTimer -= diff;
|
|
||||||
|
|
||||||
//HamstringTimer
|
|
||||||
if (HamstringTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_HAMSTRING);
|
|
||||||
HamstringTimer = 5000;
|
|
||||||
}
|
|
||||||
else HamstringTimer -= diff;
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
ObjectGuid _portalGUID;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1107,37 +1048,112 @@ public:
|
|||||||
{
|
{
|
||||||
SetCombatMovement(false);
|
SetCombatMovement(false);
|
||||||
|
|
||||||
if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
if (Creature* portal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
||||||
{
|
{
|
||||||
pPortal->SetReactState(REACT_PASSIVE);
|
portal->SetReactState(REACT_PASSIVE);
|
||||||
Portal = pPortal->GetGUID();
|
_portalGUID = portal->GetGUID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GroundRuptureTimer;
|
|
||||||
uint32 ThrashTimer;
|
|
||||||
uint32 HamstringTimer;
|
|
||||||
uint32 EvadeTimer;
|
|
||||||
ObjectGuid Portal;
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
if (Unit* p = ObjectAccessor::GetUnit(*me, Portal))
|
if (Unit* p = ObjectAccessor::GetUnit(*me, _portalGUID))
|
||||||
|
{
|
||||||
Unit::Kill(p, p);
|
Unit::Kill(p, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
//First rupture should happen half a second after we spawn
|
_scheduler.Schedule(500ms, [this](TaskContext /*task*/)
|
||||||
GroundRuptureTimer = 500;
|
{
|
||||||
HamstringTimer = 2000;
|
DoCastAOE(SPELL_MASSIVE_GROUND_RUPTURE);
|
||||||
ThrashTimer = 5000;
|
});
|
||||||
EvadeTimer = 5000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
void EnterCombat(Unit* /*who*/) override
|
||||||
{
|
{
|
||||||
DoZoneInCombat();
|
DoZoneInCombat();
|
||||||
|
|
||||||
|
_scheduler.Schedule(2s, [this](TaskContext context)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_HAMSTRING);
|
||||||
|
context.Repeat(10s);
|
||||||
|
}).Schedule(5s, [this](TaskContext context) {
|
||||||
|
DoCastSelf(SPELL_THRASH);
|
||||||
|
context.Repeat(10s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScheduleMeleeCheck()
|
||||||
|
{
|
||||||
|
// Check if a target is in melee range
|
||||||
|
_scheduler.Schedule(10s, [this](TaskContext task)
|
||||||
|
{
|
||||||
|
if (Unit* target = me->GetVictim())
|
||||||
|
{
|
||||||
|
if (!target->IsWithinMeleeRange(me))
|
||||||
|
{
|
||||||
|
// Main target not found within melee range, try to select a new one
|
||||||
|
if (Player* newTarget = me->SelectNearestPlayer(5.0f))
|
||||||
|
{
|
||||||
|
AttackStart(newTarget);
|
||||||
|
}
|
||||||
|
else // Main target not found, and failed to acquire a new target... Submerge
|
||||||
|
{
|
||||||
|
Submerge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task.Repeat();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Submerge()
|
||||||
|
{
|
||||||
|
if (me->SelectNearestPlayer(5.0f))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Despawn portal
|
||||||
|
if (Creature* p = ObjectAccessor::GetCreature(*me, _portalGUID))
|
||||||
|
{
|
||||||
|
p->DespawnOrUnsummon();
|
||||||
|
}
|
||||||
|
|
||||||
|
DoCastSelf(SPELL_SUBMERGE_VISUAL);
|
||||||
|
me->SetHealth(me->GetMaxHealth());
|
||||||
|
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
|
||||||
|
_scheduler.CancelAll();
|
||||||
|
|
||||||
|
_scheduler.Schedule(5s, [this](TaskContext /*task*/)
|
||||||
|
{
|
||||||
|
Emerge();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emerge()
|
||||||
|
{
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NotInStomachSelector()))
|
||||||
|
{
|
||||||
|
Position pos = target->GetPosition();
|
||||||
|
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), 0);
|
||||||
|
if (Creature* portal = me->SummonCreature(NPC_GIANT_PORTAL, pos, TEMPSUMMON_CORPSE_DESPAWN))
|
||||||
|
{
|
||||||
|
portal->SetReactState(REACT_PASSIVE);
|
||||||
|
_portalGUID = portal->GetGUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_VISUAL);
|
||||||
|
DoCastSelf(SPELL_BIRTH);
|
||||||
|
DoCastAOE(SPELL_MASSIVE_GROUND_RUPTURE, true);
|
||||||
|
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||||
|
|
||||||
|
ScheduleMeleeCheck();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void UpdateAI(uint32 diff) override
|
||||||
@@ -1146,70 +1162,14 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//EvadeTimer
|
_scheduler.Update(diff);
|
||||||
if (!me->IsWithinMeleeRange(me->GetVictim()))
|
|
||||||
{
|
|
||||||
if (EvadeTimer <= diff)
|
|
||||||
{
|
|
||||||
if (Unit* p = ObjectAccessor::GetUnit(*me, Portal))
|
|
||||||
Unit::Kill(p, p);
|
|
||||||
|
|
||||||
//Dissapear and reappear at new position
|
|
||||||
me->SetVisible(false);
|
|
||||||
|
|
||||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
|
|
||||||
if (!target)
|
|
||||||
{
|
|
||||||
Unit::Kill(me, me);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target->HasAura(SPELL_DIGESTIVE_ACID))
|
|
||||||
{
|
|
||||||
me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
|
|
||||||
if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
|
||||||
{
|
|
||||||
pPortal->SetReactState(REACT_PASSIVE);
|
|
||||||
Portal = pPortal->GetGUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
GroundRuptureTimer = 500;
|
|
||||||
HamstringTimer = 2000;
|
|
||||||
ThrashTimer = 5000;
|
|
||||||
EvadeTimer = 5000;
|
|
||||||
AttackStart(target);
|
|
||||||
}
|
|
||||||
me->SetVisible(true);
|
|
||||||
}
|
|
||||||
else EvadeTimer -= diff;
|
|
||||||
}
|
|
||||||
|
|
||||||
//GroundRuptureTimer
|
|
||||||
if (GroundRuptureTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_GROUND_RUPTURE);
|
|
||||||
GroundRuptureTimer = 30000;
|
|
||||||
}
|
|
||||||
else GroundRuptureTimer -= diff;
|
|
||||||
|
|
||||||
//ThrashTimer
|
|
||||||
if (ThrashTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_THRASH);
|
|
||||||
ThrashTimer = 10000;
|
|
||||||
}
|
|
||||||
else ThrashTimer -= diff;
|
|
||||||
|
|
||||||
//HamstringTimer
|
|
||||||
if (HamstringTimer <= diff)
|
|
||||||
{
|
|
||||||
DoCastVictim(SPELL_HAMSTRING);
|
|
||||||
HamstringTimer = 10000;
|
|
||||||
}
|
|
||||||
else HamstringTimer -= diff;
|
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
ObjectGuid _portalGUID;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1229,26 +1189,34 @@ public:
|
|||||||
{
|
{
|
||||||
SetCombatMovement(false);
|
SetCombatMovement(false);
|
||||||
|
|
||||||
if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
if (Creature* portal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
|
||||||
{
|
{
|
||||||
pPortal->SetReactState(REACT_PASSIVE);
|
portal->SetReactState(REACT_PASSIVE);
|
||||||
Portal = pPortal->GetGUID();
|
_portalGUID = portal->GetGUID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 BeamTimer;
|
|
||||||
ObjectGuid Portal;
|
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
{
|
{
|
||||||
if (Unit* p = ObjectAccessor::GetUnit(*me, Portal))
|
if (Unit* p = ObjectAccessor::GetUnit(*me, _portalGUID))
|
||||||
|
{
|
||||||
Unit::Kill(p, p);
|
Unit::Kill(p, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
//Green Beam half a second after we spawn
|
_scheduler.Schedule(500ms, [this](TaskContext /*task*/)
|
||||||
BeamTimer = 500;
|
{
|
||||||
|
DoCastAOE(SPELL_MASSIVE_GROUND_RUPTURE);
|
||||||
|
}).Schedule(1s, 5s, [this](TaskContext context) {
|
||||||
|
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, -SPELL_DIGESTIVE_ACID))
|
||||||
|
{
|
||||||
|
DoCast(target, SPELL_GREEN_BEAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Repeat(2100ms);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* /*who*/) override
|
void EnterCombat(Unit* /*who*/) override
|
||||||
@@ -1262,18 +1230,12 @@ public:
|
|||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//BeamTimer
|
_scheduler.Update(diff);
|
||||||
if (BeamTimer <= diff)
|
|
||||||
{
|
|
||||||
Unit* target = SelectTarget(SelectTargetMethod::Random, 0);
|
|
||||||
if (target && !target->HasAura(SPELL_DIGESTIVE_ACID))
|
|
||||||
DoCast(target, SPELL_GREEN_BEAM);
|
|
||||||
|
|
||||||
//Beam every 2 seconds
|
|
||||||
BeamTimer = 2100;
|
|
||||||
}
|
|
||||||
else BeamTimer -= diff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TaskScheduler _scheduler;
|
||||||
|
ObjectGuid _portalGUID;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,8 +69,6 @@ public:
|
|||||||
{
|
{
|
||||||
if (p->GetZoneId() == me->GetZoneId())
|
if (p->GetZoneId() == me->GetZoneId())
|
||||||
{
|
{
|
||||||
|
|
||||||
p->RemoveAurasDueToSpell(SPELL_AURA_OF_FROST);
|
|
||||||
p->RemoveAurasDueToSpell(SPELL_CHILL);
|
p->RemoveAurasDueToSpell(SPELL_CHILL);
|
||||||
p->RemoveAurasDueToSpell(SPELL_FROST_BREATH);
|
p->RemoveAurasDueToSpell(SPELL_FROST_BREATH);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -738,48 +738,6 @@ class spell_gen_no_offhand_proc : public AuraScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 71602 - Item - Icecrown 25 Normal Caster Trinket 1 Base
|
|
||||||
71645 - Item - Icecrown 25 Heroic Caster Trinket 1 Base
|
|
||||||
71845 - Item - Icecrown 25 Normal Caster Weapon Proc
|
|
||||||
71846 - Item - Icecrown 25 Heroic Caster Weapon Proc
|
|
||||||
72419 - Item - Icecrown Reputation Ring Healer Trigger
|
|
||||||
75465 - Item - Chamber of Aspects 25 Nuker Trinket
|
|
||||||
75474 - Item - Chamber of Aspects 25 Heroic Nuker Trinket */
|
|
||||||
class spell_gen_proc_once_per_cast : public AuraScript
|
|
||||||
{
|
|
||||||
PrepareAuraScript(spell_gen_proc_once_per_cast);
|
|
||||||
|
|
||||||
bool Load() override
|
|
||||||
{
|
|
||||||
_spellPointer = nullptr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckProc(ProcEventInfo& eventInfo)
|
|
||||||
{
|
|
||||||
if (eventInfo.GetActor())
|
|
||||||
{
|
|
||||||
if (Player* player = eventInfo.GetActor()->ToPlayer())
|
|
||||||
{
|
|
||||||
if (player->m_spellModTakingSpell == _spellPointer)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
_spellPointer = player->m_spellModTakingSpell;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Register() override
|
|
||||||
{
|
|
||||||
DoCheckProc += AuraCheckProcFn(spell_gen_proc_once_per_cast::CheckProc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Spell* _spellPointer;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 70805 - Item - Rogue T10 2P Bonus
|
// 70805 - Item - Rogue T10 2P Bonus
|
||||||
class spell_gen_proc_on_self : public AuraScript
|
class spell_gen_proc_on_self : public AuraScript
|
||||||
{
|
{
|
||||||
@@ -4545,7 +4503,6 @@ void AddSC_generic_spell_scripts()
|
|||||||
RegisterSpellScript(spell_gen_use_spell_base_level_check);
|
RegisterSpellScript(spell_gen_use_spell_base_level_check);
|
||||||
RegisterSpellScript(spell_gen_proc_from_direct_damage);
|
RegisterSpellScript(spell_gen_proc_from_direct_damage);
|
||||||
RegisterSpellScript(spell_gen_no_offhand_proc);
|
RegisterSpellScript(spell_gen_no_offhand_proc);
|
||||||
RegisterSpellScript(spell_gen_proc_once_per_cast);
|
|
||||||
RegisterSpellScript(spell_gen_proc_on_self);
|
RegisterSpellScript(spell_gen_proc_on_self);
|
||||||
RegisterSpellScript(spell_gen_proc_not_self);
|
RegisterSpellScript(spell_gen_proc_not_self);
|
||||||
RegisterSpellScript(spell_gen_baby_murloc_passive);
|
RegisterSpellScript(spell_gen_baby_murloc_passive);
|
||||||
|
|||||||
@@ -1208,6 +1208,27 @@ class spell_warl_drain_soul : public AuraScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 29341 - Shadowburn
|
||||||
|
class spell_warl_shadowburn : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(spell_warl_shadowburn);
|
||||||
|
|
||||||
|
void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
if (!(GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH && caster && target && caster->IsPlayer() && caster->ToPlayer()->isHonorOrXPTarget(target)))
|
||||||
|
{
|
||||||
|
PreventDefaultAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectRemove += AuraEffectRemoveFn(spell_warl_shadowburn::RemoveEffect, EFFECT_0, SPELL_AURA_CHANNEL_DEATH_ITEM, AURA_EFFECT_HANDLE_REAL);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_warlock_spell_scripts()
|
void AddSC_warlock_spell_scripts()
|
||||||
{
|
{
|
||||||
RegisterSpellScript(spell_warl_eye_of_kilrogg);
|
RegisterSpellScript(spell_warl_eye_of_kilrogg);
|
||||||
@@ -1238,4 +1259,5 @@ void AddSC_warlock_spell_scripts()
|
|||||||
RegisterSpellScript(spell_warl_soulshatter);
|
RegisterSpellScript(spell_warl_soulshatter);
|
||||||
RegisterSpellScript(spell_warl_unstable_affliction);
|
RegisterSpellScript(spell_warl_unstable_affliction);
|
||||||
RegisterSpellScript(spell_warl_drain_soul);
|
RegisterSpellScript(spell_warl_drain_soul);
|
||||||
|
RegisterSpellScript(spell_warl_shadowburn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,9 +302,6 @@ public:
|
|||||||
* ---
|
* ---
|
||||||
* --- Dragonspecific scripts and handling: LETHON
|
* --- Dragonspecific scripts and handling: LETHON
|
||||||
* ---
|
* ---
|
||||||
*
|
|
||||||
* @todo
|
|
||||||
* - Spell: Shadow bolt whirl casts needs custom handling (spellscript)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum LethonTexts
|
enum LethonTexts
|
||||||
@@ -318,6 +315,14 @@ enum LethonSpells
|
|||||||
SPELL_DRAW_SPIRIT = 24811,
|
SPELL_DRAW_SPIRIT = 24811,
|
||||||
SPELL_SHADOW_BOLT_WHIRL = 24834,
|
SPELL_SHADOW_BOLT_WHIRL = 24834,
|
||||||
SPELL_DARK_OFFERING = 24804,
|
SPELL_DARK_OFFERING = 24804,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL1 = 24820,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL2 = 24821,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL3 = 24822,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL4 = 24823,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL5 = 24835,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL6 = 24836,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL7 = 24837,
|
||||||
|
SPELL_SHADOW_BOLT_WHIRL8 = 24838,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LethonCreatures
|
enum LethonCreatures
|
||||||
@@ -340,13 +345,14 @@ public:
|
|||||||
{
|
{
|
||||||
_stage = 1;
|
_stage = 1;
|
||||||
emerald_dragonAI::Reset();
|
emerald_dragonAI::Reset();
|
||||||
events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, 10000);
|
me->RemoveAurasDueToSpell(SPELL_SHADOW_BOLT_WHIRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit* who) override
|
void EnterCombat(Unit* who) override
|
||||||
{
|
{
|
||||||
Talk(SAY_LETHON_AGGRO);
|
Talk(SAY_LETHON_AGGRO);
|
||||||
WorldBossAI::EnterCombat(who);
|
WorldBossAI::EnterCombat(who);
|
||||||
|
DoCastSelf(SPELL_SHADOW_BOLT_WHIRL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||||
@@ -368,20 +374,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteEvent(uint32 eventId) override
|
|
||||||
{
|
|
||||||
switch (eventId)
|
|
||||||
{
|
|
||||||
case EVENT_SHADOW_BOLT_WHIRL:
|
|
||||||
me->CastSpell((Unit*)nullptr, SPELL_SHADOW_BOLT_WHIRL, false);
|
|
||||||
events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, urand(15000, 30000));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
emerald_dragonAI::ExecuteEvent(eventId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8 _stage;
|
uint8 _stage;
|
||||||
};
|
};
|
||||||
@@ -712,6 +704,41 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class spell_shadow_bolt_whirl : public AuraScript
|
||||||
|
{
|
||||||
|
PrepareAuraScript(spell_shadow_bolt_whirl);
|
||||||
|
|
||||||
|
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||||
|
{
|
||||||
|
return ValidateSpellInfo({ SPELL_SHADOW_BOLT_WHIRL1, SPELL_SHADOW_BOLT_WHIRL2, SPELL_SHADOW_BOLT_WHIRL3, SPELL_SHADOW_BOLT_WHIRL4, SPELL_SHADOW_BOLT_WHIRL5, SPELL_SHADOW_BOLT_WHIRL6, SPELL_SHADOW_BOLT_WHIRL7, SPELL_SHADOW_BOLT_WHIRL8 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandlePeriodic(AuraEffect const* aurEff)
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
Unit* target = GetTarget();
|
||||||
|
|
||||||
|
if (!caster || !target)
|
||||||
|
return;
|
||||||
|
std::array<uint32, 8> spellForTick = { SPELL_SHADOW_BOLT_WHIRL1, SPELL_SHADOW_BOLT_WHIRL2, SPELL_SHADOW_BOLT_WHIRL3, SPELL_SHADOW_BOLT_WHIRL4, SPELL_SHADOW_BOLT_WHIRL5, SPELL_SHADOW_BOLT_WHIRL6, SPELL_SHADOW_BOLT_WHIRL7, SPELL_SHADOW_BOLT_WHIRL8 };
|
||||||
|
uint32 tick = (aurEff->GetTickNumber() + 7/*-1*/) % 8;
|
||||||
|
|
||||||
|
// casted in left/right (but triggered spell have wide forward cone)
|
||||||
|
float forward = target->GetOrientation();
|
||||||
|
if (tick <= 3)
|
||||||
|
target->SetOrientation(forward + 0.75f * M_PI - tick * M_PI / 8); // Left
|
||||||
|
else
|
||||||
|
target->SetOrientation(forward - 0.75f * M_PI + (8 - tick) * M_PI / 8); // Right
|
||||||
|
|
||||||
|
target->CastSpell(target, spellForTick[tick], true);
|
||||||
|
target->SetOrientation(forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadow_bolt_whirl::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||||
|
}
|
||||||
|
};
|
||||||
class spell_mark_of_nature : public SpellScriptLoader
|
class spell_mark_of_nature : public SpellScriptLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -765,4 +792,5 @@ void AddSC_emerald_dragons()
|
|||||||
// dragon spellscripts
|
// dragon spellscripts
|
||||||
new spell_dream_fog_sleep();
|
new spell_dream_fog_sleep();
|
||||||
new spell_mark_of_nature();
|
new spell_mark_of_nature();
|
||||||
|
RegisterSpellScript(spell_shadow_bolt_whirl);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1015,6 +1015,13 @@ struct FactionTemplateEntry
|
|||||||
[[nodiscard]] bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS) != 0; }
|
[[nodiscard]] bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS) != 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GameObjectArtKitEntry
|
||||||
|
{
|
||||||
|
uint32 ID; // 0
|
||||||
|
//char* TextureVariation[3] // 1-3 m_textureVariations[3]
|
||||||
|
//char* AttachModel[4] // 4-8 m_attachModels[4]
|
||||||
|
};
|
||||||
|
|
||||||
struct GameObjectDisplayInfoEntry
|
struct GameObjectDisplayInfoEntry
|
||||||
{
|
{
|
||||||
uint32 Displayid; // 0 m_ID
|
uint32 Displayid; // 0 m_ID
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ char constexpr EmotesTextEntryfmt[] = "nxixxxxxxxxxxxxxxxx";
|
|||||||
char constexpr EmotesTextSoundEntryfmt[] = "niiii";
|
char constexpr EmotesTextSoundEntryfmt[] = "niiii";
|
||||||
char constexpr FactionEntryfmt[] = "niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
char constexpr FactionEntryfmt[] = "niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx";
|
||||||
char constexpr FactionTemplateEntryfmt[] = "niiiiiiiiiiiii";
|
char constexpr FactionTemplateEntryfmt[] = "niiiiiiiiiiiii";
|
||||||
|
char constexpr GameObjectArtKitfmt[] = "nxxxxxxx";
|
||||||
char constexpr GameObjectDisplayInfofmt[] = "nsxxxxxxxxxxffffffx";
|
char constexpr GameObjectDisplayInfofmt[] = "nsxxxxxxxxxxffffffx";
|
||||||
char constexpr GemPropertiesEntryfmt[] = "nixxi";
|
char constexpr GemPropertiesEntryfmt[] = "nixxi";
|
||||||
char constexpr GlyphPropertiesfmt[] = "niii";
|
char constexpr GlyphPropertiesfmt[] = "niii";
|
||||||
|
|||||||
Reference in New Issue
Block a user