diff options
author | Angelo Venturini <nefertum.dev@protonmail.com> | 2022-10-05 16:53:20 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 21:53:20 +0200 |
commit | ad4ce0895f04e633e259941aee470c138700ee8e (patch) | |
tree | dedc652b3ae06b6b008a7613db10d8eb84b5f751 | |
parent | e189caeb76347b573727262739d7fbc919366aa6 (diff) |
fix: Qaston revert (#13320)
* Revert "fix(Core/QAston): fixed shields oneshotting (#13271)"
This reverts commit e05f61d1b3873a217798078169455591422a1766.
* Revert "fix(Core): Crash (#13292)"
This reverts commit a818bcf3e20653a52670b7905f004187f883afff.
* Revert "fix: Crash (#13241)"
This reverts commit be423a91b53538c92b28f14759f01c474bb8b277.
* delete sql
* Revert "refactor(Core/Spells): Implement QAston Proc System (#11079)"
This reverts commit cbd3fd0967fd94a2a9eb96aaf55ebd69f32aa918.
* add sql revert
* fix sql
* remove update from world.updates
55 files changed, 8914 insertions, 9176 deletions
diff --git a/.gitignore b/.gitignore index d1b444f30d..8d0d4fcfb2 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,6 @@ nbproject/ cmake-build-debug/* cmake-build-debug-coverage/* cmake-build-debug-event-trace/* -cmake-build-debug-visual-studio/* coverage-report/ # diff --git a/data/sql/updates/db_world/2022_10_02_01.sql b/data/sql/updates/db_world/2022_10_02_01.sql deleted file mode 100644 index 4672d680f5..0000000000 --- a/data/sql/updates/db_world/2022_10_02_01.sql +++ /dev/null @@ -1,1101 +0,0 @@ --- DB update 2022_10_02_00 -> 2022_10_02_01 --- Earth shield heal is DAMAGE_CLASS_NONE, it won't scale --- Entry is unneeded -DELETE FROM `spell_bonus_data` WHERE `entry`=379; - -ALTER TABLE `spell_proc` - CHANGE `spellId` `SpellId` int(11) NOT NULL DEFAULT 0 FIRST, - CHANGE `schoolMask` `SchoolMask` tinyint(3) unsigned NOT NULL DEFAULT 0 AFTER `SpellId`, - CHANGE `spellFamilyName` `SpellFamilyName` smallint(5) unsigned NOT NULL DEFAULT 0 AFTER `SchoolMask`, - CHANGE `spellFamilyMask0` `SpellFamilyMask0` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyName`, - CHANGE `spellFamilyMask1` `SpellFamilyMask1` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask0`, - CHANGE `spellFamilyMask2` `SpellFamilyMask2` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask1`, - CHANGE `typeMask` `ProcFlags` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellFamilyMask2`, - CHANGE `spellTypeMask` `SpellTypeMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `ProcFlags`, - CHANGE `spellPhaseMask` `SpellPhaseMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellTypeMask`, - CHANGE `hitMask` `HitMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `SpellPhaseMask`, - CHANGE `attributesMask` `AttributesMask` int(10) unsigned NOT NULL DEFAULT 0 AFTER `HitMask`, - CHANGE `ratePerMinute` `ProcsPerMinute` float NOT NULL DEFAULT 0 AFTER `AttributesMask`, - CHANGE `chance` `Chance` float NOT NULL DEFAULT 0 AFTER `ProcsPerMinute`, - CHANGE `cooldown` `Cooldown` int(10) unsigned NOT NULL DEFAULT 0 AFTER `Chance`, - CHANGE `charges` `Charges` tinyint(3) unsigned NOT NULL DEFAULT 0 AFTER `Cooldown`; - -DELETE FROM `command` WHERE `name`='reload spell_proc_event'; - -DELETE FROM `spell_proc`; -INSERT INTO `spell_proc` (`SpellId`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `AttributesMask`, `ProcsPerMinute`, `Chance`, `Cooldown`, `Charges`) VALUES -(17941, 0, 5, 1, 0, 0, 65536, 1, 1, 0, 8, 0, 0, 0, 1), -(18820, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 1), -(22008, 0, 3, 1631584309, 0, 0, 69632, 5, 1, 0, 0, 0, 0, 0, 1), -(28200, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 6), -(-7001, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(32216, 0, 4, 0, 256, 0, 16, 1, 4, 0, 0, 0, 0, 0, 1), -(34477, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 1), -(34936, 0, 5, 1, 64, 0, 65536, 1, 1, 0, 8, 0, 0, 0, 1), -(44401, 0, 3, 2048, 0, 0, 65536, 5, 1, 0, 8, 0, 0, 0, 1), -(48108, 0, 3, 4194304, 0, 0, 65536, 1, 1, 0, 8, 0, 0, 0, 1), -(51124, 0, 15, 2, 6, 0, 65552, 1, 4, 0, 8, 0, 0, 0, 1), -(54741, 0, 3, 4, 0, 0, 65536, 5, 1, 0, 0, 0, 0, 0, 1), -(57761, 0, 3, 1, 4096, 0, 65536, 1, 1, 0, 8, 0, 0, 0, 1), -(64823, 0, 7, 4, 0, 0, 65536, 1, 1, 0, 0, 0, 0, 0, 1), -(-974, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3000, 0), -(-10400, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-11119, 4, 3, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-11185, 0, 3, 128, 0, 0, 65536, 1, 2, 0, 2, 0, 0, 0, 0), -(-12834, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-13983, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 1000, 0), -(-14156, 0, 8, 4063232, 9, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0), -(-15337, 0, 6, 8396800, 2, 0, 0, 1, 2, 2, 2, 0, 0, 0, 0), -(-16180, 0, 11, 448, 0, 16, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(-18094, 0, 5, 10, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-47230, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(-20234, 0, 10, 32768, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(-20335, 0, 10, 8388608, 0, 0, 16, 5, 2, 0, 0, 0, 100, 0, 0), -(-27243, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(-29441, 0, 0, 0, 0, 0, 0, 7, 0, 8, 0, 0, 0, 1000, 0), -(-29723, 0, 4, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-29834, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0), -(-30293, 0, 5, 385, 8519872, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-30675, 0, 11, 3, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-31244, 0, 8, 3801088, 9, 0, 0, 5, 2, 11196, 0, 0, 0, 0, 0), -(-31571, 0, 3, 0, 34, 0, 16384, 7, 4, 0, 2, 0, 0, 0, 0), -(-31785, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0), -(-31871, 0, 10, 16, 0, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(-31876, 0, 10, 8388608, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-34497, 0, 9, 395264, 8388609, 513, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-34914, 0, 6, 8192, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(-44404, 0, 3, 536870945, 36864, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-44445, 0, 3, 19, 69632, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-44546, 0, 3, 736, 4096, 0, 69632, 0, 2, 0, 0, 0, 0, 0, 0), -(-46913, 0, 4, 64, 1028, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-46951, 0, 4, 1024, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-47569, 0, 6, 16384, 0, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(-48979, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), -(-49015, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), -(-49018, 0, 15, 20971520, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-49182, 0, 15, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-49188, 0, 15, 0, 131072, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-49208, 0, 15, 4194304, 65536, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-49467, 0, 15, 16, 131072, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-51459, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0), -(-51474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(-51525, 0, 11, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-51556, 0, 11, 192, 0, 16, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(-51625, 0, 8, 268476416, 0, 0, 0, 5, 2, 0, 2, 0, 0, 0, 0), -(-51627, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0), -(-51664, 0, 8, 131072, 8, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-53178, 0, 9, 0, 268435456, 0, 65536, 4, 2, 0, 0, 0, 100, 0, 0), -(-53228, 0, 9, 32, 16777216, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0), -(-53290, 0, 9, 2048, 1, 512, 0, 1, 2, 2, 2, 0, 0, 0, 0), -(-53380, 0, 10, 8388608, 163840, 0, 0, 1, 2, 2, 2, 0, 0, 0, 0), -(-53501, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(-53569, 0, 10, 1075838976, 65536, 0, 0, 3, 2, 0, 2, 0, 0, 0, 0), -(-53695, 0, 10, 8388608, 0, 8, 16, 5, 2, 0, 2, 0, 0, 0, 0), -(-54639, 0, 15, 4194304, 65536, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-54747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(-59088, 0, 4, 0, 2, 0, 1024, 4, 4, 0, 0, 0, 0, 0, 0), -(-61680, 0, 9, 0, 268435456, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-62764, 0, 9, 0, 268435456, 0, 65536, 4, 2, 0, 0, 0, 100, 0, 0), -(-63156, 0, 5, 1, 192, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-63373, 0, 11, 2147483648, 0, 0, 65536, 1, 2, 0, 0, 0, 0, 0, 0), -(-64127, 0, 6, 1, 1, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0), -(-65661, 0, 15, 4194321, 537001988, 0, 16, 1, 2, 0, 0, 0, 100, 0, 0), -(1719, 0, 4, 778044484, 4212549, 0, 0, 1, 2, 0, 8, 0, 0, 0, 0), -(11129, 4, 3, 146800663, 200776, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(12536, 0, 3, 549591799, 168000, 0, 0, 0, 1, 0, 12, 0, 0, 0, 0), -(15286, 32, 6, 41984016, 9218, 8, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(16246, 0, 11, 2551185859, 5120, 16, 0, 0, 1, 0, 12, 0, 0, 0, 0), -(16864, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0), -(16870, 0, 7, 14924799, 126879699, 263168, 0, 0, 1, 0, 12, 0, 0, 0, 0), -(17619, 0, 13, 0, 0, 0, 34816, 7, 0, 0, 0, 0, 0, 0, 0), -(20185, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0), -(20186, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0), -(22007, 0, 3, 2097185, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(24658, 0, 0, 0, 0, 0, 87376, 7, 2, 0, 0, 0, 0, 0, 0), -(24932, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(26169, 0, 6, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(26467, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(28719, 0, 7, 32, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(28744, 0, 7, 64, 0, 0, 278528, 2, 2, 0, 0, 0, 0, 0, 0), -(28789, 0, 10, 3221225472, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(28809, 0, 6, 4096, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(28823, 0, 11, 192, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(28845, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(28847, 0, 7, 32, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(28849, 0, 11, 128, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(29601, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 0), -(32863, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(36123, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(38252, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(39367, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(44141, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(70388, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(30823, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 10, 0, 0, 0), -(31801, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(32409, 0, 0, 0, 8192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(33757, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3000, 0), -(37288, 0, 7, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(37295, 0, 7, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(37381, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(37377, 32, 5, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(39437, 4, 5, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(37168, 0, 8, 4063232, 9, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0), -(37594, 0, 6, 4096, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(38164, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(39372, 48, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(40442, 0, 7, 20, 1088, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0), -(40463, 0, 11, 129, 16, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0), -(40470, 0, 10, 3229614080, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0), -(40971, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(42770, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0), -(45057, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 30000, 0), -(46916, 0, 4, 2097152, 0, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0), -(47383, 0, 5, 0, 192, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(71162, 0, 5, 0, 192, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(71165, 0, 5, 0, 192, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(49005, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(49028, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0), -(49194, 0, 15, 0, 0, 1, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(49222, 0, 0, 0, 0, 0, 139944, 1, 0, 0, 0, 0, 0, 2000, 0), -(49796, 0, 15, 2, 131078, 0, 0, 0, 4, 0, 8, 0, 0, 0, 0), -(51209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(51528, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 4, 0, 0, 0), -(51529, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 8, 0, 0, 0), -(51530, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 12, 0, 0, 0), -(51531, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 16, 0, 0, 0), -(51532, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 20, 0, 0, 0), -(51698, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 0, 33, 0, 0), -(51700, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 0, 66, 0, 0), -(51701, 0, 0, 0, 0, 0, 0, 3, 4, 2, 0, 0, 100, 0, 0), -(52420, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 30000, 0), -(52437, 1, 4, 536870912, 0, 0, 16, 0, 4, 0, 0, 0, 0, 0, 0), -(53601, 0, 0, 0, 0, 0, 1048576, 0, 0, 0, 0, 0, 0, 0, 0), -(53736, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(54274, 0, 5, 357, 131264, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(54276, 0, 5, 357, 131264, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(54277, 0, 5, 357, 131264, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(54748, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, 0), -(54815, 0, 7, 32768, 0, 0, 16, 1, 2, 0, 0, 0, 0, 0, 0), -(54821, 0, 7, 4096, 0, 0, 16, 1, 2, 0, 0, 0, 0, 0, 0), -(54832, 0, 7, 0, 4096, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(54845, 0, 7, 4, 0, 0, 65536, 1, 2, 0, 0, 0, 0, 0, 0), -(54937, 0, 10, 2147483648, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(54939, 0, 10, 32768, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(55198, 0, 11, 448, 0, 0, 16384, 2, 2, 2, 0, 0, 0, 0, 3), -(55440, 0, 11, 64, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(55677, 0, 6, 0, 1, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0), -(56372, 0, 3, 0, 128, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(56374, 0, 3, 0, 16384, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(56375, 0, 3, 16777216, 0, 0, 65536, 4, 2, 2049, 0, 0, 0, 0, 0), -(56800, 0, 8, 4, 0, 0, 16, 1, 2, 0, 0, 0, 0, 0, 0), -(58375, 0, 4, 0, 512, 0, 16, 1, 2, 0, 0, 0, 0, 0, 0), -(58642, 0, 15, 0, 134217728, 0, 16, 1, 2, 0, 0, 0, 0, 0, 0), -(58677, 0, 15, 8192, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0), -(58877, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(59906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), -(59915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(37447, 0, 3, 0, 256, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(61062, 0, 3, 0, 256, 0, 16384, 4, 2, 0, 0, 0, 0, 0, 0), -(61257, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0), -(62259, 0, 15, 33554432, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), -(62600, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(62606, 0, 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0, 0), -(63279, 0, 11, 0, 1024, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0), -(63280, 0, 11, 536870912, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0), -(63320, 0, 5, 2147745792, 0, 32768, 1024, 7, 2, 0, 0, 0, 0, 0, 0), -(64890, 0, 10, 0, 65536, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0), -(64928, 0, 11, 1, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(65032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(67228, 0, 11, 0, 4096, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(69755, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 0, 0, 45000, 0), -(69739, 0, 0, 0, 0, 0, 0, 7, 2, 0, 0, 0, 0, 45000, 0), -(69762, 0, 0, 0, 0, 0, 87040, 0, 1, 0, 256, 0, 0, 0, 0), -(70723, 0, 7, 5, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(70770, 0, 6, 2048, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(70805, 0, 8, 0, 131072, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0), -(70808, 0, 11, 256, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(70817, 0, 11, 0, 4096, 0, 65536, 1, 2, 0, 0, 0, 0, 0, 0), -(70844, 0, 4, 256, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(70672, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0, 0, 0), -(72455, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0, 0, 0), -(72832, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0, 0, 0), -(72833, 0, 0, 0, 0, 0, 0, 0, 0, 12287, 0, 0, 0, 0, 0), -(71756, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(72782, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(72783, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(72784, 4, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(71406, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 50, 0, 0), -(71545, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 50, 0, 0), -(71880, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0), -(71892, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0), -(71519, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 105000, 0), -(71562, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 105000, 0), -(71564, 126, 0, 0, 0, 0, 0, 3, 2, 2, 0, 0, 0, 0, 5), -(71634, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 30000, 0), -(71640, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 30000, 0), -(71761, 0, 3, 0, 1048576, 0, 0, 5, 2, 256, 0, 0, 0, 0, 0), -(71770, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(72176, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(75475, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 45000, 0), -(75481, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 45000, 0), -(-66799, 0, 15, 4194304, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-63730, 0, 6, 2048, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-58872, 0, 0, 0, 0, 0, 0, 1, 0, 8259, 0, 0, 0, 0, 0), -(-57878, 0, 0, 0, 0, 0, 0, 1, 0, 16, 0, 0, 0, 0, 0), -(-57470, 0, 6, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 15000, 0), -(-56342, 0, 9, 24, 134217728, 147456, 0, 0, 4, 0, 2, 0, 0, 0, 0), -(-55666, 0, 15, 1, 134217728, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-53709, 2, 10, 16384, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-53671, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-53551, 0, 10, 4096, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-53527, 1, 10, 0, 0, 4, 1024, 0, 2, 1, 0, 0, 100, 0, 0), -(-53486, 0, 10, 8388608, 163840, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0), -(-53256, 0, 9, 2048, 8388609, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-53234, 0, 9, 131072, 1, 1, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-53221, 0, 9, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-53215, 0, 9, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-52795, 0, 6, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-52127, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3000, 0), -(-51940, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(-51692, 0, 8, 516, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-51672, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1000, 0), -(-51634, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 0, 0, 0), -(-51562, 0, 11, 256, 0, 16, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-51523, 0, 11, 0, 1, 0, 65536, 0, 2, 0, 0, 0, 50, 0, 0), -(-51521, 0, 11, 0, 16777216, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(-50880, 0, 15, 0, 67108864, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0), -(-49223, 0, 15, 17, 134348800, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-49219, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0), -(-49149, 0, 15, 6, 131074, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-49027, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 20000, 0), -(-49004, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0), -(-48988, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-48516, 0, 7, 5, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-48506, 0, 7, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-48496, 0, 7, 96, 33554434, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-48483, 0, 7, 34816, 1088, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-47580, 0, 6, 0, 0, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-47516, 0, 6, 6144, 65536, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0), -(-47509, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(-47263, 32, 5, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 20000, 0), -(-47258, 0, 5, 0, 8388608, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-47201, 0, 5, 16393, 262144, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-46945, 0, 4, 0, 65536, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-46867, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-46854, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-45234, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-44557, 0, 3, 32, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-44449, 0, 3, 551686775, 102472, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-44442, 0, 3, 8388608, 64, 0, 0, 0, 2, 0, 0, 0, 0, 1000, 0), -(-41635, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(-35541, 0, 0, 0, 0, 0, 8388608, 0, 0, 0, 0, 0, 0, 0, 0), -(-35100, 0, 9, 4096, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-34950, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-34935, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8000, 0), -(-34753, 0, 6, 6144, 4, 4096, 0, 0, 2, 2, 2, 0, 0, 0, 0), -(-34500, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-33881, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-33191, 0, 6, 32768, 1024, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-33150, 0, 0, 0, 0, 0, 0, 3, 2, 2, 2, 0, 0, 0, 0), -(-33142, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-33076, 0, 0, 0, 0, 0, 664232, 1, 0, 0, 0, 0, 0, 0, 0), -(-32385, 0, 5, 1, 262144, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-31833, 0, 10, 2147483648, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-31569, 0, 3, 65536, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-31124, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-30881, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 30000, 0), -(-30701, 28, 0, 0, 0, 0, 664232, 1, 0, 0, 0, 0, 100, 0, 0), -(-30299, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(-30160, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-29593, 0, 0, 0, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0), -(-29074, 20, 3, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-27811, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-20925, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(-20500, 0, 4, 268435456, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-20210, 0, 10, 3221225472, 65536, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-20177, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(-20049, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-19184, 0, 9, 16, 8192, 0, 0, 0, 4, 0, 2, 0, 0, 0, 0), -(-18119, 0, 5, 0, 8388608, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-18096, 0, 5, 256, 8388608, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-17793, 0, 5, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-17106, 0, 7, 524288, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-16958, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-16952, 0, 7, 233472, 1024, 262144, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-16880, 72, 7, 103, 58720258, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(-16487, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-16257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(-16256, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-16176, 0, 11, 448, 0, 16, 0, 2, 2, 2, 0, 0, 0, 0, 0), -(-14892, 0, 6, 268443136, 65540, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0), -(-14531, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-14186, 0, 8, 1107296782, 2, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0), -(-13754, 0, 8, 16, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-12966, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(-12319, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(-12311, 0, 4, 2048, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-12298, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0), -(-12289, 0, 4, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-12281, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 6000, 0), -(-11255, 0, 3, 16384, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-11213, 0, 3, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(-11180, 16, 3, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0), -(-11095, 0, 3, 16, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-9799, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(-9452, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(-5952, 0, 8, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(-324, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 3000, 0), -(6346, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0), -(7383, 1, 0, 0, 0, 0, 0, 1, 0, 256, 0, 0, 0, 0, 0), -(7434, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(57351, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(9782, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(9784, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(12169, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(12322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), -(12999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0), -(13000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0), -(13001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0), -(13002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0), -(15088, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0), -(15128, 4, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(15277, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(15346, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(15600, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 2, 0, 0), -(16164, 28, 0, 0, 0, 0, 65536, 1, 2, 2, 0, 0, 0, 0, 0), -(16550, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0), -(16620, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 30000, 0), -(16624, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(17364, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(17495, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(20128, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(20131, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(20132, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(20164, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 5, 0, 0, 0), -(20165, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 20, 0, 0, 0), -(20166, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 12, 0, 0, 0), -(20375, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 1000, 0), -(20705, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0), -(20911, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0), -(21185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(21882, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0), -(21890, 0, 4, 712396527, 876, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(22618, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(22648, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0), -(23547, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0), -(23548, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(23551, 0, 11, 192, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(23552, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3000, 0), -(23572, 0, 11, 192, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(23578, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0), -(23581, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0), -(23686, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0), -(23688, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(23689, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 4, 0, 0, 0), -(23721, 0, 9, 2048, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(23920, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(24353, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(24389, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(24905, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 15, 0, 0, 0), -(25050, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(25669, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0), -(25899, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 0), -(26107, 0, 7, 8388608, 268435584, 0, 0, 0, 2, 116, 0, 0, 0, 0, 0), -(26119, 0, 0, 2416967683, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(26128, 0, 0, 0, 0, 0, 0, 0, 2, 8, 0, 0, 0, 0, 0), -(26135, 0, 10, 8388608, 0, 0, 16, 0, 2, 0, 2, 0, 0, 0, 0), -(26480, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(26605, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 0, 0, 0), -(27419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), -(27498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), -(27521, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 15000, 0), -(27656, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(27774, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0), -(27787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), -(28305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(28752, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(28802, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(28812, 0, 8, 33554438, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(28816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0), -(29150, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 1000, 0), -(29455, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(29501, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29624, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29625, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29626, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29632, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29633, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29634, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29635, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29636, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29637, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(29977, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(30003, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(30937, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(31394, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(31794, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(31904, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(32587, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(32642, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(32734, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3000, 0), -(32748, 0, 8, 0, 1, 0, 320, 0, 2, 0, 0, 0, 0, 0, 0), -(32776, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(32777, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(32837, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(32844, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0), -(32885, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(33089, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(33127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 1000, 0), -(33297, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(33299, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(33510, 0, 0, 0, 0, 0, 340, 1, 2, 0, 0, 3, 0, 0, 0), -(33648, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(33719, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(33746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(33759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(33953, 0, 0, 0, 0, 0, 279552, 2, 2, 0, 0, 0, 0, 45000, 0), -(34074, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(34080, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0), -(34138, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(34139, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(34258, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0), -(34262, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0), -(34320, 0, 0, 0, 0, 0, 0, 3, 2, 2, 0, 0, 0, 45000, 0), -(34355, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3000, 0), -(34584, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 30000, 0), -(34586, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1.5, 0, 0, 0), -(34598, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(34749, 0, 0, 0, 0, 0, 0, 0, 2, 8, 2, 0, 0, 0, 0), -(34774, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1.5, 0, 20000, 0), -(34783, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(34827, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3000, 0), -(35077, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 55000, 0), -(35080, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 55000, 0), -(35083, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 55000, 0), -(35086, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 55000, 0), -(35121, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(36032, 0, 3, 4096, 32768, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(36096, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(36111, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(36541, 4, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(37165, 0, 8, 2098176, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37170, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0), -(37173, 0, 8, 750519704, 262, 0, 0, 0, 2, 0, 0, 0, 0, 25000, 0), -(37189, 0, 10, 3221225472, 0, 0, 0, 0, 2, 2, 0, 0, 0, 60000, 0), -(37193, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(37195, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0), -(37197, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(37213, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(37214, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(37227, 0, 11, 448, 0, 0, 0, 0, 2, 2, 0, 0, 0, 60000, 0), -(37237, 0, 11, 1, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(37247, 8, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(37379, 32, 5, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37384, 0, 5, 1, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37443, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(37514, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0), -(37516, 0, 4, 1024, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37519, 0, 0, 0, 0, 0, 0, 0, 2, 48, 0, 0, 0, 0, 0), -(37523, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(37528, 0, 4, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37536, 0, 4, 65536, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37568, 0, 6, 2048, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(37600, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(37601, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(37655, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 60000, 0), -(37657, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 2500, 0), -(38026, 1, 0, 0, 0, 0, 0, 1, 0, 256, 0, 0, 0, 0, 0), -(38031, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(38290, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 1.6, 0, 0, 0), -(38299, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 12000, 0), -(38326, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(38327, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(38334, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 60000, 0), -(38347, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 45000, 0), -(38350, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(48504, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(39027, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3000, 0), -(39442, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0), -(39443, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(39530, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(39958, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0.7, 0, 40000, 0), -(40407, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(40444, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(40458, 0, 4, 33554432, 1537, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(40475, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 0, 0, 0), -(40482, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(40485, 0, 9, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(40899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), -(41034, 126, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 0), -(41260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(41262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(41381, 0, 0, 0, 0, 0, 0, 1, 0, 256, 0, 0, 0, 0, 0), -(41393, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0), -(41434, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 2, 0, 45000, 0), -(41469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 1000, 0), -(41989, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0.5, 0, 0, 0), -(42083, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(42135, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 90000, 0), -(42136, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 90000, 0), -(42368, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(42370, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43443, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(43726, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43728, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43737, 0, 7, 0, 1088, 0, 0, 0, 2, 0, 0, 0, 0, 10000, 0), -(43739, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43741, 0, 10, 2147483648, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43745, 0, 10, 0, 512, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43748, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43750, 0, 11, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(43819, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(44543, 0, 3, 1049120, 4096, 0, 0, 0, 1, 0, 2, 0, 7, 0, 0), -(44545, 0, 3, 1049120, 4096, 0, 0, 0, 1, 0, 2, 0, 15, 0, 0), -(45354, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(45355, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(45469, 0, 15, 16, 0, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0), -(45481, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(45482, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(45483, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(45484, 0, 0, 0, 0, 0, 16384, 2, 2, 0, 0, 0, 0, 45000, 0), -(46025, 32, 6, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(46092, 0, 10, 1073741824, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(46098, 0, 11, 128, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(46569, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(46662, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 20000, 0), -(46832, 0, 7, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(46910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.5, 0, 0, 0), -(46911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7.5, 0, 0, 0), -(47981, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(48833, 0, 7, 0, 1088, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(48835, 0, 10, 8388608, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0), -(48837, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(49592, 0, 0, 0, 0, 0, 8528552, 1, 0, 0, 0, 0, 0, 0, 0), -(49622, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 60000, 0), -(50240, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0), -(50421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(50781, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 6000, 0), -(51123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), -(51127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0), -(51128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0), -(51129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0), -(51130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0), -(51346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(51349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(51352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(51359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10000, 0), -(51414, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 45000, 0), -(51915, 0, 0, 0, 0, 0, 16777216, 0, 0, 0, 0, 0, 100, 600000, 0), -(52020, 0, 7, 32768, 1048576, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(52423, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0), -(52898, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(53386, 0, 15, 2182250279, 447, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(53397, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(54646, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(54695, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(54707, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 60000, 0), -(54738, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 45000, 0), -(54808, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 60000, 0), -(54838, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(54841, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 2500, 0), -(54925, 2, 10, 0, 512, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(55380, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0.7, 0, 40000, 0), -(55381, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 15000, 0), -(55640, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(55680, 0, 6, 512, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(55681, 0, 6, 32768, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(55689, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 0, 0, 0, 0), -(55747, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(55768, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(55776, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(56249, 0, 5, 0, 0, 1024, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(56355, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), -(56364, 0, 3, 0, 16777216, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(56451, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3000, 0), -(56816, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0), -(56817, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(56821, 0, 8, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(56841, 0, 9, 2048, 0, 0, 256, 0, 2, 0, 0, 0, 0, 0, 0), -(57345, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 45000, 0), -(57352, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(57907, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(57989, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(58357, 0, 4, 64, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(58364, 0, 4, 1024, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(58372, 0, 4, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(58386, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 0, 0, 0), -(58442, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 15000, 0), -(58444, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 5000, 0), -(58616, 0, 15, 16777216, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(58620, 0, 15, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(58626, 0, 15, 33554432, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(58901, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(59176, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0), -(59327, 0, 15, 134217728, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(59345, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(59630, 0, 0, 0, 0, 0, 69648, 5, 1, 0, 2, 0, 0, 35000, 0), -(59725, 0, 0, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0, 0), -(60063, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60066, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(60132, 0, 15, 16, 134348800, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60172, 0, 5, 262144, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60221, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 45000, 0), -(60301, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60306, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60317, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60436, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60442, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60473, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 45000, 0), -(60482, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(60490, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(60493, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(60503, 1, 4, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60519, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 45000, 0), -(60524, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60529, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 45000, 0), -(60537, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 45000, 0), -(60564, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60571, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60572, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60573, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60574, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60575, 0, 11, 2416967680, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60710, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60717, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60719, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60722, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60724, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60726, 0, 7, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60770, 0, 11, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60818, 0, 10, 0, 512, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(60826, 0, 15, 20971520, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(61324, 0, 10, 0, 131072, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(61356, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 90000, 0), -(61618, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(62114, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(62115, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(62147, 0, 15, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(62459, 0, 15, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(63086, 0, 9, 0, 0, 65536, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(63108, 0, 5, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(63251, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(63310, 0, 5, 0, 65536, 0, 65536, 0, 2, 0, 0, 0, 0, 0, 0), -(63335, 0, 15, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(63611, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 0, 0), -(64343, 0, 3, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64411, 0, 0, 0, 0, 0, 279552, 2, 2, 0, 0, 0, 0, 0, 0), -(64415, 0, 0, 0, 0, 0, 279552, 2, 2, 0, 0, 0, 0, 45000, 0), -(64440, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0), -(64571, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 10000, 0), -(64714, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(64738, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(64742, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(64786, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(64792, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(64860, 0, 9, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64867, 0, 3, 536870945, 4096, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64882, 0, 10, 0, 1048576, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64908, 0, 6, 8192, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64912, 0, 6, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64938, 0, 4, 2097216, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0), -(64952, 0, 7, 0, 1088, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64955, 0, 10, 0, 64, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64964, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64976, 0, 4, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(64999, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 0), -(65002, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(65005, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 45000, 0), -(65007, 0, 0, 0, 0, 0, 81920, 3, 1, 0, 0, 0, 0, 0, 0), -(65013, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(65020, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(65025, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(66808, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0), -(67115, 0, 15, 20971520, 0, 0, 0, 0, 2, 0, 0, 0, 0, 45000, 0), -(67151, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(67353, 0, 7, 32768, 1049856, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(67363, 0, 10, 2147483648, 0, 0, 0, 0, 2, 0, 0, 0, 0, 10000, 0), -(67379, 0, 10, 0, 262144, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(67381, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0, 10000, 0), -(67384, 0, 15, 16, 134348800, 0, 0, 0, 2, 0, 0, 0, 80, 10000, 0), -(67386, 0, 11, 1, 0, 0, 65536, 0, 1, 0, 0, 0, 0, 6000, 0), -(67389, 0, 11, 256, 0, 0, 16384, 0, 1, 0, 0, 0, 0, 8000, 0), -(67392, 0, 11, 0, 0, 4, 16, 0, 2, 0, 0, 0, 0, 0, 0), -(67653, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 50000, 0), -(67667, 0, 0, 0, 0, 0, 16384, 2, 1, 0, 0, 0, 0, 45000, 0), -(67670, 0, 0, 0, 0, 0, 65536, 1, 1, 0, 0, 0, 0, 45000, 0), -(67672, 0, 0, 0, 0, 0, 8388948, 1, 2, 0, 0, 0, 0, 45000, 0), -(67698, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(67702, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(67712, 0, 0, 0, 0, 0, 69632, 1, 2, 2, 0, 0, 0, 2000, 0), -(67752, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(67758, 0, 0, 0, 0, 0, 69632, 1, 2, 2, 0, 0, 0, 2000, 0), -(67771, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(68051, 1, 4, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(68160, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0), -(70188, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0), -(70652, 0, 15, 8, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(70727, 0, 9, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(70748, 0, 3, 0, 2097152, 0, 1024, 0, 2, 0, 0, 0, 0, 0, 0), -(70756, 0, 10, 0, 65536, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(70761, 0, 10, 0, 0, 1, 1024, 0, 2, 0, 0, 0, 0, 0, 0), -(70803, 0, 8, 4063232, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(70807, 0, 11, 0, 0, 16, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(70811, 0, 11, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(70830, 0, 11, 0, 131072, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(71186, 0, 10, 0, 32768, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(71191, 0, 10, 0, 65536, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0), -(71194, 0, 10, 0, 1048576, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(71214, 0, 11, 0, 16, 0, 16, 0, 2, 0, 0, 0, 0, 0, 0), -(71217, 0, 11, 0, 0, 16, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(71226, 0, 15, 16, 134348800, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(71228, 0, 15, 0, 536870912, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0), -(71402, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(71404, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 45000, 0), -(71540, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(71585, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 45000, 0), -(71602, 0, 0, 0, 0, 0, 65536, 1, 1, 0, 0, 0, 0, 45000, 0), -(71611, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 45000, 0), -(71642, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 45000, 0), -(71645, 0, 0, 0, 0, 0, 65536, 1, 1, 0, 0, 0, 0, 45000, 0), -(71903, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 12, 0, 0, 0), -(72413, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 10, 60000, 0), -(72417, 0, 0, 0, 0, 0, 327680, 1, 2, 0, 0, 0, 0, 60000, 0), -(72419, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 60000, 0), -(74396, 84, 3, 685904631, 1151048, 0, 65536, 0, 1, 0, 0, 0, 0, 0, 0), -(75455, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(75457, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 45000, 0), -(75465, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 45000, 0), -(75474, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 45000, 0), -(-12317, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(63057, 0, 7, 0, 262144, 0, 16384, 0, 2, 0, 0, 0, 0, 0, 0), -(71571, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(71573, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(71865, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0), -(71868, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0), -(75490, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0), -(75495, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 0), -(53651, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0), -(53257, 0, 9, 0, 268435456, 0, 16, 1, 2, 2, 8, 0, 0, 0, 0), -(-31226, 0, 8, 0, 524288, 0, 0, 5, 2, 0, 2, 0, 0, 0, 0), -(-51682, 0, 8, 0, 524288, 0, 0, 4, 2, 0, 2, 0, 0, 0, 0), -(53817, 0, 11, 451, 32768, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(12328, 0, 4, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(21084, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(5118, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(13159, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(-168, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0, 0, 0), -(-7302, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0, 0, 0), -(-30482, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0, 0, 0), -(17670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(50908, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(58501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(-1120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), -(-49200, 126, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0), -(41350, 0, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0), -(18708, 0, 5, 536870912, 0, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0), -(57529, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(57531, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(72059, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0, 0, 0), -(-11103, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(13234, 0, 0, 0, 0, 0, 0, 1, 0, 1027, 2, 0, 0, 0, 0), -(12043, 0, 3, 1631584309, 4096, 0, 0, 7, 1, 0, 8, 0, 0, 0, 0), -(16166, 0, 11, 3, 4096, 0, 0, 7, 1, 0, 8, 0, 0, 0, 0), -(17116, 0, 7, 268436065, 33554464, 32768, 0, 7, 1, 0, 8, 0, 0, 0, 0), -(-53583, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0), -(53515, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0), -(71993, 0, 0, 0, 0, 0, 4, 0, 0, 12287, 0, 0, 0, 4000, 0), -(35321, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0), -(38363, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0), -(39215, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0), -(45092, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(50871, 0, 9, 0, 1073741824, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0), -(32065, 0, 0, 0, 0, 0, 524288, 1, 0, 0, 0, 0, 0, 0, 0), -(36659, 0, 0, 0, 0, 0, 524288, 1, 0, 0, 0, 0, 0, 0, 0), -(4341, 0, 0, 0, 0, 0, 4096, 1, 1, 0, 0, 0, 0, 0, 0), -(70904, 0, 6, 0, 0, 2048, 2048, 4, 0, 0, 0, 0, 0, 0, 0), -(63849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), -(23591, 0, 10, 8388608, 0, 0, 16, 0, 2, 0, 2, 0, 0, 0, 0), -(-16689, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(-588, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0), -(-59887, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), -(71567, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 400, 0), -(-14143, 0, 8, 1191182854, 2097152, 0, 0, 1, 2, 0, 8, 0, 0, 0, 0), -(60617, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0), -(40816, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 7000, 0); - --- Threat of Thassarian triggered spells, for easier script access -DELETE FROM `spell_ranks` WHERE `first_spell_id` IN (59133,66198,66196,66216,66188,66215); -INSERT INTO `spell_ranks` (`first_spell_id`, `spell_id`, `rank`) VALUES -(66198, 66198, 1), -(66198, 66972, 2), -(66198, 66973, 3), -(66198, 66974, 4), - -(66196, 66196, 1), -(66196, 66958, 2), -(66196, 66959, 3), -(66196, 66960, 4), -(66196, 66961, 5), -(66196, 66962, 6), - -(66216, 66216, 1), -(66216, 66988, 2), -(66216, 66989, 3), -(66216, 66990, 4), -(66216, 66991, 5), -(66216, 66992, 6), - -(66188, 66188, 1), -(66188, 66950, 2), -(66188, 66951, 3), -(66188, 66952, 4), -(66188, 66953, 5), - -(66215, 66215, 1), -(66215, 66975, 2), -(66215, 66976, 3), -(66215, 66977, 4), -(66215, 66978, 5), -(66215, 66979, 6); - --- Remove renamed scripts -DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_gen_dummy_trigger','spell_pri_item_greater_heal_refund'); - --- Stop console spam from dummy EFFECT_2 proc -DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_pal_seals'; -INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES -(20375, 'spell_pal_seals'), -- Seal of Command -(21084, 'spell_pal_seals'), -- Seal of Righteousness -(31801, 'spell_pal_seals'), -- Seal of Vengeance -(31892, 'spell_pal_seals'), -- Seal of Blood -(33127, 'spell_pal_seals'), -- Seal of Command -(38008, 'spell_pal_seals'), -- Seal of Blood -(41459, 'spell_pal_seals'), -- Seal of Blood -(53720, 'spell_pal_seals'), -- Seal of the Martyr -(53736, 'spell_pal_seals'); -- Seal of Corruption - --- Grouped several hacks and handled with AuraScript now -DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_mage_fingers_of_frost'; -INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES -(74396, 'spell_mage_fingers_of_frost'); -- Fingers of Frost - --- Add spellscripts to spells previously on giant switches in Unit.cpp -DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_rog_t10_2p_bonus'; -DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_sha_flametongue_weapon','spell_mage_imp_blizzard','spell_warr_deep_wounds_aura','spell_rog_setup','spell_pri_improved_spirit_tap','spell_sha_imp_water_shield','spell_pal_improved_lay_of_hands','spell_pal_heart_of_the_crusader','spell_warl_seed_of_corruption_dummy','spell_mage_magic_absorption','spell_warr_extra_proc','spell_warr_second_wind','spell_warl_soul_leech','spell_sha_lightning_overload','spell_rog_quick_recovery','spell_mage_arcane_potency','spell_mage_empowered_fire','spell_pal_spiritual_attunement','spell_pal_divine_purpose','spell_pal_judgements_of_the_wise','spell_hun_thrill_of_the_hunt','spell_mage_missile_barrage','spell_mage_hot_streak','spell_pri_imp_shadowform','spell_dk_butchery','spell_item_unstable_power','spell_item_restless_strength','spell_pri_aq_3p_bonus','spell_item_persistent_shield','spell_dru_revitalize','spell_dk_scent_of_blood_trigger','spell_dk_vendetta','spell_dk_sudden_doom','spell_dk_blade_barrier','spell_dk_wandering_plague','spell_sha_astral_shift_aura','spell_dk_necrosis','spell_sha_static_shock','spell_sha_maelstrom_weapon','spell_sha_ancestral_awakening','spell_rog_deadly_brew','spell_rog_turn_the_tables','spell_rog_cut_to_the_chase','spell_pet_guard_dog','spell_hun_rapid_recuperation_trigger','spell_hun_hunting_party','spell_pal_infusion_of_light','spell_pal_judgements_of_the_just','spell_mage_burning_determination','spell_warr_improved_spell_reflection','spell_pet_culling_the_herd','spell_pet_silverback','spell_warl_decimation','spell_sha_frozen_power','spell_pri_body_and_soul','spell_dk_threat_of_thassarian','spell_warl_seduction','spell_mage_combustion','spell_pri_vampiric_embrace','spell_dru_omen_of_clarity','spell_item_alchemists_stone','spell_pal_judgement_of_light_heal','spell_pal_judgement_of_wisdom_mana','spell_twisted_reflection','spell_dru_t3_2p_bonus','spell_dru_t3_8p_bonus','spell_dru_t3_6p_bonus','spell_pal_t3_6p_bonus','spell_pri_t3_4p_bonus','spell_sha_t3_6p_bonus','spell_warr_t3_prot_8p_bonus','spell_item_healing_touch_refund','spell_item_totem_of_flowing_water','spell_sha_shamanistic_rage','spell_pal_seal_of_vengeance','spell_warl_seed_of_corruption_generic','spell_mark_of_malice','spell_item_mark_of_conquest','spell_sha_windfury_weapon','spell_dru_t4_2p_bonus','spell_pri_t5_heal_2p_bonus','spell_anetheron_vampiric_aura','spell_item_frozen_shadoweave','spell_item_aura_of_madness','spell_pri_item_t6_trinket','spell_dru_item_t6_trinket','spell_sha_item_t6_trinket','spell_pal_item_t6_trinket','spell_item_crystal_spire_of_karabor','spell_item_dementia','spell_item_pet_healing','spell_warl_t4_2p_bonus_shadow','spell_warl_t4_2p_bonus_fire','spell_mage_gen_extra_effects','spell_uk_second_wind','spell_item_sunwell_exalted_caster_neck','spell_item_sunwell_exalted_melee_neck','spell_item_sunwell_exalted_tank_neck','spell_item_sunwell_exalted_healer_neck','spell_warl_glyph_of_corruption_nightfall','spell_dk_mark_of_blood','spell_dk_dancing_rune_weapon','spell_dk_hungering_cold','spell_pal_sacred_shield_dummy','spell_warl_demonic_pact','spell_pal_seal_of_corruption','spell_dru_glyph_of_rejuvenation','spell_dru_glyph_of_shred','spell_dru_glyph_of_rake','spell_dru_glyph_of_innervate','spell_dru_glyph_of_starfire_dummy','spell_pal_glyph_of_holy_light_dummy','spell_pal_glyph_of_divinity','spell_sha_tidal_force_dummy','spell_sha_glyph_of_healing_wave','spell_pri_glyph_of_dispel_magic','spell_mage_glyph_of_icy_veins','spell_mage_glyph_of_polymorph','spell_rog_glyph_of_backstab','spell_hun_glyph_of_mend_pet','spell_pri_shadowfiend_death','spell_warr_glyph_of_blocking','spell_dk_glyph_of_scourge_strike','spell_sha_spirit_hunt','spell_hun_kill_command_pet','spell_item_swift_hand_justice_dummy','spell_item_discerning_eye_beast_dummy','spell_mage_imp_mana_gems','spell_dk_pvp_4p_bonus','spell_dru_savage_defense','spell_sha_glyph_of_earth_shield','spell_sha_glyph_of_totem_of_wrath','spell_warl_glyph_of_life_tap','spell_item_purified_shard_of_the_scale','spell_item_shiny_shard_of_the_scale','spell_dru_t10_balance_4p_bonus','spell_dru_t10_restoration_4p_bonus_dummy','spell_sha_t10_restoration_4p_bonus','spell_sha_t10_elemental_4p_bonus','spell_warr_item_t10_prot_4p_bonus','spell_item_tiny_abomination_in_a_jar','spell_item_tiny_abomination_in_a_jar_hero','spell_item_deadly_precision_dummy','spell_item_deadly_precision','spell_item_heartpierce','spell_item_heartpierce_hero','spell_item_deathbringers_will_normal','spell_item_deathbringers_will_heroic','spell_putricide_ooze_tank_protection','spell_deathbringer_blood_beast_blood_link'); -INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES -(-10400, 'spell_sha_flametongue_weapon'), -(-11185, 'spell_mage_imp_blizzard'), -(-12834, 'spell_warr_deep_wounds_aura'), -(-13983, 'spell_rog_setup'), -(-15337, 'spell_pri_improved_spirit_tap'), -(-16180, 'spell_sha_imp_water_shield'), -(-20234, 'spell_pal_improved_lay_of_hands'), -(-20335, 'spell_pal_heart_of_the_crusader'), -(-27243, 'spell_warl_seed_of_corruption_dummy'), -(-29441, 'spell_mage_magic_absorption'), - -(-29723, 'spell_warr_extra_proc'), -(-46913, 'spell_warr_extra_proc'), - -(-29834, 'spell_warr_second_wind'), -(-30293, 'spell_warl_soul_leech'), -(-30675, 'spell_sha_lightning_overload'), -(-31244, 'spell_rog_quick_recovery'), -(-31571, 'spell_mage_arcane_potency'), -(-31656, 'spell_mage_empowered_fire'), -(-31785, 'spell_pal_spiritual_attunement'), -(-31871, 'spell_pal_divine_purpose'), -(-31876, 'spell_pal_judgements_of_the_wise'), -(-34497, 'spell_hun_thrill_of_the_hunt'), -(-44404, 'spell_mage_missile_barrage'), -(-44445, 'spell_mage_hot_streak'), -(-47569, 'spell_pri_imp_shadowform'), -(-48979, 'spell_dk_butchery'), -(-48539, 'spell_dru_revitalize'), - -(-49004, 'spell_dk_scent_of_blood_trigger'), -(-49015, 'spell_dk_vendetta'), -(-49018, 'spell_dk_sudden_doom'), -(-49182, 'spell_dk_blade_barrier'), -(-49217, 'spell_dk_wandering_plague'), -(-51474, 'spell_sha_astral_shift_aura'), -(-51459, 'spell_dk_necrosis'), -(-51525, 'spell_sha_static_shock'), -(-51556, 'spell_sha_ancestral_awakening'), -(-51625, 'spell_rog_deadly_brew'), -(-51627, 'spell_rog_turn_the_tables'), -(-51664, 'spell_rog_cut_to_the_chase'), -(-53178, 'spell_pet_guard_dog'), -(-53228, 'spell_hun_rapid_recuperation_trigger'), -(-53290, 'spell_hun_hunting_party'), -(-53569, 'spell_pal_infusion_of_light'), -(-53695, 'spell_pal_judgements_of_the_just'), -(-54747, 'spell_mage_burning_determination'), -(-59088, 'spell_warr_improved_spell_reflection'), -(-61680, 'spell_pet_culling_the_herd'), -(-62764, 'spell_pet_silverback'), -(-63156, 'spell_warl_decimation'), -(-63373, 'spell_sha_frozen_power'), -(-64127, 'spell_pri_body_and_soul'), -(-65661, 'spell_dk_threat_of_thassarian'), -(6358, 'spell_warl_seduction'), -(11129, 'spell_mage_combustion'), -(15286, 'spell_pri_vampiric_embrace'), -(16864, 'spell_dru_omen_of_clarity'), -(17619, 'spell_item_alchemists_stone'), -(20185, 'spell_pal_judgement_of_light_heal'), -(20186, 'spell_pal_judgement_of_wisdom_mana'), -(21063, 'spell_twisted_reflection'), -(24658, 'spell_item_unstable_power'), -(24661, 'spell_item_restless_strength'), -(26169, 'spell_pri_aq_3p_bonus'), -(26467, 'spell_item_persistent_shield'), -(28716, 'spell_dru_t3_2p_bonus'), -(28719, 'spell_dru_t3_8p_bonus'), -(28744, 'spell_dru_t3_6p_bonus'), -(28789, 'spell_pal_t3_6p_bonus'), -(28809, 'spell_pri_t3_4p_bonus'), -(28823, 'spell_sha_t3_6p_bonus'), -(28845, 'spell_warr_t3_prot_8p_bonus'), -(28847, 'spell_item_healing_touch_refund'), -(28849, 'spell_item_totem_of_flowing_water'), -(30823, 'spell_sha_shamanistic_rage'), -(31801, 'spell_pal_seal_of_vengeance'), - -(32863, 'spell_warl_seed_of_corruption_generic'), -(36123, 'spell_warl_seed_of_corruption_generic'), -(38252, 'spell_warl_seed_of_corruption_generic'), -(39367, 'spell_warl_seed_of_corruption_generic'), -(44141, 'spell_warl_seed_of_corruption_generic'), -(70388, 'spell_warl_seed_of_corruption_generic'), - -(33493, 'spell_mark_of_malice'), -(33510, 'spell_item_mark_of_conquest'), -(33757, 'spell_sha_windfury_weapon'), -(37288, 'spell_dru_t4_2p_bonus'), -(37295, 'spell_dru_t4_2p_bonus'), -(37594, 'spell_pri_t5_heal_2p_bonus'), -(38196, 'spell_anetheron_vampiric_aura'), -(39372, 'spell_item_frozen_shadoweave'), -(39446, 'spell_item_aura_of_madness'), -(40438, 'spell_pri_item_t6_trinket'), -(40442, 'spell_dru_item_t6_trinket'), -(40463, 'spell_sha_item_t6_trinket'), -(40470, 'spell_pal_item_t6_trinket'), -(40971, 'spell_item_crystal_spire_of_karabor'), -(41404, 'spell_item_dementia'), - -(37381, 'spell_item_pet_healing'), - -(37377, 'spell_warl_t4_2p_bonus_shadow'), -(39437, 'spell_warl_t4_2p_bonus_fire'), - -(44401, 'spell_mage_gen_extra_effects'), -(48108, 'spell_mage_gen_extra_effects'), -(57761, 'spell_mage_gen_extra_effects'), - -(42770, 'spell_uk_second_wind'), -(45481, 'spell_item_sunwell_exalted_caster_neck'), -(45482, 'spell_item_sunwell_exalted_melee_neck'), -(45483, 'spell_item_sunwell_exalted_tank_neck'), -(45484, 'spell_item_sunwell_exalted_healer_neck'), - -(-18094, 'spell_warl_glyph_of_corruption_nightfall'), -(56218, 'spell_warl_glyph_of_corruption_nightfall'), - -(49005, 'spell_dk_mark_of_blood'), -(49028, 'spell_dk_dancing_rune_weapon'), -(51209, 'spell_dk_hungering_cold'), - -(53601, 'spell_pal_sacred_shield_dummy'), - -(53646, 'spell_warl_demonic_pact'), -(54909, 'spell_warl_demonic_pact'), - -(53736, 'spell_pal_seal_of_corruption'), -(53817, 'spell_sha_maelstrom_weapon'), -(54748, 'spell_mage_burning_determination'), -(54754, 'spell_dru_glyph_of_rejuvenation'), -(54815, 'spell_dru_glyph_of_shred'), -(54821, 'spell_dru_glyph_of_rake'), -(54832, 'spell_dru_glyph_of_innervate'), -(54845, 'spell_dru_glyph_of_starfire_dummy'), -(54937, 'spell_pal_glyph_of_holy_light_dummy'), -(54939, 'spell_pal_glyph_of_divinity'), -(55198, 'spell_sha_tidal_force_dummy'), -(55440, 'spell_sha_glyph_of_healing_wave'), -(55677, 'spell_pri_glyph_of_dispel_magic'), -(56374, 'spell_mage_glyph_of_icy_veins'), -(56375, 'spell_mage_glyph_of_polymorph'), -(56800, 'spell_rog_glyph_of_backstab'), -(57870, 'spell_hun_glyph_of_mend_pet'), -(57989, 'spell_pri_shadowfiend_death'), -(58375, 'spell_warr_glyph_of_blocking'), -(58642, 'spell_dk_glyph_of_scourge_strike'), -(58877, 'spell_sha_spirit_hunt'), -(58914, 'spell_hun_kill_command_pet'), -(59906, 'spell_item_swift_hand_justice_dummy'), -(59915, 'spell_item_discerning_eye_beast_dummy'), - -(37447, 'spell_mage_imp_mana_gems'), -(61062, 'spell_mage_imp_mana_gems'), - -(61257, 'spell_dk_pvp_4p_bonus'), -(62600, 'spell_dru_savage_defense'), -(63279, 'spell_sha_glyph_of_earth_shield'), -(63280, 'spell_sha_glyph_of_totem_of_wrath'), -(63320, 'spell_warl_glyph_of_life_tap'), -(69755, 'spell_item_purified_shard_of_the_scale'), -(69739, 'spell_item_shiny_shard_of_the_scale'), -(70723, 'spell_dru_t10_balance_4p_bonus'), -(70664, 'spell_dru_t10_restoration_4p_bonus_dummy'), -(70808, 'spell_sha_t10_restoration_4p_bonus'), -(70817, 'spell_sha_t10_elemental_4p_bonus'), -(70844, 'spell_warr_item_t10_prot_4p_bonus'), - -(71406, 'spell_item_tiny_abomination_in_a_jar'), -(71545, 'spell_item_tiny_abomination_in_a_jar_hero'), - -(71563, 'spell_item_deadly_precision_dummy'), -(71564, 'spell_item_deadly_precision'), - -(71880, 'spell_item_heartpierce'), -(71892, 'spell_item_heartpierce_hero'), - -(71519, 'spell_item_deathbringers_will_normal'), -(71562, 'spell_item_deathbringers_will_heroic'), - -(61685, 'spell_pet_charge'), -(-49200, 'spell_dk_acclimation'), -(70656, 'spell_dk_advantage_t10_4p'), -(37336, 'spell_dru_forms_trinket'), -(67353, 'spell_dru_t9_feral_relic'), -(13567, 'spell_gen_dummy_trigger'), -(-53234, 'spell_hun_piercing_shots'), -(67151, 'spell_hun_t9_4p_bonus'), -(-31641, 'spell_mage_blazing_speed'), -(-20210, 'spell_pal_illumination'), -(-27811, 'spell_pri_blessed_recovery'), -(37594, 'spell_pri_item_greater_heal_refund'), -(-47580, 'spell_pri_pain_and_suffering_dummy'), -(-324, 'spell_sha_lightning_shield'), -(-30881, 'spell_sha_nature_guardian'), -(-30299, 'spell_warl_nether_protection'), -(60510, 'spell_item_soul_preserver'), -(67702, 'spell_item_death_choice'), -(67771, 'spell_item_death_choice'), -(37657, 'spell_item_lightning_capacitor'), -(54841, 'spell_item_thunder_capacitor'), -(67712, 'spell_item_toc25_normal_caster_trinket'), -(67758, 'spell_item_toc25_heroic_caster_trinket'), -(57345, 'spell_item_darkmoon_card_greatness'), -(43820, 'spell_item_charm_witch_doctor'), -(27522, 'spell_item_mana_drain'), -(40336, 'spell_item_mana_drain'), - -(71770, 'spell_putricide_ooze_tank_protection'), -(72176, 'spell_deathbringer_blood_beast_blood_link'); - --- Kill the damned thing already! -DROP TABLE IF EXISTS `spell_proc_event`; diff --git a/data/sql/updates/pending_db_world/rev_1664980163888388800.sql b/data/sql/updates/pending_db_world/rev_1664980163888388800.sql new file mode 100644 index 0000000000..d7baaa4027 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1664980163888388800.sql @@ -0,0 +1,2950 @@ +-- +-- Restoring spell_proc to how it was before the commit. +DROP TABLE IF EXISTS `spell_proc`; +CREATE TABLE IF NOT EXISTS `spell_proc` ( + `spellId` MEDIUMINT(9) NOT NULL DEFAULT '0', + `schoolMask` TINYINT(4) NOT NULL DEFAULT '0', + `spellFamilyName` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0', + `spellFamilyMask0` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `spellFamilyMask1` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `spellFamilyMask2` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `typeMask` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `spellTypeMask` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `spellPhaseMask` INT(11) NOT NULL DEFAULT '0', + `hitMask` INT(11) NOT NULL DEFAULT '0', + `attributesMask` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `ratePerMinute` FLOAT NOT NULL DEFAULT '0', + `chance` FLOAT NOT NULL DEFAULT '0', + `cooldown` FLOAT NOT NULL DEFAULT '0', + `charges` INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`spellId`) +) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4; + +-- Restoring spell_script_names to how it was before the commit +DROP TABLE IF EXISTS `spell_script_names`; +CREATE TABLE IF NOT EXISTS `spell_script_names` ( + `spell_id` INT(11) NOT NULL, + `ScriptName` CHAR(64) NOT NULL, + UNIQUE KEY `spell_id` (`spell_id`,`ScriptName`) +) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4; + +DELETE FROM `spell_script_names`; + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(-62900, 'spell_dk_death_coil'), +(-61391, 'spell_dru_typhoon'), +(-58872, 'spell_warr_damage_shield'), +(-56342, 'spell_hun_lock_and_load'), +(-55428, 'spell_gen_lifeblood'), +(-55090, 'spell_dk_scourge_strike'), +(-54347, 'spell_warl_improved_demonic_tactics'), +(-53302, 'spell_hun_sniper_training'), +(-52284, 'spell_dk_will_of_the_necropolis'), +(-51940, 'spell_sha_earthliving_weapon'), +(-51685, 'spell_rog_prey_on_the_weak'), +(-51490, 'spell_sha_thunderstorm'), +(-51474, 'spell_sha_astral_shift'), +(-51123, 'spell_gen_no_offhand_proc'), +(-50391, 'spell_dk_improved_unholy_presence'), +(-50384, 'spell_dk_improved_frost_presence'), +(-50365, 'spell_dk_improved_blood_presence'), +(-50294, 'spell_dru_starfall_aoe'), +(-50286, 'spell_dru_starfall_dummy'), +(-49998, 'spell_dk_death_strike'), +(-49821, 'spell_pri_mind_sear'), +(-49219, 'spell_dk_blood_caked_blade'), +(-49217, 'spell_dk_wandering_plague_aura'), +(-49188, 'spell_gen_no_offhand_proc'), +(-49158, 'spell_dk_corpse_explosion'), +(-49145, 'spell_dk_spell_deflection'), +(-49004, 'spell_dk_scent_of_blood_trigger'), +(-49004, 'spell_gen_proc_from_direct_damage'), +(-48721, 'spell_dk_blood_boil'), +(-48496, 'spell_dru_living_seed'), +(-48438, 'spell_dru_wild_growth'), +(-48181, 'spell_warl_haunt'), +(-47897, 'spell_warl_shadowflame'), +(-47541, 'spell_dk_death_coil'), +(-47540, 'spell_pri_penance'), +(-47509, 'spell_pri_divine_aegis'), +(-47230, 'spell_warl_fel_synergy'), +(-44546, 'spell_mage_brain_freeze'), +(-44543, 'spell_mage_fingers_of_frost_proc_aura'), +(-44457, 'spell_mage_living_bomb'), +(-44450, 'spell_mage_burnout_trigger'), +(-44449, 'spell_mage_burnout'), +(-43265, 'spell_dk_death_and_decay'), +(-42243, 'spell_hun_volley_trigger'), +(-35696, 'spell_warl_demonic_knowledge'), +(-35541, 'spell_rog_combat_potency'), +(-34914, 'spell_pri_vampiric_touch'), +(-34861, 'spell_pri_circle_of_healing'), +(-33872, 'spell_dru_nurturing_instinct'), +(-33851, 'spell_dru_primal_tenacity'), +(-33763, 'spell_dru_lifebloom'), +(-32379, 'spell_pri_shadow_word_death'), +(-31850, 'spell_pal_ardent_defender'), +(-31228, 'spell_rog_cheat_death'), +(-31130, 'spell_rog_nerves_of_steel'), +(-30706, 'spell_sha_totem_of_wrath'), +(-30482, 'spell_mage_molten_armor'), +(-30451, 'spell_mage_arcane_blast'), +(-30143, 'spell_warl_demonic_aegis'), +(-30108, 'spell_warl_unstable_affliction'), +(-29074, 'spell_mage_master_of_elements'), +(-27285, 'spell_warl_seed_of_corruption'), +(-24869, 'spell_gen_holiday_buff_food'), +(-20473, 'spell_pal_holy_shock'), +(-19572, 'spell_hun_improved_mend_pet'), +(-19386, 'spell_hun_wyvern_sting'), +(-17002, 'spell_dru_feral_swiftness'), +(-16972, 'spell_dru_predatory_strikes'), +(-16257, 'spell_sha_flurry_proc'), +(-12317, 'spell_gen_proc_from_direct_damage'), +(-12162, 'spell_warr_deep_wounds'), +(-11426, 'spell_mage_ice_barrier'), +(-11119, 'spell_mage_ignite'), +(-11113, 'spell_mage_blast_wave'), +(-9799, 'spell_pal_eye_for_an_eye'), +(-8050, 'spell_sha_flame_shock'), +(-7001, 'spell_pri_lightwell_renew'), +(-6229, 'spell_warl_shadow_ward'), +(-6201, 'spell_warl_create_healthstone'), +(-6143, 'spell_mage_fire_frost_ward'), +(-5570, 'spell_dru_insect_swarm'), +(-5308, 'spell_warr_execute'), +(-5217, 'spell_dru_tiger_s_fury'), +(-2818, 'spell_rog_deadly_poison'), +(-1943, 'spell_rog_rupture'), +(-1850, 'spell_dru_dash'), +(-1535, 'spell_sha_fire_nova'), +(-1464, 'spell_warr_slam'), +(-1463, 'spell_mage_mana_shield'), +(-1454, 'spell_warl_life_tap'), +(-1120, 'spell_warl_drain_soul'), +(-1079, 'spell_dru_rip'), +(-1064, 'spell_sha_chain_heal'), +(-974, 'spell_sha_earth_shield'), +(-772, 'spell_warr_rend'), +(-755, 'spell_hun_check_pet_los'), +(-755, 'spell_warl_health_funnel'), +(-746, 'spell_gen_bandage'), +(-710, 'spell_warl_banish'), +(-633, 'spell_pal_lay_on_hands'), +(-603, 'spell_warl_curse_of_doom'), +(-543, 'spell_mage_fire_frost_ward'), +(-139, 'spell_pri_renew'), +(-136, 'spell_hun_check_pet_los'), +(-100, 'spell_warr_charge'), +(-17, 'spell_pri_power_word_shield'), +(126, 'spell_warl_eye_of_kilrogg'), +(605, 'spell_pri_mind_control'), +(694, 'spell_warr_mocking_blow'), +(698, 'spell_warl_ritual_of_summoning'), +(781, 'spell_hun_disengage'), +(802, 'spell_mutate_explode_bug'), +(804, 'spell_mutate_explode_bug'), +(818, 'spell_gen_basic_campfire'), +(1038, 'spell_pal_hand_of_salvation'), +(1090, 'spell_item_magic_dust'), +(1178, 'spell_dru_bear_form_passive'), +(1515, 'spell_hun_tame_beast'), +(1742, 'spell_hun_cower'), +(2825, 'spell_sha_bloodlust'), +(3411, 'spell_warr_intervene'), +(4073, 'spell_gen_allow_cast_from_item_only'), +(4338, 'spell_q13280_13283_plant_battle_standard'), +(5024, 'spell_item_skull_of_impeding_doom'), +(5229, 'spell_dru_enrage'), +(5246, 'spell_warr_intimidating_shout'), +(5487, 'spell_dru_feral_swiftness'), +(5938, 'spell_rog_shiv'), +(6358, 'spell_warl_seduction'), +(6474, 'spell_sha_earthbind_totem'), +(6495, 'spell_sha_sentry_totem'), +(6870, 'spell_gen_moss_covered_feet'), +(6940, 'spell_pal_hand_of_sacrifice'), +(6962, 'spell_gen_pet_summoned'), +(7054, 'spell_shadowfang_keep_forsaken_skills'), +(7057, 'spell_shadowfang_keep_haunting_spirits'), +(7102, 'spell_contagion_of_rot'), +(7215, 'spell_item_with_mount_speed'), +(7384, 'spell_warr_overpower'), +(7434, 'spell_item_fate_rune_of_unsurpassed_vigor'), +(7887, 'spell_warr_overpower'), +(7932, 'spell_item_anti_venom'), +(7933, 'spell_item_strong_anti_venom'), +(8063, 'spell_item_deviate_fish'), +(8067, 'spell_item_party_time'), +(8129, 'spell_pri_mana_burn'), +(8171, 'spell_sha_cleansing_totem_pulse'), +(8213, 'spell_item_savory_deviate_delight'), +(8342, 'spell_item_goblin_jumper_cables'), +(8344, 'spell_item_gnomish_universal_remote'), +(8593, 'spell_symbol_of_life_dummy'), +(8856, 'spell_q1846_bending_shinbone'), +(8913, 'spell_q55_sacred_cleansing'), +(9204, 'spell_gen_hate_to_zero'), +(9634, 'spell_dru_feral_swiftness'), +(9635, 'spell_dru_bear_form_passive'), +(9712, 'spell_q2203_thaumaturgy_channel'), +(9771, 'spell_gnomeregan_radiation_bolt'), +(10101, 'spell_gen_knock_away'), +(10247, 'spell_zulfarrak_summon_zulfarrak_zombies'), +(10255, 'spell_uldaman_stoned'), +(10340, 'spell_uldaman_boss_agro_archaedas'), +(10738, 'spell_zulfarrak_unlocking'), +(11568, 'spell_uldaman_sub_boss_agro_keepers'), +(11584, 'spell_warr_overpower'), +(11585, 'spell_warr_overpower'), +(11885, 'spell_item_muisek_vessel'), +(11886, 'spell_item_muisek_vessel'), +(11887, 'spell_item_muisek_vessel'), +(11888, 'spell_item_muisek_vessel'), +(11889, 'spell_item_muisek_vessel'), +(11958, 'spell_mage_cold_snap'), +(12021, 'spell_scholomance_fixate'), +(12328, 'spell_warr_sweeping_strikes'), +(12346, 'spell_temple_of_atal_hakkar_awaken_the_soulflayer'), +(12479, 'spell_temple_of_atal_hakkar_hex_of_jammal_an'), +(12749, 'spell_gen_allow_cast_from_item_only'), +(12809, 'spell_warr_concussion_blow'), +(12975, 'spell_warr_last_stand'), +(13006, 'spell_item_gnomish_shrink_ray'), +(13120, 'spell_item_net_o_matic'), +(13161, 'spell_hun_aspect_of_the_beast'), +(13166, 'spell_gen_allow_cast_from_item_only'), +(13180, 'spell_item_mind_amplify_dish'), +(13258, 'spell_gen_allow_cast_from_item_only'), +(13280, 'spell_item_gnomish_death_ray'), +(13567, 'spell_gen_dummy_trigger'), +(13877, 'spell_rog_blade_flurry'), +(14185, 'spell_rog_preparation'), +(14537, 'spell_item_six_demon_bag'), +(15366, 'spell_gen_disabled_above_63'), +(15600, 'spell_gen_proc_reduced_above_60'), +(15712, 'spell_item_linken_boomerang'), +(15748, 'spell_item_freeze_rookery_egg'), +(15958, 'spell_q4735_collect_rookery_egg'), +(15998, 'spell_gen_despawn_self'), +(16028, 'spell_item_freeze_rookery_egg'), +(16349, 'spell_blackrock_spire_call_of_vaelastrasz'), +(16372, 'spell_gyth_chromatic_protection'), +(16414, 'spell_item_wraith_scythe_drain_life'), +(16589, 'spell_item_noggenfogger_elixir'), +(16796, 'spell_q5056_summon_shy_rotam'), +(16864, 'spell_dru_omen_of_clarity'), +(17009, 'spell_voodoo'), +(17179, 'spell_scholomance_boon_of_life'), +(17251, 'spell_gen_spirit_healer_res'), +(17271, 'spell_q5206_test_fetid_skull'), +(17512, 'spell_item_piccolo_of_the_flaming_fire'), +(18173, 'spell_vael_burning_adrenaline'), +(18277, 'spell_onslaught_or_call_bone_gryphon'), +(18541, 'spell_warl_ritual_of_doom_effect'), +(18670, 'spell_vem_knockback'), +(18765, 'spell_warr_sweeping_strikes'), +(18813, 'spell_gen_knock_away'), +(18945, 'spell_gen_knock_away'), +(19395, 'spell_gordunni_trap'), +(19411, 'spell_magmadar_lava_bomb'), +(19512, 'spell_q6124_6129_apply_salve'), +(19515, 'spell_garr_frenzy'), +(19548, 'spell_hun_tame_beast'), +(19574, 'spell_hun_bestial_wrath'), +(19577, 'spell_hun_intimidation'), +(19593, 'spell_egg_explosion'), +(19597, 'spell_hun_taming_the_beast'), +(19633, 'spell_gen_knock_away'), +(19674, 'spell_hun_tame_beast'), +(19676, 'spell_hun_taming_the_beast'), +(19677, 'spell_hun_taming_the_beast'), +(19678, 'spell_hun_taming_the_beast'), +(19679, 'spell_hun_taming_the_beast'), +(19680, 'spell_hun_taming_the_beast'), +(19681, 'spell_hun_taming_the_beast'), +(19682, 'spell_hun_taming_the_beast'), +(19683, 'spell_hun_taming_the_beast'), +(19684, 'spell_hun_taming_the_beast'), +(19685, 'spell_hun_taming_the_beast'), +(19686, 'spell_hun_taming_the_beast'), +(19687, 'spell_hun_tame_beast'), +(19688, 'spell_hun_tame_beast'), +(19689, 'spell_hun_tame_beast'), +(19692, 'spell_hun_tame_beast'), +(19693, 'spell_hun_tame_beast'), +(19694, 'spell_hun_tame_beast'), +(19695, 'spell_geddon_inferno'), +(19696, 'spell_hun_tame_beast'), +(19697, 'spell_hun_tame_beast'), +(19699, 'spell_hun_tame_beast'), +(19700, 'spell_hun_tame_beast'), +(19753, 'spell_pal_divine_intervention'), +(19774, 'spell_summon_ragnaros'), +(19804, 'spell_gen_allow_cast_from_item_only'), +(19822, 'spell_mc_play_dead'), +(19873, 'spell_egg_event'), +(20004, 'spell_gen_reduced_above_60'), +(20005, 'spell_gen_reduced_above_60'), +(20007, 'spell_gen_reduced_above_60'), +(20154, 'spell_pal_seal_of_righteousness'), +(20165, 'spell_pal_seal_of_light'), +(20166, 'spell_pal_seal_of_light'), +(20230, 'spell_warr_retaliation'), +(20271, 'spell_pal_judgement_of_light'), +(20375, 'spell_pal_seal_of_command'), +(20424, 'spell_pal_seal_of_command'), +(20425, 'spell_pal_judgement_of_command'), +(20474, 'spell_magmadar_lava_bomb'), +(20478, 'spell_geddon_armageddon'), +(20538, 'spell_hate_to_zero'), +(20577, 'spell_gen_cannibalize'), +(20589, 'spell_gen_remove_impairing_auras'), +(20625, 'spell_gen_default_count_pct_from_max_hp'), +(20631, 'spell_gen_use_spell_base_level_check'), +(20686, 'spell_gen_knock_away'), +(20911, 'spell_gen_damage_reduction_aura'), +(20911, 'spell_pal_blessing_of_sanctuary'), +(21084, 'spell_pal_seal_of_righteousness'), +(21094, 'spell_majordomo_separation_nexiety'), +(21108, 'spell_ragnaros_summon_sons_of_flame'), +(21147, 'spell_arcane_vacuum'), +(21149, 'spell_item_eggnog'), +(21708, 'spell_gen_visual_dummy_stun'), +(21737, 'spell_gen_periodic_knock_away'), +(21809, 'spell_gen_random_target32'), +(21848, 'spell_item_snowman'), +(21908, 'spell_ragnaros_lava_burst_randomizer'), +(22247, 'spell_suppression_aura'), +(22276, 'spell_gen_elemental_shield'), +(22282, 'spell_gen_brood_power'), +(22539, 'spell_bwl_shadowflame'), +(22563, 'spell_item_recall'), +(22564, 'spell_item_recall'), +(22659, 'spell_spawn_drakonid'), +(22664, 'spell_shadowblink'), +(22803, 'spell_gen_random_target32'), +(22812, 'spell_dru_barkskin'), +(22821, 'spell_gen_random_target32'), +(22888, 'spell_gen_disabled_above_63'), +(22888, 'spell_gen_rallying_cry_of_the_dragonslayer'), +(22999, 'spell_item_goblin_jumper_cables_xl'), +(23019, 'spell_item_crystal_prison_dummy_dnd'), +(23074, 'spell_item_arcanite_dragonling'), +(23075, 'spell_item_mithril_mechanical_dragonling'), +(23076, 'spell_item_mechanical_dragonling'), +(23133, 'spell_item_gnomish_battle_chicken'), +(23134, 'spell_item_goblin_bomb'), +(23138, 'spell_shazzrah_gate_dummy'), +(23183, 'spell_mark_of_frost_freeze'), +(23397, 'spell_class_call_handler'), +(23398, 'spell_class_call_handler'), +(23401, 'spell_class_call_handler'), +(23410, 'aura_class_call_wild_magic'), +(23410, 'spell_class_call_handler'), +(23414, 'spell_class_call_handler'), +(23418, 'aura_class_call_siphon_blessing'), +(23418, 'spell_class_call_handler'), +(23424, 'spell_corrupted_totems'), +(23425, 'spell_class_call_handler'), +(23427, 'spell_class_call_handler'), +(23436, 'spell_class_call_handler'), +(23448, 'spell_gen_gadgetzan_transporter_backfire'), +(23453, 'spell_gen_gnomish_transporter'), +(23487, 'spell_garr_separation_nexiety'), +(23551, 'spell_sha_item_lightning_shield'), +(23552, 'spell_sha_item_lightning_shield_trigger'), +(23567, 'spell_gen_bandage'), +(23568, 'spell_gen_bandage'), +(23569, 'spell_gen_bandage'), +(23572, 'spell_sha_item_mana_surge'), +(23603, 'spell_class_call_polymorph'), +(23696, 'spell_gen_bandage'), +(23780, 'spell_item_aegis_of_preservation'), +(23786, 'spell_item_powerful_anti_venom'), +(23878, 'spell_random_aggro'), +(23880, 'spell_warr_bloodthirst_heal'), +(23881, 'spell_warr_bloodthirst'), +(23970, 'spell_batrider_bomb'), +(23989, 'spell_hun_readiness'), +(24083, 'spell_hatch_eggs'), +(24084, 'spell_marli_transform'), +(24110, 'spell_enveloping_webs'), +(24306, 'spell_delusions_of_jindo'), +(24314, 'spell_threatening_gaze'), +(24315, 'spell_threatening_gaze_charge'), +(24324, 'spell_blood_siphon'), +(24325, 'spell_pagles_point_cast'), +(24326, 'spell_gahzranka_slam'), +(24401, 'spell_gen_model_visible'), +(24408, 'spell_mandokir_charge'), +(24412, 'spell_gen_bandage'), +(24413, 'spell_gen_bandage'), +(24414, 'spell_gen_bandage'), +(24531, 'spell_item_refocus'), +(24590, 'spell_item_brittle_armor'), +(24684, 'spell_chain_burn'), +(24693, 'spell_hakkar_power_down'), +(24717, 'spell_hallows_end_pirate_costume'), +(24718, 'spell_hallows_end_ninja_costume'), +(24719, 'spell_hallows_end_leper_costume'), +(24720, 'spell_hallows_end_trick'), +(24737, 'spell_hallows_end_ghost_costume'), +(24750, 'spell_hallows_end_trick'), +(24751, 'spell_hallows_end_trick_or_treat'), +(24778, 'spell_dream_fog_sleep'), +(24834, 'spell_shadow_bolt_whirl'), +(24905, 'spell_dru_moonkin_form_passive_proc'), +(24930, 'spell_hallows_end_candy'), +(24983, 'spell_gen_baby_murloc_passive'), +(24984, 'spell_gen_baby_murloc'), +(25042, 'spell_mark_of_nature'), +(25153, 'spell_aggro_drones'), +(25177, 'spell_crystal_weakness'), +(25178, 'spell_crystal_weakness'), +(25180, 'spell_crystal_weakness'), +(25181, 'spell_crystal_weakness'), +(25183, 'spell_crystal_weakness'), +(25185, 'spell_itch_aq20'), +(25281, 'spell_gen_turkey_marker'), +(25371, 'spell_consume_aq20'), +(25373, 'spell_gen_10pct_count_pct_from_max_hp'), +(25599, 'spell_rajaxx_thundercrash'), +(25671, 'spell_drain_mana'), +(25676, 'spell_moam_mana_drain_filter'), +(25684, 'spell_moam_summon_mana_fiends'), +(25711, 'spell_ayamiss_swarmer_start_loop'), +(25755, 'spell_drain_mana'), +(25778, 'spell_gen_knock_away'), +(25790, 'spell_vem_vengeance'), +(25830, 'spell_ayamiss_swarmer_teleport_trigger'), +(25833, 'spell_gen_ayamiss_swarmer_loop_1'), +(25834, 'spell_gen_ayamiss_swarmer_loop_2'), +(25835, 'spell_gen_ayamiss_swarmer_loop_3'), +(25844, 'spell_ayamiss_swarmer_swarm'), +(25860, 'spell_item_reindeer_transformation'), +(25899, 'spell_gen_damage_reduction_aura'), +(25899, 'spell_pal_blessing_of_sanctuary'), +(25938, 'spell_explode_trigger'), +(25952, 'spell_gen_despawn_self'), +(26052, 'spell_huhuran_poison_bolt'), +(26077, 'spell_itch_aq40'), +(26180, 'spell_huhuran_wyvern_sting'), +(26192, 'spell_skeram_arcane_explosion'), +(26218, 'spell_winter_veil_mistletoe'), +(26275, 'spell_winter_wondervolt_trap'), +(26374, 'spell_gen_elune_candle'), +(26400, 'spell_item_arcane_shroud'), +(26465, 'spell_item_mercurial_shield'), +(26546, 'spell_aq_shadow_storm'), +(26552, 'spell_nullify'), +(26555, 'spell_aq_shadow_storm'), +(26584, 'spell_summon_toxin_slime'), +(26678, 'spell_item_create_heart_candy'), +(27539, 'spell_gen_obsidian_armor'), +(27686, 'spell_razelikh_teleport_group'), +(27687, 'spell_kormok_summon_bone_minions'), +(27695, 'spell_kormok_summon_bone_mages'), +(27769, 'spell_gen_whisper_gulch_yogg_saron_whisper'), +(27808, 'spell_kelthuzad_frost_blast'), +(27819, 'spell_kelthuzad_detonate_mana'), +(27831, 'spell_gothik_shadow_bolt_volley'), +(27867, 'spell_gen_disabled_above_70'), +(28062, 'spell_thaddius_pos_neg_charge'), +(28085, 'spell_thaddius_pos_neg_charge'), +(28089, 'spell_thaddius_polarity_shift'), +(28169, 'spell_grobbulus_mutating_injection'), +(28241, 'spell_grobbulus_poison'), +(28305, 'spell_pri_mana_leech'), +(28374, 'spell_gluth_decimate'), +(28441, 'spell_item_ashbringer'), +(28524, 'spell_sapphiron_frost_explosion'), +(28682, 'spell_mage_combustion_proc'), +(28702, 'spell_gen_netherbloom'), +(28720, 'spell_gen_nightmare_vine'), +(28764, 'spell_gen_adaptive_warding'), +(28832, 'spell_four_horsemen_mark'), +(28833, 'spell_four_horsemen_mark'), +(28834, 'spell_four_horsemen_mark'), +(28835, 'spell_four_horsemen_mark'), +(28845, 'spell_warr_t3_prot_8p_bonus'), +(28862, 'spell_item_the_eye_of_diminution'), +(28865, 'spell_four_horsemen_consumption'), +(28880, 'spell_gen_gift_of_naaru'), +(29142, 'spell_gen_default_count_pct_from_max_hp'), +(29166, 'spell_dru_innervate'), +(29200, 'spell_item_purify_helboar_meat'), +(29266, 'spell_gen_creature_permanent_feign_death'), +(29341, 'spell_warl_shadowburn'), +(29431, 'spell_gen_select_target_count_15_1'), +(29431, 'spell_moroes_vanish'), +(29435, 'spell_gen_despawn_self'), +(29519, 'spell_silithyst'), +(29768, 'spell_karazhan_overload'), +(29830, 'spell_item_mirrens_drinking_hat'), +(29858, 'spell_warl_soulshatter'), +(29866, 'spell_q9452_cast_net'), +(29883, 'spell_gen_select_target_count_15_1'), +(29883, 'spell_karazhan_blink'), +(30099, 'spell_hun_tame_beast'), +(30100, 'spell_hun_taming_the_beast'), +(30102, 'spell_hun_tame_beast'), +(30103, 'spell_hun_taming_the_beast'), +(30104, 'spell_hun_taming_the_beast'), +(30105, 'spell_hun_tame_beast'), +(30205, 'spell_gen_visual_dummy_stun'), +(30410, 'spell_magtheridon_shadow_grasp'), +(30458, 'spell_item_nigh_invulnerability'), +(30505, 'spell_tsh_shadow_bolt'), +(30507, 'spell_item_poultryizer'), +(30541, 'spell_magtheridon_blaze'), +(30646, 'spell_hun_tame_beast'), +(30647, 'spell_hun_taming_the_beast'), +(30648, 'spell_hun_taming_the_beast'), +(30652, 'spell_hun_taming_the_beast'), +(30653, 'spell_hun_tame_beast'), +(30654, 'spell_hun_tame_beast'), +(30693, 'spell_vazruden_call_nazan'), +(30735, 'spell_tsh_shadow_sear'), +(30914, 'spell_broggok_poison_cloud'), +(30918, 'spell_gen_remove_impairing_auras'), +(30926, 'spell_vazruden_fireball'), +(30952, 'spell_tsh_shoot_flame_arrow'), +(31225, 'spell_item_shimmering_vessel'), +(31261, 'spell_gen_creature_permanent_feign_death'), +(31326, 'spell_black_morass_corrupt_medivh'), +(31389, 'spell_gen_knock_away'), +(31399, 'spell_gen_moss_covered_feet'), +(31427, 'spell_gen_allergies'), +(31447, 'spell_mark_of_kazrogal'), +(31687, 'spell_mage_summon_water_elemental'), +(31696, 'spell_q12943_shadow_vault_decree'), +(31789, 'spell_pal_righteous_defense'), +(31884, 'spell_pal_avenging_wrath'), +(31984, 'spell_finger_of_death'), +(32111, 'spell_red_sky_effect'), +(32146, 'spell_q9874_liquid_fire'), +(32182, 'spell_sha_heroism'), +(32441, 'spell_karazhan_brittle_bones'), +(32727, 'spell_gen_bg_preparation'), +(32826, 'spell_mage_polymorph_cast_visual'), +(32830, 'spell_auchenai_possess'), +(32959, 'spell_gen_knock_away'), +(32960, 'spell_mark_of_kazzak'), +(33060, 'spell_item_make_a_wish'), +(33110, 'spell_pri_prayer_of_mending_heal'), +(33401, 'spell_auchenai_possess'), +(33525, 'spell_gruul_ground_slam'), +(33654, 'spell_gruul_shatter'), +(33666, 'spell_murmur_sonic_boom_effect'), +(33671, 'spell_gruul_shatter_effect'), +(33695, 'spell_pal_exorcism_and_holy_wrath_damage'), +(33735, 'spell_rog_blade_flurry'), +(33793, 'spell_vazruden_fireball'), +(33794, 'spell_vazruden_fireball'), +(33896, 'spell_item_desperate_defense'), +(33953, 'spell_item_essence_of_life'), +(34074, 'spell_hun_ascpect_of_the_viper'), +(34098, 'spell_gen_clear_debuffs'), +(34133, 'spell_alar_ember_blast'), +(34201, 'spell_botanica_shift_form'), +(34229, 'spell_alar_flame_quills'), +(34246, 'spell_dru_idol_lifebloom'), +(34341, 'spell_alar_ember_blast_death'), +(34428, 'spell_warr_victory_rush'), +(34438, 'spell_warl_unstable_affliction'), +(34439, 'spell_warl_unstable_affliction'), +(34477, 'spell_hun_misdirection'), +(34719, 'spell_midnight_fixate'), +(34803, 'spell_commander_sarannis_summon_reinforcements'), +(34852, 'spell_botanica_call_of_the_falcon'), +(34902, 'spell_hun_generic_scaling'), +(34903, 'spell_hun_generic_scaling'), +(34904, 'spell_hun_generic_scaling'), +(34947, 'spell_warl_generic_scaling'), +(34956, 'spell_warl_generic_scaling'), +(34957, 'spell_warl_generic_scaling'), +(34958, 'spell_warl_generic_scaling'), +(35035, 'spell_the_eye_countercharge'), +(35079, 'spell_hun_misdirection_proc'), +(35139, 'spell_gen_default_count_pct_from_max_hp'), +(35183, 'spell_warl_unstable_affliction'), +(35201, 'spell_gen_paralytic_poison'), +(35268, 'spell_ragin_flames_inferno'), +(35354, 'spell_hand_of_death'), +(35356, 'spell_gen_creature_permanent_feign_death'), +(35357, 'spell_gen_creature_permanent_feign_death'), +(35367, 'spell_alar_dive_bomb'), +(35429, 'spell_warr_sweeping_strikes'), +(35657, 'spell_mage_pet_scaling'), +(35658, 'spell_mage_pet_scaling'), +(35659, 'spell_mage_pet_scaling'), +(35660, 'spell_mage_pet_scaling'), +(35661, 'spell_pri_shadowfiend_scaling'), +(35662, 'spell_pri_shadowfiend_scaling'), +(35663, 'spell_pri_shadowfiend_scaling'), +(35664, 'spell_pri_shadowfiend_scaling'), +(35665, 'spell_sha_fire_elemental_scaling'), +(35666, 'spell_sha_fire_elemental_scaling'), +(35667, 'spell_sha_fire_elemental_scaling'), +(35668, 'spell_sha_fire_elemental_scaling'), +(35669, 'spell_dru_treant_scaling'), +(35670, 'spell_dru_treant_scaling'), +(35671, 'spell_dru_treant_scaling'), +(35672, 'spell_dru_treant_scaling'), +(35674, 'spell_sha_feral_spirit_scaling'), +(35675, 'spell_sha_feral_spirit_scaling'), +(35676, 'spell_sha_feral_spirit_scaling'), +(35745, 'spell_item_socrethars_stone'), +(35865, 'spell_kaelthas_summon_nether_vapor'), +(35869, 'spell_kaelthas_nether_beam'), +(35941, 'spell_kaelthas_gravity_lapse'), +(36186, 'spell_warl_infernal_scaling'), +(36188, 'spell_warl_infernal_scaling'), +(36189, 'spell_warl_infernal_scaling'), +(36190, 'spell_warl_infernal_scaling'), +(36444, 'spell_wintergrasp_water'), +(36448, 'spell_gen_focused_bursts'), +(36450, 'spell_kaelthas_resurrection'), +(36475, 'spell_gen_focused_bursts'), +(36500, 'spell_gen_throw_back'), +(36573, 'spell_q10525_vision_guide'), +(36709, 'spell_kaelthas_kael_phase_two'), +(36720, 'spell_kaelthas_burn'), +(36730, 'spell_kaelthas_flame_strike'), +(36778, 'spell_arcatraz_soul_steal'), +(36785, 'spell_quest_test_flight_charging'), +(36797, 'spell_kaelthas_mind_control'), +(36860, 'spell_quest_test_flight_charging'), +(36890, 'spell_item_dimensional_ripper_area52'), +(36921, 'spell_vazruden_fireball'), +(36976, 'spell_kaelthas_summon_weapons'), +(37025, 'spell_serpentshrine_cavern_coilfang_water'), +(37027, 'spell_kaelthas_remote_toy'), +(37065, 'spell_q10036_torgos'), +(37097, 'spell_q10563_q10596_to_legion_hold'), +(37408, 'spell_oscillating_field'), +(37430, 'spell_lurker_below_spout'), +(37433, 'spell_lurker_below_spout_cone'), +(37506, 'spell_hun_scatter_shot'), +(37594, 'spell_pri_item_greater_heal_refund'), +(37641, 'spell_leotheras_whirlwind'), +(37674, 'spell_leotheras_chaos_blast'), +(37676, 'spell_leotheras_insidious_whisper'), +(37705, 'spell_item_eye_of_gruul_healing_discount'), +(37716, 'spell_leotheras_demon_link'), +(37727, 'spell_gen_charmed_unit_spell_cooldown'), +(37750, 'spell_leotheras_clear_consuming_madness'), +(37851, 'spell_gen_charmed_unit_spell_cooldown'), +(37853, 'spell_black_morass_corrupt_medivh'), +(37877, 'spell_pal_blessing_of_faith'), +(37917, 'spell_gen_charmed_unit_spell_cooldown'), +(37918, 'spell_gen_charmed_unit_spell_cooldown'), +(37919, 'spell_gen_charmed_unit_spell_cooldown'), +(37934, 'spell_hydross_cleansing_field_command'), +(37935, 'spell_hydross_cleansing_field_aura'), +(38017, 'spell_gen_select_target_count_7_1'), +(38028, 'spell_morogrim_tidewalker_watery_grave'), +(38055, 'spell_q10612_10613_the_fel_and_the_furious'), +(38112, 'spell_lady_vashj_magic_barrier'), +(38140, 'spell_gen_select_target_count_7_1'), +(38173, 'spell_q10714_on_spirits_wings'), +(38215, 'spell_hydross_mark_of_hydross'), +(38219, 'spell_hydross_mark_of_hydross'), +(38223, 'spell_q10769_dissension_amongst_the_ranks'), +(38224, 'spell_q10769_dissension_amongst_the_ranks'), +(38241, 'spell_gen_select_target_count_7_1'), +(38248, 'spell_gen_select_target_count_7_1'), +(38441, 'spell_gen_50pct_count_pct_from_max_hp'), +(38443, 'spell_sha_totemic_mastery'), +(38451, 'spell_karathress_power_of_caribdis'), +(38462, 'spell_broggok_poison_cloud'), +(38494, 'spell_lady_vashj_summon_sporebat'), +(38573, 'spell_gen_select_target_count_15_1'), +(38573, 'spell_lady_vashj_spore_drop_effect'), +(38629, 'spell_q10720_the_smallest_creature'), +(38633, 'spell_gen_select_target_count_15_1'), +(38650, 'spell_gen_select_target_count_15_1'), +(38724, 'spell_q10838_demoniac_scryer_visual'), +(38776, 'spell_q9718_crow_transform'), +(38795, 'spell_murmur_sonic_boom_effect'), +(39032, 'spell_serpentshrine_cavern_infection'), +(39042, 'spell_serpentshrine_cavern_infection'), +(39044, 'spell_serpentshrine_cavern_serpentshrine_parasite'), +(39053, 'spell_serpentshrine_cavern_serpentshrine_parasite_trigger'), +(39090, 'spell_capacitus_polarity_charge'), +(39093, 'spell_capacitus_polarity_charge'), +(39096, 'spell_capacitus_polarity_shift'), +(39117, 'spell_astromancer_solarian_transform'), +(39166, 'spell_q10898_skywing'), +(39187, 'spell_gruul_ground_slam_trigger'), +(39228, 'spell_gen_absorb0_hitlimit1'), +(39238, 'spell_q10929_fumping'), +(39239, 'spell_q10923_evil_draws_near_summon'), +(39246, 'spell_q10930_big_bone_worm'), +(39256, 'spell_q10923_evil_draws_near_visual'), +(39257, 'spell_q10923_evil_draws_near_visual'), +(39259, 'spell_q10923_evil_draws_near_periodic'), +(39346, 'spell_ragin_flames_inferno'), +(39365, 'spell_murmur_thundering_storm'), +(39371, 'spell_q10935_the_exorcism_of_colonel_jules'), +(39495, 'spell_lady_vashj_remove_tainted_cores'), +(39575, 'spell_black_temple_charge_rage'), +(39610, 'spell_sha_mana_tide_totem'), +(39635, 'spell_illidan_glaive_throw'), +(39645, 'spell_black_temple_shadow_inferno'), +(39672, 'spell_gen_select_target_count_15_1'), +(39832, 'spell_q10985_light_of_the_naaru'), +(39844, 'spell_q11010_q11102_q11023_q11008_check_fly_mount'), +(39848, 'spell_morogrim_tidewalker_water_globule_new_target'), +(39849, 'spell_illidan_glaive_throw'), +(39857, 'spell_illidan_tear_of_azzinoth_summon_channel'), +(39948, 'spell_najentus_hurl_spine'), +(39953, 'spell_gen_adals_song_of_battle'), +(39992, 'spell_najentus_needle_spine'), +(40056, 'spell_q11010_q11102_q11023_choose_loc'), +(40081, 'spell_black_template_free_friend'), +(40084, 'spell_black_template_harpooners_mark'), +(40112, 'spell_q11010_q11102_q11023_aggro_check'), +(40113, 'spell_q11010_q11102_q11023_aggro_check_aura'), +(40119, 'spell_q11010_q11102_q11023_aggro_burst'), +(40121, 'spell_dru_swift_flight_passive'), +(40132, 'spell_gen_summon_earth_elemental'), +(40133, 'spell_gen_summon_fire_elemental'), +(40157, 'spell_teron_gorefiend_spirit_lance'), +(40160, 'spell_q11010_q11102_q11023_q11008_check_fly_mount'), +(40251, 'spell_teron_gorefiend_shadow_of_death'), +(40268, 'spell_teron_gorefiend_spiritual_vengeance'), +(40326, 'spell_teron_gorefiend_shadowy_construct'), +(40398, 'spell_illidan_demon_transform2'), +(40401, 'spell_shade_of_akama_shade_soul_channel'), +(40414, 'spell_gen_fixate'), +(40486, 'spell_gurtogg_eject'), +(40511, 'spell_illidan_demon_transform1'), +(40638, 'spell_item_sleepy_willy'), +(40647, 'spell_illidan_shadow_prison'), +(40760, 'spell_illidan_cage_trap_stun'), +(40761, 'spell_illidan_cage_trap'), +(40802, 'spell_item_mingos_fortune_generator'), +(40816, 'spell_mother_shahraz_saber_lash'), +(40825, 'spell_q11026_a11051_banish_the_demons'), +(40828, 'spell_q11026_a11051_banish_the_demons'), +(40846, 'spell_npc22275_crystal_prison'), +(40851, 'spell_gen_select_target_count_7_1'), +(40854, 'spell_shade_of_akama_akama_soul_expel'), +(40855, 'spell_shade_of_akama_akama_soul_expel'), +(40856, 'spell_q11065_wrangle_some_aether_rays'), +(40862, 'spell_mother_shahraz_beam_periodic'), +(40863, 'spell_mother_shahraz_beam_periodic'), +(40865, 'spell_mother_shahraz_beam_periodic'), +(40866, 'spell_mother_shahraz_beam_periodic'), +(40867, 'spell_mother_shahraz_random_periodic'), +(40869, 'spell_mother_shahraz_fatal_attraction'), +(40870, 'spell_mother_shahraz_fatal_attraction_dummy'), +(40890, 'spell_quest_dragonmaw_race_generic'), +(40892, 'spell_gen_fixate'), +(40894, 'spell_quest_dragonmaw_race_generic'), +(40904, 'spell_illidan_draw_soul'), +(40909, 'spell_quest_dragonmaw_race_generic'), +(40928, 'spell_quest_dragonmaw_race_generic'), +(40930, 'spell_quest_dragonmaw_race_generic'), +(40945, 'spell_quest_dragonmaw_race_generic'), +(41001, 'spell_mother_shahraz_fatal_attraction_aura'), +(41034, 'spell_black_temple_spell_absorption'), +(41054, 'spell_gen_clone_weapon_aura'), +(41055, 'spell_gen_clone_weapon'), +(41072, 'spell_black_temple_bloodbolt'), +(41081, 'spell_gen_select_target_count_15_1'), +(41082, 'spell_illidan_found_target'), +(41126, 'spell_illidan_flame_burst'), +(41170, 'spell_black_temple_curse_of_the_bleakheart'), +(41171, 'spell_black_temple_skeleton_shot'), +(41172, 'spell_gen_select_target_count_24_1'), +(41186, 'spell_black_temple_wyvern_sting'), +(41213, 'spell_gen_throw_shield'), +(41248, 'spell_black_temple_consuming_strikes'), +(41292, 'spell_reliquary_of_souls_aura_of_suffering'), +(41294, 'spell_reliquary_of_souls_fixate'), +(41337, 'spell_reliquary_of_souls_aura_of_anger'), +(41341, 'spell_illidari_council_balance_of_power'), +(41350, 'spell_reliquary_of_souls_aura_of_desire'), +(41351, 'spell_black_temple_curse_of_vitality'), +(41357, 'spell_gen_select_target_count_15_1'), +(41360, 'spell_gen_100pct_count_pct_from_max_hp'), +(41376, 'spell_reliquary_of_souls_spite'), +(41404, 'spell_black_temple_dementia'), +(41467, 'spell_illidari_council_judgement'), +(41475, 'spell_illidari_council_reflective_shield'), +(41480, 'spell_illidari_council_deadly_strike'), +(41499, 'spell_illidari_council_empyreal_balance'), +(41621, 'spell_q11117_catch_the_wild_wolpertinger'), +(41914, 'spell_illidan_parasitic_shadowfiend_trigger'), +(41917, 'spell_illidan_parasitic_shadowfiend'), +(41920, 'spell_brewfest_fill_keg'), +(41921, 'spell_brewfest_unfill_keg'), +(41943, 'spell_brewfest_unfill_keg'), +(41944, 'spell_brewfest_unfill_keg'), +(41945, 'spell_brewfest_unfill_keg'), +(41946, 'spell_brewfest_unfill_keg'), +(42005, 'spell_gurtogg_bloodboil'), +(42074, 'spell_hallows_end_base_fire'), +(42268, 'spell_gen_despawn_self'), +(42300, 'spell_brewfest_add_mug'), +(42339, 'spell_hallows_end_bucket_lands'), +(42393, 'spell_gen_default_count_pct_from_max_hp'), +(42436, 'spell_brewfest_toss_mug'), +(42485, 'spell_ooze_zap_channel_end'), +(42489, 'spell_ooze_zap'), +(42492, 'spell_energize_aoe'), +(42578, 'spell_q11198_take_down_tethyr'), +(42672, 'spell_frost_tomb'), +(42760, 'spell_item_goblin_gumbo_kettle'), +(42783, 'spell_astromancer_wrath_of_the_astromancer'), +(42992, 'spell_brewfest_ram_fatigue'), +(42993, 'spell_brewfest_ram_fatigue'), +(42994, 'spell_brewfest_ram_fatigue'), +(43042, 'spell_item_summon_or_dismiss'), +(43102, 'spell_item_summon_or_dismiss'), +(43263, 'spell_dk_aotd_taunt'), +(43310, 'spell_brewfest_main_ram_buff'), +(43332, 'spell_brewfest_ram_fatigue'), +(43351, 'spell_q11322_q11317_the_cleansing'), +(43416, 'spell_gen_throw_shield'), +(43421, 'spell_hexlord_lifebloom'), +(43450, 'spell_brewfest_apple_trap'), +(43522, 'spell_hexlord_unstable_affliction'), +(43714, 'spell_brewfest_relay_race_force_cast'), +(43723, 'spell_item_demon_broiled_surprise'), +(43874, 'spell_q11396_11399_force_shield_arcane_purple_x3'), +(43882, 'spell_q11396_11399_scourging_crystal_controller_dummy'), +(43907, 'spell_brewfest_reveler_transform'), +(43908, 'spell_brewfest_reveler_transform'), +(43909, 'spell_brewfest_reveler_transform'), +(43910, 'spell_brewfest_reveler_transform'), +(43911, 'spell_brewfest_reveler_transform'), +(43912, 'spell_brewfest_reveler_transform'), +(43913, 'spell_brewfest_reveler_transform'), +(43914, 'spell_brewfest_reveler_transform'), +(43915, 'spell_brewfest_reveler_transform'), +(43916, 'spell_brewfest_reveler_transform'), +(43917, 'spell_brewfest_reveler_transform'), +(44003, 'spell_brewfest_reveler_transform'), +(44004, 'spell_brewfest_reveler_transform'), +(44094, 'spell_brewfest_reveler_transform'), +(44096, 'spell_brewfest_reveler_transform'), +(44198, 'spell_mt_phoenix_burn'), +(44337, 'spell_brewfest_reveler_transform'), +(44338, 'spell_brewfest_reveler_transform'), +(44436, 'spell_hallows_end_tricky_treat'), +(44521, 'spell_gen_bg_preparation'), +(44811, 'spell_kalecgos_spectral_realm_dummy'), +(44869, 'spell_kalecgos_spectral_blast_dummy'), +(44875, 'spell_item_complete_raptor_capture'), +(44935, 'spell_q11520_discovering_your_roots'), +(44936, 'spell_q11515_fel_siphon_dummy'), +(45032, 'spell_kalecgos_curse_of_boundless_agony'), +(45042, 'spell_item_shifting_naaru_silver'), +(45043, 'spell_item_shifting_naaru_silver'), +(45072, 'spell_gen_arcane_charge'), +(45102, 'spell_love_is_in_the_air_romantic_picnic'), +(45141, 'spell_brutallus_burn'), +(45151, 'spell_brutallus_burn'), +(45202, 'spell_item_rocket_chicken'), +(45204, 'spell_gen_clone'), +(45205, 'spell_gen_clone_weapon_aura'), +(45206, 'spell_gen_clone_weapon'), +(45208, 'spell_item_dragon_kite_summon_lightning_bunny'), +(45235, 'spell_eredar_twins_apply_flame_touched'), +(45235, 'spell_eredar_twins_blaze'), +(45246, 'spell_eredar_twins_apply_flame_touched'), +(45248, 'spell_eredar_twins_apply_dark_touched'), +(45253, 'spell_item_dragon_kite_summon_lightning_bunny'), +(45256, 'spell_eredar_twins_apply_dark_touched'), +(45270, 'spell_eredar_twins_apply_dark_touched'), +(45271, 'spell_eredar_twins_apply_dark_touched'), +(45329, 'spell_eredar_twins_apply_dark_touched'), +(45342, 'spell_eredar_twins_apply_flame_touched'), +(45347, 'spell_eredar_twins_handle_touch'), +(45348, 'spell_eredar_twins_handle_touch'), +(45406, 'spell_midsummer_ribbon_pole'), +(45449, 'spell_q11587_arcane_prisoner_rescue'), +(45472, 'spell_gen_parachute'), +(45524, 'spell_dk_chains_of_ice'), +(45625, 'spell_arcane_chains_character_force_cast'), +(45644, 'spell_midsummer_torch_catch'), +(45668, 'spell_q11653_youre_not_so_big_now'), +(45671, 'spell_midsummer_fling_torch'), +(45680, 'spell_gen_select_target_count_7_1'), +(45714, 'spell_felmyst_fog_of_corruption'), +(45716, 'spell_midsummer_torch_quest'), +(45717, 'spell_felmyst_fog_of_corruption_charm'), +(45737, 'spell_kiljaeden_flame_dart'), +(45742, 'spell_q11670_it_was_the_orcs_honest'), +(45759, 'spell_q11670_it_was_the_orcs_honest'), +(45785, 'spell_gen_clone'), +(45785, 'spell_kiljaeden_sinister_reflection_clone'), +(45819, 'spell_midsummer_juggling_torch'), +(45822, 'spell_gen_av_drekthar_presence'), +(45823, 'spell_gen_av_drekthar_presence'), +(45824, 'spell_gen_av_drekthar_presence'), +(45826, 'spell_gen_av_drekthar_presence'), +(45828, 'spell_gen_av_drekthar_presence'), +(45829, 'spell_gen_av_drekthar_presence'), +(45830, 'spell_gen_av_drekthar_presence'), +(45831, 'spell_gen_av_drekthar_presence'), +(45833, 'spell_kiljaeden_power_of_the_blue_flight'), +(45839, 'spell_kiljaeden_vengeance_of_the_blue_flight'), +(45853, 'spell_item_map_of_the_geyser_fields'), +(45856, 'spell_kiljaeden_dragon_breath'), +(45860, 'spell_kiljaeden_dragon_breath'), +(45892, 'spell_kiljaeden_sinister_reflection'), +(45909, 'spell_kiljaeden_armageddon_missile'), +(45921, 'spell_kiljaeden_armageddon_periodic'), +(45976, 'spell_gen_select_target_count_7_1'), +(45996, 'spell_muru_darkness'), +(45997, 'spell_q11719_bloodspore_ruination_45997'), +(46008, 'spell_gen_select_target_count_15_5'), +(46021, 'spell_kalecgos_spectral_realm'), +(46023, 'spell_q11730_ultrasonic_screwdriver'), +(46041, 'spell_muru_summon_blood_elves_periodic'), +(46203, 'spell_item_goblin_weather_machine'), +(46221, 'spell_gen_animal_blood'), +(46230, 'spell_entropius_black_hole_effect'), +(46265, 'spell_entropius_void_zone_visual'), +(46289, 'spell_entropius_negative_energy'), +(46292, 'spell_cataclysm_breath'), +(46337, 'spell_gen_crab_disguise'), +(46394, 'spell_gen_burn_brutallus'), +(46485, 'spell_item_greatmothers_soulcatcher'), +(46584, 'spell_dk_raise_dead'), +(46605, 'spell_kiljaeden_darkness'), +(46610, 'spell_madrigosa_activate_barrier'), +(46619, 'spell_dk_raise_ally_trigger'), +(46620, 'spell_q11919_q11940_drake_hunt'), +(46629, 'spell_gen_disabled_above_73'), +(46630, 'spell_midsummer_torch_quest'), +(46638, 'spell_madrigosa_deactivate_barrier'), +(46642, 'spell_gen_5000_gold'), +(46650, 'spell_felmyst_open_brutallus_back_doors'), +(46680, 'spell_kiljaeden_shadow_spike'), +(46736, 'spell_item_goblin_weather_machine'), +(46738, 'spell_item_goblin_weather_machine'), +(46739, 'spell_item_goblin_weather_machine'), +(46740, 'spell_item_goblin_weather_machine'), +(46747, 'spell_midsummer_fling_torch'), +(46771, 'spell_eredar_twins_apply_flame_touched'), +(47110, 'spell_image_of_drakuru_reagent_check'), +(47130, 'spell_q12014_steady_as_a_rock'), +(47170, 'spell_item_impale_leviroth'), +(47193, 'spell_warl_demonic_empowerment'), +(47336, 'spell_novos_crystal_handler_death'), +(47344, 'spell_request_second_mug'), +(47369, 'spell_send_mug_control_aura'), +(47370, 'spell_send_mug_target_picker'), +(47407, 'spell_direbrew_disarm'), +(47422, 'spell_warl_everlasting_affliction'), +(47496, 'spell_dk_ghoul_explode'), +(47530, 'spell_q12096_q12092_bark'), +(47575, 'spell_q12096_q12092_dummy'), +(47691, 'spell_direbrew_summon_mole_machine_target_picker'), +(47710, 'spell_boss_magus_telestra_summon_telestra_clones'), +(47764, 'spell_boss_magus_telestra_gravity_well'), +(47788, 'spell_pri_guardian_spirit'), +(47911, 'spell_gen_charmed_unit_spell_cooldown'), +(47948, 'spell_pri_pain_and_suffering_proc'), +(47977, 'spell_magic_broom'), +(48018, 'spell_warl_demonic_circle_summon'), +(48020, 'spell_warl_demonic_circle_teleport'), +(48025, 'spell_headless_horseman_mount'), +(48129, 'spell_item_scroll_of_recall'), +(48263, 'spell_dk_presence'), +(48265, 'spell_dk_presence'), +(48266, 'spell_dk_presence'), +(48277, 'spell_svala_ritual_strike'), +(48310, 'spell_transitus_shield_beam'), +(48363, 'spell_q12237_rescue_villager'), +(48388, 'spell_call_wintergarde_gryphon'), +(48391, 'spell_dru_owlkin_frenzy'), +(48397, 'spell_q12237_drop_off_villager'), +(48425, 'spell_gen_select_target_count_7_1'), +(48504, 'spell_dru_living_seed_proc'), +(48522, 'spell_q12243_fire_upon_the_waters'), +(48597, 'spell_dtk_raise_dead'), +(48605, 'spell_dtk_raise_dead'), +(48610, 'spell_shredder_delivery'), +(48620, 'spell_gen_charmed_unit_spell_cooldown'), +(48649, 'spell_item_fetch_ball'), +(48681, 'spell_q12308_escape_from_silverbrook_summon_worgen'), +(48682, 'spell_q12308_escape_from_silverbrook'), +(48707, 'spell_dk_anti_magic_shell_self'), +(48742, 'spell_q12277_wintergarde_mine_explosion'), +(48743, 'spell_dk_death_pact'), +(48762, 'spell_q12274_a_fall_from_grace_costume'), +(48776, 'spell_item_with_mount_speed'), +(48777, 'spell_item_with_mount_speed'), +(48792, 'spell_dk_icebound_fortitude'), +(48812, 'spell_renew_skirmisher'), +(48876, 'spell_utgarde_pinnacle_beast_mark'), +(48917, 'spell_q10041_q10040_who_are_they'), +(48920, 'spell_dred_grievious_bite'), +(49026, 'spell_gen_fixate'), +(49028, 'spell_dk_dancing_rune_weapon'), +(49107, 'spell_vehicle_warhead_fuse'), +(49181, 'spell_warhead_fuse'), +(49206, 'spell_dk_summon_gargoyle'), +(49222, 'spell_dk_bone_shield'), +(49250, 'spell_warhead_detonate'), +(49297, 'spell_winter_veil_racer_rocket_slam'), +(49325, 'spell_winter_veil_racer_slam_hit'), +(49345, 'spell_oculus_call_ruby_emerald_amber_drake'), +(49346, 'spell_oculus_rider_aura'), +(49357, 'spell_item_brewfest_mount_transformation'), +(49380, 'spell_trollgore_consume'), +(49405, 'spell_trollgore_invader_taunt'), +(49427, 'spell_oculus_ride_ruby_emerald_amber_drake_que'), +(49459, 'spell_oculus_ride_ruby_emerald_amber_drake_que'), +(49460, 'spell_oculus_rider_aura'), +(49461, 'spell_oculus_call_ruby_emerald_amber_drake'), +(49462, 'spell_oculus_call_ruby_emerald_amber_drake'), +(49463, 'spell_oculus_ride_ruby_emerald_amber_drake_que'), +(49464, 'spell_oculus_rider_aura'), +(49466, 'spell_item_direbrew_remote'), +(49527, 'spell_tharon_ja_curse_of_life'), +(49551, 'spell_tharon_ja_dummy'), +(49555, 'spell_trollgore_corpse_explode'), +(49560, 'spell_dk_death_grip'), +(49576, 'spell_dk_death_grip'), +(49587, 'spell_q12459_seeds_of_natures_wrath'), +(49592, 'spell_oculus_temporal_rift'), +(49642, 'spell_onslaught_or_call_bone_gryphon'), +(49761, 'spell_wintergrasp_rp_gg'), +(49817, 'spell_q12478_frostmourne_cavern'), +(49838, 'spell_oculus_stop_time'), +(49840, 'spell_oculus_shock_lance'), +(49882, 'spell_gen_default_count_pct_from_max_hp'), +(49889, 'spell_gen_clone'), +(49960, 'spell_dtk_summon_random_drakkari'), +(50133, 'spell_q11396_11399_scourging_crystal_controller'), +(50180, 'spell_item_draenic_pale_ale'), +(50218, 'spell_gen_clone'), +(50240, 'spell_oculus_evasive_maneuvers'), +(50241, 'spell_oculus_evasive_charges'), +(50243, 'spell_item_teach_language'), +(50278, 'spell_barreled_control_aura'), +(50325, 'spell_oculus_soar'), +(50334, 'spell_dru_berserk'), +(50341, 'spell_oculus_touch_the_nightmare'), +(50344, 'spell_oculus_dream_funnel'), +(50419, 'spell_dru_brambles_treant'), +(50421, 'spell_dk_scent_of_blood'), +(50452, 'spell_dk_bloodworms'), +(50453, 'spell_dk_blood_gorged'), +(50461, 'spell_dk_anti_magic_zone'), +(50462, 'spell_dk_anti_magic_shell_raid'), +(50526, 'spell_dk_wandering_plague'), +(50546, 'spell_q12066_bunny_kill_credit'), +(50630, 'spell_gen_eject_all_passengers'), +(50720, 'spell_warr_vigilance'), +(50725, 'spell_warr_vigilance_trigger'), +(50810, 'spell_krystallus_shatter'), +(50811, 'spell_krystallus_shatter_effect'), +(50842, 'spell_dk_pestilence'), +(50999, 'spell_wg_reduce_damage_by_distance'), +(51001, 'spell_hos_dark_matter'), +(51060, 'spell_gen_have_item_auras'), +(51068, 'spell_gen_have_item_auras'), +(51088, 'spell_gen_have_item_auras'), +(51094, 'spell_gen_have_item_auras'), +(51186, 'spell_item_summon_or_dismiss'), +(51188, 'spell_item_summon_or_dismiss'), +(51189, 'spell_item_summon_or_dismiss'), +(51190, 'spell_item_summon_or_dismiss'), +(51191, 'spell_item_summon_or_dismiss'), +(51192, 'spell_item_summon_or_dismiss'), +(51209, 'spell_dk_hungering_cold'), +(51211, 'spell_rog_blade_flurry'), +(51330, 'spell_q12589_shoot_rjr'), +(51403, 'spell_novos_despawn_crystal_handler'), +(51422, 'spell_wg_reduce_damage_by_distance'), +(51519, 'spell_death_knight_initiate_visual'), +(51582, 'spell_item_rocket_boots'), +(51592, 'spell_gen_despawn_self'), +(51640, 'spell_the_flag_of_ownership'), +(51690, 'spell_rog_killing_spree'), +(51719, 'spell_gen_clone'), +(51748, 'spell_gen_charmed_unit_spell_cooldown'), +(51752, 'spell_gen_charmed_unit_spell_cooldown'), +(51756, 'spell_gen_charmed_unit_spell_cooldown'), +(51769, 'spell_q12619_emblazon_runeblade'), +(51770, 'spell_q12619_emblazon_runeblade_effect'), +(51840, 'spell_q12634_despawn_fruit_tosser'), +(51854, 'spell_q12611_deathbolt'), +(51858, 'spell_q12641_death_comes_from_on_high'), +(51904, 'spell_q12641_death_comes_from_on_high_summon_ghouls'), +(51910, 'spell_gen_despawn_self'), +(51957, 'spell_q12620_the_lifewarden_wrath'), +(51961, 'spell_item_chicken_cover'), +(51963, 'spell_pet_dk_gargoyle_strike'), +(51996, 'spell_dk_pet_scaling'), +(52031, 'spell_sha_mana_spring_totem'), +(52033, 'spell_sha_mana_spring_totem'), +(52034, 'spell_sha_mana_spring_totem'), +(52035, 'spell_sha_mana_spring_totem'), +(52036, 'spell_sha_mana_spring_totem'), +(52041, 'spell_sha_healing_stream_totem'), +(52046, 'spell_sha_healing_stream_totem'), +(52047, 'spell_sha_healing_stream_totem'), +(52048, 'spell_sha_healing_stream_totem'), +(52049, 'spell_sha_healing_stream_totem'), +(52050, 'spell_sha_healing_stream_totem'), +(52086, 'spell_azjol_nerub_web_wrap'), +(52090, 'spell_q12659_ahunaes_knife'), +(52107, 'spell_wintergrasp_hide_small_elementals'), +(52143, 'spell_dk_master_of_ghouls'), +(52160, 'spell_shango_tracks'), +(52163, 'spell_shango_tracks'), +(52212, 'spell_dk_death_and_decay'), +(52249, 'spell_gen_visual_dummy_stun'), +(52267, 'spell_gen_despawn_self'), +(52278, 'spell_gen_visual_dummy_stun'), +(52308, 'spell_q12683_take_sputum_sample'), +(52375, 'spell_dk_death_coil'), +(52408, 'spell_gen_seaforium_blast'), +(52417, 'spell_item_massive_seaforium_charge'), +(52438, 'spell_gen_select_target_count_7_1'), +(52449, 'spell_gen_select_target_count_7_1'), +(52479, 'spell_q12698_the_gift_that_keeps_on_giving'), +(52481, 'spell_item_gift_of_the_harvester'), +(52510, 'spell_q12690_burst_at_the_seams'), +(52536, 'spell_azjol_nerub_fixate'), +(52551, 'spell_tur_ragepaw_lifebloom'), +(52610, 'spell_dru_savage_roar'), +(52708, 'spell_boss_salramm_steal_flesh'), +(52751, 'spell_dk_death_gate'), +(52759, 'spell_sha_ancestral_awakening_proc'), +(52845, 'spell_item_brewfest_mount_transformation'), +(52862, 'spell_q12726_song_of_wind_and_water'), +(52864, 'spell_q12726_song_of_wind_and_water'), +(52941, 'spell_q12735_song_of_cleansing'), +(52942, 'spell_loken_pulsing_shockwave'), +(53030, 'spell_hadronox_leech_poison'), +(53032, 'spell_gen_flurry_of_claws'), +(53035, 'spell_hadronox_summon_periodic_champion'), +(53036, 'spell_hadronox_summon_periodic_necromancer'), +(53037, 'spell_hadronox_summon_periodic_crypt_fiend'), +(53094, 'spell_infected_worgen_bite'), +(53110, 'spell_q12779_an_end_to_all_things'), +(53160, 'spell_dk_dancing_rune_weapon_visual'), +(53209, 'spell_hun_chimera_shot'), +(53242, 'spell_tharon_ja_clear_gift_of_tharon_ja'), +(53271, 'spell_hun_masters_call'), +(53350, 'spell_q12730_quenching_mist'), +(53365, 'spell_dk_rune_of_the_fallen_crusader'), +(53385, 'spell_pal_divine_storm'), +(53407, 'spell_pal_judgement_of_justice'), +(53408, 'spell_pal_judgement_of_wisdom'), +(53412, 'spell_hun_invigoration'), +(53457, 'spell_gen_select_target_count_15_1'), +(53458, 'spell_azjol_nerub_impale_summon'), +(53472, 'spell_azjol_nerub_pound'), +(53475, 'spell_gen_oracle_wolvar_reputation'), +(53478, 'spell_hun_last_stand_pet'), +(53487, 'spell_gen_oracle_wolvar_reputation'), +(53520, 'spell_azjol_nerub_carrion_beetels'), +(53601, 'spell_pal_sacred_shield_base'), +(53608, 'spell_cenarion_scout_lifebloom'), +(53642, 'spell_gen_area_aura_select_players'), +(53658, 'spell_chapter5_light_of_dawn_aura'), +(53680, 'spell_chapter5_rebuke'), +(53750, 'spell_item_crazy_alchemists_potion'), +(53768, 'spell_gen_haunted'), +(53797, 'spell_oculus_drake_flag'), +(53798, 'spell_azjol_nerub_fixate'), +(53808, 'spell_item_pygmy_oil'), +(54015, 'spell_gen_oracle_wolvar_reputation'), +(54044, 'spell_hun_pet_carrion_feeder'), +(54171, 'spell_pal_divine_storm_dummy'), +(54190, 'spell_q12805_lifeblood_dummy'), +(54307, 'spell_item_summon_argent_knight'), +(54355, 'spell_gen_mine_sweeper'), +(54363, 'spell_grobbulus_poison'), +(54396, 'spell_optic_link'), +(54420, 'spell_deliver_gryphon'), +(54426, 'spell_gluth_decimate'), +(54566, 'spell_dk_pet_scaling'), +(54646, 'spell_mage_focus_magic'), +(54729, 'spell_winged_steed_of_the_ebon_blade'), +(54732, 'spell_item_gnomish_army_knife'), +(54747, 'spell_mage_burning_determination'), +(54749, 'spell_mage_burning_determination'), +(54798, 'spell_q12851_going_bearback'), +(54801, 'spell_drakkari_colossus_surge'), +(54846, 'spell_dru_glyph_of_starfire'), +(54847, 'spell_gen_select_target_count_15_2'), +(54850, 'spell_drakkari_colossus_emerge'), +(54894, 'spell_gen_visual_dummy_stun'), +(54956, 'spell_galdarah_impaling_charge'), +(54968, 'spell_pal_glyph_of_holy_light'), +(54991, 'spell_drakkari_colossus_face_me'), +(54996, 'spell_gen_charmed_unit_spell_cooldown'), +(54997, 'spell_gen_charmed_unit_spell_cooldown'), +(55004, 'spell_item_nitro_boots'), +(55093, 'spell_sladran_grip_of_sladran'), +(55163, 'spell_moorabi_mojo_frenzy'), +(55233, 'spell_dk_vampiric_blood'), +(55269, 'spell_gen_default_count_pct_from_max_hp'), +(55299, 'spell_galdarah_transform'), +(55342, 'spell_mage_mirror_image'), +(55368, 'spell_q12661_q12669_q12676_q12677_q12713_summon_stefan'), +(55421, 'spell_q12919_gymers_throw'), +(55475, 'spell_gen_grow_flower_patch'), +(55516, 'spell_q12919_gymers_grab'), +(55638, 'spell_gothik_shadow_bolt_volley'), +(55640, 'spell_gen_allow_proc_from_spells_with_cost'), +(55680, 'spell_pri_glyph_of_prayer_of_healing'), +(55693, 'spell_q12823_remove_collapsing_cave_aura'), +(55709, 'spell_hun_pet_heart_of_the_phoenix'), +(55804, 'spell_q12937_relief_for_the_fallen'), +(55895, 'spell_prince_taldaram_flame_sphere_summon'), +(55931, 'spell_prince_taldaram_conjure_flame_sphere'), +(55945, 'spell_gen_spectator_cheer_trigger'), +(56096, 'spell_gen_vendor_bark_trigger'), +(56150, 'spell_jedoga_sacrafice_beam'), +(56159, 'spell_ahn_kahet_swarmer_aura'), +(56246, 'spell_warl_glyph_of_felguard'), +(56278, 'spell_q12987_read_pronouncement'), +(56328, 'spell_random_lightning_visual_effect'), +(56504, 'spell_q13007_iron_colossus'), +(56508, 'spell_q13007_iron_colossus'), +(56513, 'spell_gen_charmed_unit_spell_cooldown'), +(56524, 'spell_gen_charmed_unit_spell_cooldown'), +(56565, 'spell_q13011_bear_flank_master'), +(56575, 'spell_wintergrasp_create_vehicle'), +(56578, 'spell_gen_default_count_pct_from_max_hp'), +(56659, 'spell_wintergrasp_force_building'), +(56661, 'spell_wintergrasp_create_vehicle'), +(56662, 'spell_wintergrasp_force_building'), +(56663, 'spell_wintergrasp_create_vehicle'), +(56664, 'spell_wintergrasp_force_building'), +(56689, 'spell_q13003_thursting_hodirs_spear'), +(56698, 'spell_gen_default_count_pct_from_max_hp'), +(56702, 'spell_shadow_sickle_periodic_damage'), +(56763, 'spell_close_rift'), +(56841, 'spell_hun_glyph_of_arcane_shot'), +(57099, 'spell_gen_mine_sweeper'), +(57283, 'spell_amanitar_remove_mushroom_power'), +(57301, 'spell_item_feast'), +(57385, 'spell_q13086_last_line_of_defence'), +(57407, 'spell_eoe_ph3_surge_of_power'), +(57412, 'spell_q13086_last_line_of_defence'), +(57426, 'spell_item_feast'), +(57496, 'spell_herald_volzaj_insanity'), +(57528, 'spell_gen_clone'), +(57578, 'spell_sartharion_lava_strike'), +(57591, 'spell_sartharion_lava_strike'), +(57593, 'spell_gen_clone_weapon'), +(57594, 'spell_gen_clone_weapon_aura'), +(57607, 'spell_wg_reduce_damage_by_distance'), +(57610, 'spell_wg_reduce_damage_by_distance'), +(57669, 'spell_gen_replenishment'), +(57685, 'spell_gen_creature_permanent_feign_death'), +(57762, 'spell_twisted_visage_lifebloom'), +(57934, 'spell_rog_tricks_of_the_trade'), +(58040, 'spell_destroy_door_seal'), +(58387, 'spell_warr_glyph_of_sunder_armor'), +(58465, 'spell_item_feast'), +(58474, 'spell_item_feast'), +(58601, 'spell_gen_remove_flight_auras'), +(58622, 'spell_wintergrasp_portal'), +(58683, 'spell_rog_savage_combat'), +(58684, 'spell_rog_savage_combat'), +(58759, 'spell_sha_healing_stream_totem'), +(58760, 'spell_sha_healing_stream_totem'), +(58761, 'spell_sha_healing_stream_totem'), +(58778, 'spell_sha_mana_spring_totem'), +(58779, 'spell_sha_mana_spring_totem'), +(58780, 'spell_sha_mana_spring_totem'), +(58875, 'spell_sha_spirit_walk'), +(58886, 'spell_magic_eater_food'), +(58941, 'spell_archavon_rock_shards'), +(58951, 'spell_gen_creature_permanent_feign_death'), +(58983, 'spell_big_blizzard_bear'), +(59061, 'spell_charge_shield_bomber'), +(59065, 'spell_q13369_fate_up_against_your_will'), +(59088, 'spell_warr_improved_spell_reflection'), +(59089, 'spell_warr_improved_spell_reflection'), +(59102, 'spell_gen_default_count_pct_from_max_hp'), +(59103, 'spell_shadow_sickle_periodic_damage'), +(59134, 'spell_dk_death_coil'), +(59193, 'spell_switch_infragreen_bomber_station'), +(59194, 'spell_switch_infragreen_bomber_station'), +(59196, 'spell_switch_infragreen_bomber_station'), +(59237, 'spell_utgarde_pinnacle_beast_mark'), +(59288, 'spell_charge_shield_bomber'), +(59303, 'spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon'), +(59317, 'spell_gen_teleporting'), +(59318, 'spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy'), +(59416, 'spell_dred_raptor_call'), +(59417, 'spell_hadronox_leech_poison'), +(59433, 'spell_azjol_nerub_pound'), +(59452, 'spell_gen_select_target_count_15_2'), +(59511, 'spell_prince_taldaram_flame_sphere_summon'), +(59512, 'spell_prince_taldaram_flame_sphere_summon'), +(59542, 'spell_gen_gift_of_naaru'), +(59543, 'spell_gen_gift_of_naaru'), +(59544, 'spell_gen_gift_of_naaru'), +(59545, 'spell_gen_gift_of_naaru'), +(59547, 'spell_gen_gift_of_naaru'), +(59548, 'spell_gen_gift_of_naaru'), +(59566, 'spell_sha_earthen_power'), +(59622, 'spell_anti_air_rocket_bomber'), +(59628, 'spell_rog_tricks_of_the_trade_proc'), +(59630, 'spell_gen_black_magic_enchant'), +(59640, 'spell_item_underbelly_elixir'), +(59643, 'spell_q13280_13283_plant_battle_standard'), +(59686, 'spell_ticking_time_bomb'), +(59725, 'spell_warr_improved_spell_reflection_trigger'), +(59754, 'spell_dk_rune_tap_party'), +(59789, 'spell_item_oracle_ablutions'), +(59803, 'spell_trollgore_consume'), +(59807, 'spell_trollgore_corpse_explode'), +(59827, 'spell_galdarah_impaling_charge'), +(59837, 'spell_loken_pulsing_shockwave'), +(59910, 'spell_novos_summon_minions'), +(59917, 'spell_gen_disabled_above_70'), +(59972, 'spell_tharon_ja_curse_of_life'), +(59990, 'spell_twisted_visage_lifebloom'), +(60103, 'spell_sha_lava_lash'), +(60123, 'spell_pri_lightwell'), +(60144, 'spell_hun_viper_attack_speed'), +(60218, 'spell_gen_absorb0_hitlimit1'), +(60291, 'spell_volazj_whisper'), +(60292, 'spell_volazj_whisper'), +(60293, 'spell_volazj_whisper'), +(60294, 'spell_volazj_whisper'), +(60295, 'spell_volazj_whisper'), +(60296, 'spell_volazj_whisper'), +(60297, 'spell_volazj_whisper'), +(60320, 'spell_item_scroll_of_recall'), +(60321, 'spell_item_scroll_of_recall'), +(60476, 'spell_item_titanium_seal_of_dalaran'), +(60532, 'spell_gen_default_count_pct_from_max_hp'), +(60535, 'spell_item_light_lamp'), +(60779, 'spell_dru_idol_lifebloom'), +(60864, 'spell_gen_default_count_pct_from_max_hp'), +(60893, 'spell_gen_profession_research'), +(60900, 'spell_q13369_fate_up_against_your_will'), +(60936, 'spell_eoe_ph3_surge_of_power'), +(61013, 'spell_pet_hit_expertise_scalling'), +(61017, 'spell_pet_hit_expertise_scalling'), +(61093, 'spell_fight_fire_bomber'), +(61122, 'spell_item_branns_communicator'), +(61123, 'spell_blight_worm_ingest'), +(61177, 'spell_gen_profession_research'), +(61288, 'spell_gen_profession_research'), +(61336, 'spell_dru_survival_instincts'), +(61408, 'spell_wintergrasp_create_vehicle'), +(61409, 'spell_wintergrasp_force_building'), +(61546, 'spell_krystallus_shatter'), +(61547, 'spell_krystallus_shatter_effect'), +(61551, 'spell_item_toy_train_set'), +(61669, 'spell_hun_aspect_of_the_beast'), +(61678, 'spell_z_check'), +(61697, 'spell_dk_pet_scaling'), +(61698, 'spell_gen_ds_flush_knockback'), +(61756, 'spell_gen_profession_research'), +(61782, 'spell_gen_replenishment'), +(61783, 'spell_sha_feral_spirit_scaling'), +(61784, 'spell_pilgrims_bounty_feast_on_generic'), +(61785, 'spell_pilgrims_bounty_feast_on_generic'), +(61786, 'spell_pilgrims_bounty_feast_on_generic'), +(61787, 'spell_pilgrims_bounty_feast_on_generic'), +(61788, 'spell_pilgrims_bounty_feast_on_generic'), +(61804, 'spell_pilgrims_bounty_serve_generic'), +(61805, 'spell_pilgrims_bounty_serve_generic'), +(61806, 'spell_pilgrims_bounty_serve_generic'), +(61807, 'spell_pilgrims_bounty_serve_generic'), +(61808, 'spell_pilgrims_bounty_serve_generic'), +(61889, 'spell_assembly_meltdown'), +(61968, 'spell_hodir_flash_freeze'), +(61999, 'spell_dk_raise_ally'), +(62014, 'spell_pilgrims_bounty_turkey_tracker'), +(62018, 'spell_algalon_collapse'), +(62019, 'spell_assembly_rune_of_summoning'), +(62038, 'spell_hodir_biting_cold_main_aura'), +(62039, 'spell_hodir_biting_cold_player_aura'), +(62056, 'spell_ulduar_stone_grip'), +(62166, 'spell_ulduar_stone_grip_cast_target'), +(62266, 'spell_algalon_trigger_3_adds'), +(62274, 'spell_shield_of_runes'), +(62292, 'spell_tar_blaze'), +(62309, 'spell_demolisher_ride_vehicle'), +(62311, 'spell_algalon_cosmic_smash_damage'), +(62324, 'spell_vehicle_throw_passenger'), +(62331, 'spell_thorim_trash_impale'), +(62374, 'spell_pursue'), +(62399, 'spell_vehicle_circuit_overload'), +(62418, 'spell_thorim_trash_impale'), +(62475, 'spell_systems_shutdown'), +(62482, 'spell_vehicle_grab_pyrite'), +(62501, 'spell_hodir_shatter_chest'), +(62539, 'spell_gen_eject_passenger'), +(62546, 'spell_ignis_scorch'), +(62552, 'spell_gen_defend'), +(62563, 'spell_gen_mounted_charge'), +(62571, 'spell_item_enchanted_broom_periodic'), +(62575, 'spell_gen_break_shield'), +(62594, 'spell_gen_tournament_pennant'), +(62595, 'spell_gen_tournament_pennant'), +(62596, 'spell_gen_tournament_pennant'), +(62606, 'spell_dru_savage_defense'), +(62626, 'spell_gen_break_shield'), +(62692, 'spell_aura_of_despair'), +(62705, 'spell_auto_repair'), +(62707, 'spell_ignis_grab_initial'), +(62709, 'spell_gen_tournament_counterattack'), +(62717, 'spell_ignis_slag_pot'), +(62719, 'spell_gen_defend'), +(62774, 'spell_gen_summon_tournament_mount'), +(62775, 'spell_xt002_tympanic_tantrum'), +(62779, 'spell_gen_summon_tournament_mount'), +(62780, 'spell_gen_summon_tournament_mount'), +(62781, 'spell_gen_summon_tournament_mount'), +(62782, 'spell_gen_summon_tournament_mount'), +(62783, 'spell_gen_summon_tournament_mount'), +(62784, 'spell_gen_summon_tournament_mount'), +(62785, 'spell_gen_summon_tournament_mount'), +(62786, 'spell_gen_summon_tournament_mount'), +(62787, 'spell_gen_summon_tournament_mount'), +(62807, 'spell_hodir_starlight'), +(62821, 'spell_hodir_toasty_fire'), +(62863, 'spell_gen_tournament_duel'), +(62874, 'spell_gen_mounted_charge'), +(62912, 'spell_thorims_hammer'), +(62960, 'spell_gen_mounted_charge'), +(62976, 'spell_thorim_lightning_pillar_P2'), +(62991, 'spell_gen_bonked'), +(63003, 'spell_gen_mounted_charge'), +(63010, 'spell_gen_mounted_charge'), +(63018, 'spell_xt002_searing_light_spawn_life_spark'), +(63024, 'spell_xt002_gravity_bomb_aura'), +(63025, 'spell_xt002_gravity_bomb_damage'), +(63034, 'spell_gen_on_tournament_mount'), +(63108, 'spell_warl_siphon_life'), +(63120, 'spell_yogg_saron_insane'), +(63233, 'spell_gen_break_shield'), +(63274, 'spell_mimiron_p3wx2_laser_barrage'), +(63276, 'spell_mark_of_the_faceless_periodic'), +(63278, 'spell_mark_of_the_faceless_drainhealth'), +(63305, 'spell_yogg_saron_grim_reprisal'), +(63310, 'spell_warl_glyph_of_shadowflame'), +(63322, 'spell_saronite_vapors_dummy'), +(63338, 'spell_saronite_vapors_damage'), +(63382, 'spell_mimiron_rapid_burst'), +(63394, 'spell_gen_tournament_pennant'), +(63395, 'spell_gen_tournament_pennant'), +(63396, 'spell_gen_tournament_pennant'), +(63397, 'spell_gen_tournament_pennant'), +(63398, 'spell_gen_tournament_pennant'), +(63399, 'spell_gen_tournament_pennant'), +(63401, 'spell_gen_tournament_pennant'), +(63402, 'spell_gen_tournament_pennant'), +(63403, 'spell_gen_tournament_pennant'), +(63404, 'spell_gen_tournament_pennant'), +(63405, 'spell_gen_tournament_pennant'), +(63406, 'spell_gen_tournament_pennant'), +(63416, 'spell_gen_clone_weapon'), +(63418, 'spell_gen_clone_weapon_aura'), +(63421, 'spell_gen_tournament_pennant'), +(63422, 'spell_gen_tournament_pennant'), +(63423, 'spell_gen_tournament_pennant'), +(63425, 'spell_gen_tournament_pennant'), +(63426, 'spell_gen_tournament_pennant'), +(63427, 'spell_gen_tournament_pennant'), +(63428, 'spell_gen_tournament_pennant'), +(63429, 'spell_gen_tournament_pennant'), +(63430, 'spell_gen_tournament_pennant'), +(63431, 'spell_gen_tournament_pennant'), +(63432, 'spell_gen_tournament_pennant'), +(63433, 'spell_gen_tournament_pennant'), +(63434, 'spell_gen_tournament_pennant'), +(63435, 'spell_gen_tournament_pennant'), +(63436, 'spell_gen_tournament_pennant'), +(63474, 'spell_ignis_scorch'), +(63477, 'spell_ignis_slag_pot'), +(63489, 'spell_shield_of_runes'), +(63500, 'spell_gen_tournament_pennant'), +(63501, 'spell_gen_tournament_pennant'), +(63521, 'spell_pal_guarded_by_the_light'), +(63545, 'spell_hodir_periodic_icicle'), +(63606, 'spell_gen_tournament_pennant'), +(63607, 'spell_gen_tournament_pennant'), +(63608, 'spell_gen_tournament_pennant'), +(63609, 'spell_gen_tournament_pennant'), +(63611, 'spell_dk_improved_blood_presence_proc'), +(63661, 'spell_gen_mounted_charge'), +(63663, 'spell_gen_summon_tournament_mount'), +(63711, 'spell_hodir_storm_power'), +(63716, 'spell_kologarn_stone_shout'), +(63720, 'spell_kologarn_stone_shout'), +(63744, 'spell_yogg_saron_target_selectors'), +(63745, 'spell_yogg_saron_target_selectors'), +(63747, 'spell_yogg_saron_target_selectors'), +(63791, 'spell_gen_summon_tournament_mount'), +(63792, 'spell_gen_summon_tournament_mount'), +(63795, 'spell_yogg_saron_sanity_reduce'), +(63802, 'spell_yogg_saron_brain_link'), +(63803, 'spell_yogg_saron_sanity_reduce'), +(63825, 'spell_gen_break_shield'), +(63830, 'spell_yogg_saron_malady_of_the_mind'), +(63830, 'spell_yogg_saron_sanity_reduce'), +(63845, 'spell_gen_create_lance'), +(63881, 'spell_yogg_saron_malady_of_the_mind'), +(63881, 'spell_yogg_saron_sanity_reduce'), +(63944, 'spell_gen_damage_reduction_aura'), +(63981, 'spell_ulduar_stone_grip_cast_target'), +(63985, 'spell_ulduar_stone_grip'), +(64004, 'spell_kologarn_stone_shout'), +(64005, 'spell_kologarn_stone_shout'), +(64059, 'spell_yogg_saron_sanity_reduce'), +(64142, 'spell_gen_upper_deck_create_foam_sword'), +(64161, 'spell_yogg_saron_empowered'), +(64164, 'spell_yogg_saron_lunatic_gaze'), +(64164, 'spell_yogg_saron_sanity_reduce'), +(64168, 'spell_yogg_saron_lunatic_gaze'), +(64168, 'spell_yogg_saron_sanity_reduce'), +(64169, 'spell_yogg_saron_sanity_well'), +(64172, 'spell_yogg_saron_titanic_storm'), +(64174, 'spell_yogg_saron_protective_gaze'), +(64184, 'spell_yogg_saron_in_the_maws_of_the_old_god'), +(64205, 'spell_pal_divine_sacrifice'), +(64217, 'spell_voa_overcharge'), +(64233, 'spell_xt002_gravity_bomb_damage'), +(64234, 'spell_xt002_gravity_bomb_aura'), +(64323, 'spell_item_book_of_glyph_mastery'), +(64342, 'spell_gen_break_shield'), +(64380, 'spell_warr_shattering_throw'), +(64385, 'spell_item_unusual_compass'), +(64392, 'spell_auriaya_sentinel_blast'), +(64411, 'spell_item_blessing_of_ancient_kings'), +(64412, 'spell_algalon_phase_punch'), +(64414, 'spell_load_into_catapult'), +(64415, 'spell_item_valanyr_hammer_of_ancient_kings'), +(64440, 'spell_gen_blade_warding'), +(64440, 'spell_gen_proc_above_75'), +(64440, 'spell_item_blade_ward_enchant'), +(64443, 'spell_algalon_big_bang'), +(64445, 'spell_algalon_remove_phase'), +(64465, 'spell_yogg_saron_shadow_beacon'), +(64467, 'spell_yogg_saron_empowering_shadows'), +(64482, 'spell_orbital_supports'), +(64507, 'spell_gen_break_shield'), +(64555, 'spell_yogg_saron_insane_periodic_trigger'), +(64568, 'spell_gen_proc_above_75'), +(64568, 'spell_item_blood_draining_enchant'), +(64584, 'spell_algalon_big_bang'), +(64590, 'spell_gen_break_shield'), +(64591, 'spell_gen_mounted_charge'), +(64595, 'spell_gen_break_shield'), +(64596, 'spell_algalon_cosmic_smash_damage'), +(64614, 'spell_gen_eject_passenger'), +(64629, 'spell_gen_eject_passenger'), +(64630, 'spell_gen_eject_passenger'), +(64631, 'spell_gen_eject_passenger'), +(64632, 'spell_gen_eject_passenger'), +(64633, 'spell_gen_eject_passenger'), +(64634, 'spell_gen_eject_passenger'), +(64635, 'spell_gen_eject_passenger'), +(64636, 'spell_gen_eject_passenger'), +(64677, 'spell_shield_generator'), +(64679, 'spell_auriaya_sentinel_blast'), +(64686, 'spell_gen_break_shield'), +(64702, 'spell_ulduar_squeezed_lifeless'), +(64740, 'spell_ulduar_energy_sap'), +(64770, 'spell_ulduar_arachnopod_damaged'), +(64844, 'spell_pri_divine_hymn'), +(64876, 'spell_ulduar_energy_sap'), +(64904, 'spell_pri_hymn_of_hope'), +(64981, 'spell_item_vanquished_clutches'), +(65075, 'spell_orbital_supports'), +(65076, 'spell_orbital_supports'), +(65077, 'spell_orbital_supports'), +(65121, 'spell_xt002_searing_light_spawn_life_spark'), +(65123, 'spell_hodir_storm_cloud'), +(65133, 'spell_hodir_storm_cloud'), +(65134, 'spell_hodir_storm_power'), +(65147, 'spell_gen_break_shield'), +(65206, 'spell_yogg_saron_destabilization_matrix'), +(65225, 'spell_sha_fire_elemental_scaling'), +(65226, 'spell_sha_fire_elemental_scaling'), +(65227, 'spell_sha_fire_elemental_scaling'), +(65228, 'spell_sha_fire_elemental_scaling'), +(65266, 'spell_gen_vehicle_scaling'), +(65279, 'spell_voa_lightning_nova'), +(65301, 'spell_yogg_saron_sanity_reduce'), +(65311, 'spell_algalon_supermassive_fail'), +(65418, 'spell_pilgrims_bounty_food'), +(65419, 'spell_pilgrims_bounty_food'), +(65420, 'spell_pilgrims_bounty_food'), +(65421, 'spell_pilgrims_bounty_food'), +(65422, 'spell_pilgrims_bounty_food'), +(65576, 'spell_winter_veil_shoot_air_rifle'), +(65635, 'spell_gen_vehicle_scaling'), +(65636, 'spell_gen_vehicle_scaling'), +(65684, 'spell_valkyr_essence'), +(65686, 'spell_valkyr_essence'), +(65812, 'spell_faction_champion_warl_unstable_affliction'), +(65920, 'spell_pursuing_spikes'), +(65922, 'spell_pursuing_spikes'), +(65923, 'spell_pursuing_spikes'), +(65941, 'spell_warr_shattering_throw'), +(65950, 'spell_valkyr_touch'), +(65956, 'spell_rog_blade_flurry'), +(66001, 'spell_valkyr_touch'), +(66041, 'spell_pilgrims_bounty_food'), +(66093, 'spell_faction_champion_dru_lifebloom'), +(66118, 'spell_gen_leeching_swarm'), +(66218, 'spell_ioc_launch'), +(66240, 'spell_gen_leeching_swarm_dmg'), +(66250, 'spell_pilgrims_bounty_pass_generic'), +(66259, 'spell_pilgrims_bounty_pass_generic'), +(66260, 'spell_pilgrims_bounty_pass_generic'), +(66261, 'spell_pilgrims_bounty_pass_generic'), +(66262, 'spell_pilgrims_bounty_pass_generic'), +(66316, 'spell_gen_50pct_count_pct_from_max_hp'), +(66334, 'spell_toc25_mistress_kiss'), +(66336, 'spell_mistress_kiss_area'), +(66477, 'spell_pilgrims_bounty_food'), +(66480, 'spell_gen_break_shield'), +(66481, 'spell_gen_mounted_charge'), +(66482, 'spell_gen_defend'), +(66515, 'spell_reflective_shield'), +(66630, 'spell_ioc_gunship_portal'), +(66637, 'spell_ioc_gunship_portal'), +(66656, 'spell_ioc_parachute_ic'), +(66666, 'spell_gen_vehicle_scaling'), +(66667, 'spell_gen_vehicle_scaling'), +(66668, 'spell_gen_vehicle_scaling'), +(66672, 'spell_ioc_bomb_blast_criteria'), +(66676, 'spell_ioc_bomb_blast_criteria'), +(66690, 'spell_voa_flaming_cinder'), +(66725, 'spell_koralon_meteor_fists'), +(66741, 'spell_q14112_14145_chum_the_water'), +(66808, 'spell_flame_warder_meteor_fists'), +(66862, 'spell_eadric_radiance'), +(67019, 'spell_item_flask_of_the_north'), +(67076, 'spell_mistress_kiss_area'), +(67077, 'spell_mistress_kiss_area'), +(67078, 'spell_mistress_kiss_area'), +(67100, 'spell_gen_50pct_count_pct_from_max_hp'), +(67101, 'spell_gen_50pct_count_pct_from_max_hp'), +(67102, 'spell_gen_50pct_count_pct_from_max_hp'), +(67176, 'spell_valkyr_essence'), +(67177, 'spell_valkyr_essence'), +(67178, 'spell_valkyr_essence'), +(67197, 'spell_toc5_light_rain'), +(67222, 'spell_valkyr_essence'), +(67223, 'spell_valkyr_essence'), +(67224, 'spell_valkyr_essence'), +(67281, 'spell_valkyr_touch'), +(67282, 'spell_valkyr_touch'), +(67283, 'spell_valkyr_touch'), +(67292, 'spell_toc5_light_rain'), +(67296, 'spell_valkyr_touch'), +(67297, 'spell_valkyr_touch'), +(67298, 'spell_valkyr_touch'), +(67335, 'spell_igb_gunship_fall_teleport'), +(67393, 'spell_gen_eject_passenger'), +(67489, 'spell_item_runic_healing_injector'), +(67533, 'spell_winter_veil_shoot_air_rifle'), +(67630, 'spell_gen_leeching_swarm'), +(67681, 'spell_eadric_radiance'), +(67698, 'spell_gen_allow_proc_from_spells_with_cost'), +(67752, 'spell_gen_allow_proc_from_spells_with_cost'), +(67799, 'spell_item_mind_amplify_dish'), +(67905, 'spell_toc25_mistress_kiss'), +(67906, 'spell_toc25_mistress_kiss'), +(67907, 'spell_toc25_mistress_kiss'), +(67957, 'spell_faction_champion_dru_lifebloom'), +(67958, 'spell_faction_champion_dru_lifebloom'), +(67959, 'spell_faction_champion_dru_lifebloom'), +(68077, 'spell_ioc_repair_turret'), +(68154, 'spell_faction_champion_warl_unstable_affliction'), +(68155, 'spell_faction_champion_warl_unstable_affliction'), +(68156, 'spell_faction_champion_warl_unstable_affliction'), +(68160, 'spell_flame_warder_meteor_fists'), +(68161, 'spell_koralon_meteor_fists'), +(68198, 'spell_pos_rimefang_frost_nova'), +(68282, 'spell_gen_mounted_charge'), +(68284, 'spell_gen_mounted_charge'), +(68321, 'spell_gen_mounted_charge'), +(68361, 'spell_hun_animal_handler'), +(68498, 'spell_gen_mounted_charge'), +(68501, 'spell_gen_mounted_charge'), +(68504, 'spell_gen_break_shield'), +(68529, 'spell_love_in_air_perfume_immune'), +(68530, 'spell_love_in_air_perfume_immune'), +(68576, 'spell_gen_eject_all_passengers'), +(68614, 'spell_apothecary_cologne_spill'), +(68644, 'spell_apothecary_validate_area'), +(68646, 'spell_gen_leeching_swarm'), +(68647, 'spell_gen_leeching_swarm'), +(68721, 'spell_igb_rocket_pack'), +(68786, 'spell_garfrost_permafrost'), +(68793, 'spell_bronjahm_magic_bane'), +(68798, 'spell_apothecary_perfume_spill'), +(68870, 'spell_bronjahm_soulstorm_visual'), +(68875, 'spell_wailing_souls_periodic'), +(68921, 'spell_bronjahm_soulstorm_targeting'), +(68965, 'spell_apothecary_lingering_fumes'), +(68966, 'spell_apothecary_throw_perfume'), +(68980, 'spell_the_lich_king_harvest_soul'), +(68984, 'spell_the_lich_king_cast_back_to_caster'), +(69008, 'spell_bronjahm_soulstorm_channel_ooc'), +(69012, 'spell_krick_explosive_barrage'), +(69020, 'spell_exploding_orb_auto_grow'), +(69030, 'spell_the_lich_king_valkyr_target_search'), +(69037, 'spell_the_lich_king_summon_into_air'), +(69038, 'spell_apothecary_throw_cologne'), +(69049, 'spell_bronjahm_soulstorm_targeting'), +(69050, 'spell_bronjahm_magic_bane'), +(69055, 'spell_marrowgar_bone_slice'), +(69057, 'spell_marrowgar_bone_spike_graveyard'), +(69069, 'spell_shield_of_bones'), +(69075, 'spell_marrowgar_bone_storm'), +(69110, 'spell_the_lich_king_ice_burst_target_search'), +(69140, 'spell_marrowgar_coldflame'), +(69195, 'spell_festergut_pungent_blight'), +(69200, 'spell_the_lich_king_raging_spirit'), +(69222, 'spell_gen_throw_shield'), +(69290, 'spell_festergut_blighted_spores'), +(69366, 'spell_dru_moonkin_form_passive'), +(69377, 'spell_item_runescroll_of_fortitude'), +(69382, 'spell_the_lich_king_lights_favor'), +(69383, 'spell_the_lich_king_dark_hunger'), +(69397, 'spell_the_lich_king_soul_rip'), +(69399, 'spell_igb_cannon_blast'), +(69401, 'spell_igb_incinerating_blast'), +(69409, 'spell_the_lich_king_soul_reaper'), +(69470, 'spell_igb_periodic_trigger_with_power_cost'), +(69483, 'spell_deathwhisper_dark_reckoning'), +(69483, 'spell_icc_dark_reckoning'), +(69487, 'spell_igb_overheat'), +(69487, 'spell_igb_periodic_trigger_with_power_cost'), +(69516, 'spell_icc_yd_summon_undead'), +(69538, 'spell_rotface_little_ooze_combine'), +(69553, 'spell_rotface_large_ooze_combine'), +(69603, 'spell_pos_blight'), +(69604, 'spell_pos_blight'), +(69610, 'spell_rotface_large_ooze_buff_combine'), +(69641, 'spell_gen_gryphon_wyvern_mount_check'), +(69649, 'spell_sindragosa_frost_breath'), +(69664, 'spell_q20438_q24556_aquantos_laundry'), +(69672, 'spell_gen_sunreaver_disguise'), +(69673, 'spell_gen_silver_covenant_disguise'), +(69674, 'spell_rotface_mutated_infection'), +(69678, 'spell_igb_rocket_artillery'), +(69679, 'spell_igb_rocket_artillery_explosion'), +(69682, 'spell_item_sleepy_willy'), +(69705, 'spell_igb_below_zero'), +(69712, 'spell_sindragosa_ice_tomb'), +(69712, 'spell_sindragosa_ice_tomb_dummy'), +(69712, 'spell_sindragosa_ice_tomb_filter'), +(69732, 'spell_item_lil_phylactery'), +(69762, 'spell_gen_allow_proc_from_spells_with_cost'), +(69762, 'spell_sindragosa_unchained_magic'), +(69766, 'spell_sindragosa_instability'), +(69832, 'spell_rotface_unstable_ooze_explosion'), +(69839, 'spell_rotface_unstable_ooze_explosion_init'), +(69891, 'spell_gen_clone_weapon'), +(69892, 'spell_gen_clone_weapon'), +(69893, 'spell_gen_clone_weapon_aura'), +(69896, 'spell_gen_clone_weapon_aura'), +(70017, 'spell_hor_gunship_cannon_fire'), +(70053, 'spell_svalna_revive_champion'), +(70078, 'spell_svalna_caress_of_death'), +(70104, 'spell_igb_teleport_to_enemy_ship'), +(70107, 'spell_sindragosa_permeating_chill'), +(70117, 'spell_sindragosa_icy_grip'), +(70120, 'spell_igb_on_gunship_deck'), +(70121, 'spell_igb_on_gunship_deck'), +(70122, 'spell_sindragosa_icy_grip_jump'), +(70126, 'spell_sindragosa_frost_beacon'), +(70127, 'spell_sindragosa_mystic_buffet'), +(70132, 'spell_pos_empowered_blizzard'), +(70157, 'spell_sindragosa_ice_tomb_trap'), +(70172, 'spell_igb_cannon_blast'), +(70174, 'spell_igb_incinerating_blast'), +(70207, 'spell_shield_of_bones'), +(70285, 'spell_pos_blight'), +(70286, 'spell_pos_blight'), +(70292, 'spell_pos_glacial_strike'), +(70308, 'spell_putricide_mutation_init'), +(70311, 'spell_putricide_mutated_transformation'), +(70331, 'spell_igb_check_for_players'), +(70336, 'spell_garfrost_permafrost'), +(70337, 'spell_the_lich_king_necrotic_plague'), +(70338, 'spell_the_lich_king_necrotic_plague_jump'), +(70342, 'spell_putricide_slime_puddle_spawn'), +(70345, 'spell_putricide_grow_stacker'), +(70346, 'spell_putricide_slime_puddle'), +(70348, 'spell_igb_rocket_pack_useable'), +(70351, 'spell_putricide_unstable_experiment'), +(70360, 'spell_putricide_eat_ooze'), +(70397, 'spell_igb_burning_pitch_selector'), +(70402, 'spell_putricide_mutated_transformation_dmg'), +(70403, 'spell_igb_burning_pitch_selector'), +(70405, 'spell_putricide_mutated_transformation_dismiss'), +(70443, 'spell_igb_explosion'), +(70444, 'spell_igb_explosion'), +(70447, 'spell_putricide_ooze_channel'), +(70459, 'spell_putricide_ooze_eruption_searcher'), +(70477, 'spell_bh_cleanse_quel_delar'), +(70497, 'spell_the_lich_king_summon_into_air'), +(70498, 'spell_the_lich_king_vile_spirits'), +(70499, 'spell_the_lich_king_vile_spirits_visual'), +(70501, 'spell_the_lich_king_vile_spirit_move_target_search'), +(70534, 'spell_the_lich_king_vile_spirit_damage_target_search'), +(70536, 'spell_icc_sprit_alarm'), +(70539, 'spell_putricide_regurgitated_ooze'), +(70541, 'spell_the_lich_king_infest'), +(70545, 'spell_icc_sprit_alarm'), +(70546, 'spell_icc_sprit_alarm'), +(70547, 'spell_icc_sprit_alarm'), +(70548, 'spell_bh_cleanse_quel_delar'), +(70588, 'spell_valithria_suppression'), +(70592, 'spell_gen_creature_permanent_feign_death'), +(70598, 'spell_sindragosa_s_fury'), +(70609, 'spell_igb_rocket_artillery'), +(70614, 'spell_q24545_aod_special'), +(70628, 'spell_gen_creature_permanent_feign_death'), +(70672, 'spell_putricide_gaseous_bloat'), +(70672, 'spell_putricide_ooze_channel'), +(70691, 'spell_dru_t10_restoration_4p_bonus'), +(70723, 'spell_dru_t10_balance_4p_bonus'), +(70733, 'spell_icc_stoneform'), +(70739, 'spell_icc_geist_alarm'), +(70740, 'spell_icc_geist_alarm'), +(70743, 'spell_q24545_aod_special'), +(70769, 'spell_gen_divine_storm_cd_reset'), +(70790, 'spell_q24545_aod_special'), +(70803, 'spell_gen_proc_not_self'), +(70805, 'spell_gen_proc_on_self'), +(70808, 'spell_sha_t10_restoration_4p_bonus'), +(70811, 'spell_sha_item_t10_elemental_2p_bonus'), +(70814, 'spell_marrowgar_bone_slice'), +(70826, 'spell_marrowgar_bone_spike_graveyard'), +(70834, 'spell_marrowgar_bone_storm'), +(70835, 'spell_marrowgar_bone_storm'), +(70836, 'spell_marrowgar_bone_storm'), +(70842, 'spell_deathwhisper_mana_barrier'), +(70871, 'spell_blood_queen_essence_of_the_blood_queen'), +(70877, 'spell_blood_queen_frenzied_bloodthirst'), +(70911, 'spell_putricide_unbound_plague_dmg'), +(70912, 'spell_dreamwalker_decay_periodic_timer'), +(70912, 'spell_dreamwalker_summon_suppresser'), +(70913, 'spell_dreamwalker_decay_periodic_timer'), +(70915, 'spell_dreamwalker_decay_periodic_timer'), +(70916, 'spell_dreamwalker_decay_periodic_timer'), +(70920, 'spell_putricide_unbound_plague'), +(70921, 'spell_dreamwalker_summoner'), +(70933, 'spell_dreamwalker_summoner'), +(70936, 'spell_dreamwalker_summon_suppresser_effect'), +(70937, 'spell_mage_glyph_of_eternal_water'), +(70946, 'spell_blood_queen_vampiric_bite'), +(70961, 'spell_icc_shattered_bones'), +(70980, 'spell_icc_web_wrap'), +(71032, 'spell_dreamwalker_summoner'), +(71056, 'spell_sindragosa_frost_breath'), +(71057, 'spell_sindragosa_frost_breath'), +(71058, 'spell_sindragosa_frost_breath'), +(71078, 'spell_dreamwalker_summoner'), +(71085, 'spell_dreamwalker_mana_void'), +(71123, 'spell_stinky_precious_decimate'), +(71168, 'spell_item_unsated_craving'), +(71169, 'spell_item_shadows_fate'), +(71201, 'spell_igb_battle_experience_check'), +(71219, 'spell_festergut_pungent_blight'), +(71222, 'spell_festergut_blighted_spores'), +(71224, 'spell_rotface_mutated_infection'), +(71252, 'spell_icc_yh_volley'), +(71255, 'spell_putricide_choking_gas_bomb'), +(71268, 'spell_blood_queen_swarming_shadows_floor_dmg'), +(71274, 'spell_icc_yf_frozen_orb'), +(71281, 'spell_pos_slave_trigger_closest'), +(71316, 'spell_pos_glacial_strike'), +(71317, 'spell_pos_glacial_strike'), +(71335, 'spell_igb_burning_pitch'), +(71339, 'spell_igb_burning_pitch'), +(71340, 'spell_blood_queen_pact_of_the_darkfallen_dmg'), +(71341, 'spell_blood_queen_pact_of_the_darkfallen_dmg_target'), +(71342, 'spell_big_love_rocket'), +(71350, 'spell_frostwarden_handler_focus_fire'), +(71357, 'spell_frostwarden_handler_order_whelp'), +(71376, 'spell_rimefang_icy_blast'), +(71390, 'spell_blood_queen_pact_of_the_darkfallen'), +(71441, 'spell_rotface_unstable_ooze_explosion_suicide'), +(71450, 'spell_gen_aura_service_uniform'), +(71462, 'spell_svalna_remove_spear'), +(71474, 'spell_blood_queen_frenzied_bloodthirst'), +(71475, 'spell_blood_queen_vampiric_bite'), +(71476, 'spell_blood_queen_vampiric_bite'), +(71477, 'spell_blood_queen_vampiric_bite'), +(71503, 'spell_putricide_mutated_transformation'), +(71610, 'spell_item_echoes_of_light'), +(71615, 'spell_putricide_tear_gas_effect'), +(71641, 'spell_item_echoes_of_light'), +(71718, 'spell_taldaram_summon_flame_ball'), +(71756, 'spell_taldaram_ball_of_inferno_flame'), +(71806, 'spell_taldaram_glittering_sparks'), +(71811, 'spell_the_lich_king_jump'), +(71841, 'spell_pet_gen_valkyr_guardian_smite'), +(71842, 'spell_pet_gen_valkyr_guardian_smite'), +(71848, 'spell_item_sleepy_willy'), +(71865, 'spell_item_trauma'), +(71868, 'spell_item_trauma'), +(71874, 'spell_item_toxic_wasteling'), +(71875, 'spell_item_necrotic_touch'), +(71877, 'spell_item_necrotic_touch'), +(71899, 'spell_blood_queen_bloodbolt'), +(71900, 'spell_blood_queen_bloodbolt'), +(71901, 'spell_blood_queen_bloodbolt'), +(71902, 'spell_blood_queen_bloodbolt'), +(71903, 'spell_item_shadowmourne'), +(71905, 'spell_item_shadowmourne_soul_fragment'), +(71941, 'spell_dreamwalker_twisted_nightmares'), +(71943, 'spell_blood_council_summon_shadow_resonance'), +(71963, 'spell_blood_queen_presence_of_the_darkfallen'), +(71964, 'spell_blood_queen_presence_of_the_darkfallen'), +(71966, 'spell_putricide_unstable_experiment'), +(71967, 'spell_putricide_unstable_experiment'), +(71968, 'spell_putricide_unstable_experiment'), +(71970, 'spell_dreamwalker_nightmare_cloud'), +(72040, 'spell_taldaram_summon_flame_ball'), +(72053, 'spell_valanar_kinetic_bomb_summon'), +(72054, 'spell_valanar_kinetic_bomb_absorb'), +(72080, 'spell_valanar_kinetic_bomb'), +(72087, 'spell_valanar_kinetic_bomb_knockback'), +(72088, 'spell_marrowgar_bone_spike_graveyard'), +(72089, 'spell_marrowgar_bone_spike_graveyard'), +(72134, 'spell_igb_explosion_main'), +(72137, 'spell_igb_explosion_main'), +(72155, 'spell_icc_harvest_blight_specimen'), +(72162, 'spell_icc_harvest_blight_specimen'), +(72176, 'spell_deathbringer_blood_link_blood_beast_aura'), +(72178, 'spell_deathbringer_blood_link_aura'), +(72202, 'spell_deathbringer_blood_link'), +(72219, 'spell_festergut_gastric_bloat'), +(72224, 'spell_dreamwalker_summon_portal'), +(72262, 'spell_the_lich_king_quake'), +(72286, 'spell_invincible'), +(72340, 'spell_igb_teleport_players_on_victory'), +(72368, 'spell_hor_shared_suffering'), +(72369, 'spell_hor_shared_suffering'), +(72371, 'spell_deathbringer_blood_power'), +(72378, 'spell_deathbringer_blood_nova_targeting'), +(72385, 'spell_deathbringer_boiling_blood'), +(72429, 'spell_the_lich_king_mass_resurrection'), +(72431, 'spell_the_lich_king_jump_remove_aura'), +(72441, 'spell_deathbringer_boiling_blood'), +(72442, 'spell_deathbringer_boiling_blood'), +(72443, 'spell_deathbringer_boiling_blood'), +(72451, 'spell_putricide_mutated_plague'), +(72455, 'spell_putricide_gaseous_bloat'), +(72455, 'spell_putricide_ooze_channel'), +(72456, 'spell_putricide_slime_puddle'), +(72457, 'spell_putricide_regurgitated_ooze'), +(72463, 'spell_putricide_mutated_plague'), +(72465, 'spell_sindragosa_soul_preservation'), +(72480, 'spell_dreamwalker_summon_portal'), +(72508, 'spell_putricide_mutated_transformation_dismiss'), +(72509, 'spell_putricide_mutated_transformation_dismiss'), +(72510, 'spell_putricide_mutated_transformation_dismiss'), +(72511, 'spell_putricide_mutated_transformation_dmg'), +(72512, 'spell_putricide_mutated_transformation_dmg'), +(72513, 'spell_putricide_mutated_transformation_dmg'), +(72527, 'spell_putricide_eat_ooze'), +(72528, 'spell_sindragosa_mystic_buffet'), +(72529, 'spell_sindragosa_mystic_buffet'), +(72530, 'spell_sindragosa_mystic_buffet'), +(72551, 'spell_festergut_gastric_bloat'), +(72552, 'spell_festergut_gastric_bloat'), +(72553, 'spell_festergut_gastric_bloat'), +(72585, 'spell_icc_soul_missile'), +(72595, 'spell_the_lich_king_restore_soul'), +(72618, 'spell_putricide_clear_aura_effect_value'), +(72635, 'spell_blood_queen_swarming_shadows_floor_dmg'), +(72636, 'spell_blood_queen_swarming_shadows_floor_dmg'), +(72637, 'spell_blood_queen_swarming_shadows_floor_dmg'), +(72671, 'spell_putricide_mutated_plague'), +(72672, 'spell_putricide_mutated_plague'), +(72705, 'spell_marrowgar_coldflame_bonestorm'), +(72752, 'spell_pvp_trinket_wotf_shared_cd'), +(72754, 'spell_the_lich_king_defile'), +(72757, 'spell_pvp_trinket_wotf_shared_cd'), +(72782, 'spell_taldaram_ball_of_inferno_flame'), +(72783, 'spell_taldaram_ball_of_inferno_flame'), +(72784, 'spell_taldaram_ball_of_inferno_flame'), +(72832, 'spell_putricide_gaseous_bloat'), +(72832, 'spell_putricide_ooze_channel'), +(72833, 'spell_putricide_gaseous_bloat'), +(72833, 'spell_putricide_ooze_channel'), +(72836, 'spell_putricide_ooze_channel'), +(72837, 'spell_putricide_ooze_channel'), +(72838, 'spell_putricide_ooze_channel'), +(72854, 'spell_putricide_unbound_plague_dmg'), +(72855, 'spell_putricide_unbound_plague_dmg'), +(72856, 'spell_putricide_unbound_plague_dmg'), +(72864, 'spell_frost_giant_death_plague'), +(72868, 'spell_putricide_slime_puddle'), +(72869, 'spell_putricide_slime_puddle'), +(72875, 'spell_putricide_regurgitated_ooze'), +(72876, 'spell_putricide_regurgitated_ooze'), +(72999, 'spell_blood_council_shadow_prison_damage'), +(73001, 'spell_blood_council_shadow_prison'), +(73022, 'spell_rotface_mutated_infection'), +(73023, 'spell_rotface_mutated_infection'), +(73031, 'spell_festergut_pungent_blight'), +(73032, 'spell_festergut_pungent_blight'), +(73033, 'spell_festergut_blighted_spores'), +(73034, 'spell_festergut_blighted_spores'), +(73058, 'spell_deathbringer_blood_nova_targeting'), +(73061, 'spell_sindragosa_frost_breath'), +(73062, 'spell_sindragosa_frost_breath'), +(73063, 'spell_sindragosa_frost_breath'), +(73064, 'spell_sindragosa_frost_breath'), +(73076, 'spell_gen_throw_shield'), +(73159, 'spell_the_lich_king_play_movie'), +(73488, 'spell_the_lich_king_life_siphon'), +(73530, 'spell_the_lich_king_shadow_trap_visual'), +(73579, 'spell_the_lich_king_summon_into_air'), +(73582, 'spell_the_lich_king_trigger_vile_spirit'), +(73650, 'spell_the_lich_king_restore_soul'), +(73655, 'spell_the_lich_king_teleport_to_frostmourne_hc'), +(73708, 'spell_the_lich_king_defile'), +(73709, 'spell_the_lich_king_defile'), +(73710, 'spell_the_lich_king_defile'), +(73779, 'spell_the_lich_king_infest'), +(73780, 'spell_the_lich_king_infest'), +(73781, 'spell_the_lich_king_infest'), +(73782, 'spell_the_lich_king_life_siphon'), +(73783, 'spell_the_lich_king_life_siphon'), +(73784, 'spell_the_lich_king_life_siphon'), +(73785, 'spell_the_lich_king_necrotic_plague_jump'), +(73786, 'spell_the_lich_king_necrotic_plague_jump'), +(73787, 'spell_the_lich_king_necrotic_plague_jump'), +(73797, 'spell_the_lich_king_soul_reaper'), +(73798, 'spell_the_lich_king_soul_reaper'), +(73799, 'spell_the_lich_king_soul_reaper'), +(73912, 'spell_the_lich_king_necrotic_plague'), +(73913, 'spell_the_lich_king_necrotic_plague'), +(73914, 'spell_the_lich_king_necrotic_plague'), +(74282, 'spell_the_lich_king_shadow_trap_periodic'), +(74296, 'spell_the_lich_king_harvest_soul'), +(74297, 'spell_the_lich_king_harvest_soul'), +(74300, 'spell_the_lich_king_summon_into_air'), +(74302, 'spell_the_lich_king_summon_spirit_bomb'), +(74325, 'spell_the_lich_king_harvest_soul'), +(74341, 'spell_the_lich_king_summon_spirit_bomb'), +(74342, 'spell_the_lich_king_summon_spirit_bomb'), +(74343, 'spell_the_lich_king_summon_spirit_bomb'), +(74396, 'spell_mage_fingers_of_frost_proc'), +(74445, 'spell_the_lich_king_cast_back_to_caster'), +(74452, 'spell_saviana_conflagration_init'), +(74455, 'spell_saviana_conflagration_throwback'), +(74490, 'spell_gen_creature_permanent_feign_death'), +(74505, 'spell_baltharus_enervating_brand_trigger'), +(74562, 'spell_halion_fiery_combustion'), +(74567, 'spell_halion_mark_of_combustion'), +(74610, 'spell_halion_combustion_summon'), +(74630, 'spell_gen_mod_radius_by_caster_scale'), +(74638, 'spell_halion_meteor_strike_targeting'), +(74641, 'spell_halion_meteor_strike_marker'), +(74696, 'spell_halion_meteor_strike_spread'), +(74768, 'spell_halion_twilight_cutter_periodic'), +(74769, 'spell_halion_twilight_cutter'), +(74792, 'spell_halion_soul_consumption'), +(74795, 'spell_halion_mark_of_consumption'), +(74800, 'spell_halion_consumption_summon'), +(74802, 'spell_gen_mod_radius_by_caster_scale'), +(74804, 'spell_halion_summon_exit_portals'), +(74805, 'spell_halion_summon_exit_portals'), +(74807, 'spell_halion_twilight_realm'), +(74808, 'spell_halion_twilight_phasing'), +(74812, 'spell_halion_leave_twilight_realm'), +(74856, 'spell_blazing_hippogryph'), +(74960, 'spell_gen_select_target_count_30_1'), +(75063, 'spell_halion_twilight_division'), +(75102, 'spell_voljin_war_drums'), +(75396, 'spell_halion_clear_debuffs'), +(75415, 'spell_ruby_sanctum_rallying_shout'), +(75420, 'spell_mount_check'), +(75509, 'spell_halion_twilight_mending'), +(75614, 'spell_celestial_steed'), +(75731, 'spell_item_instant_statue'), +(75874, 'spell_gen_mod_radius_by_caster_scale'), +(75875, 'spell_gen_mod_radius_by_caster_scale'), +(75876, 'spell_gen_mod_radius_by_caster_scale'), +(75882, 'spell_gen_mod_radius_by_caster_scale'), +(75883, 'spell_gen_mod_radius_by_caster_scale'), +(75884, 'spell_gen_mod_radius_by_caster_scale'), +(75886, 'spell_halion_blazing_aura'), +(75887, 'spell_halion_blazing_aura'), +(75973, 'spell_x53_touring_rocket'), +(76096, 'spell_item_lil_xt'), +(76098, 'spell_item_lil_xt'), +(77844, 'spell_halion_twilight_cutter'), +(77845, 'spell_halion_twilight_cutter'), +(77846, 'spell_halion_twilight_cutter'), +(100101, 'spell_valkyr_ball_periodic_dummy'); + +-- Restoring deleted spell_ranks for Threat of Thassarian +DELETE FROM `spell_ranks` WHERE `first_spell_id` IN (59133, 66216); +INSERT INTO `spell_ranks` (`first_spell_id`,`spell_id`,`rank`) VALUES +(59133, 59133, 1), +(59133, 66988, 2), +(59133, 66989, 3), +(59133, 66990, 4), +(59133, 66991, 5), +(59133, 66992, 6); + +-- Restoring spell_proc_events to how it was before the commit. +DROP TABLE IF EXISTS `spell_proc_event`; +CREATE TABLE IF NOT EXISTS `spell_proc_event` ( + `entry` MEDIUMINT(9) NOT NULL DEFAULT '0', + `SchoolMask` TINYINT(4) NOT NULL DEFAULT '0', + `SpellFamilyName` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0', + `SpellFamilyMask0` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `SpellFamilyMask1` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `SpellFamilyMask2` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `procFlags` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `procEx` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `procPhase` INT(10) UNSIGNED NOT NULL DEFAULT '0', + `ppmRate` FLOAT NOT NULL DEFAULT '0', + `CustomChance` FLOAT NOT NULL DEFAULT '0', + `Cooldown` INT(10) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`) +) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4; + +DELETE FROM `spell_proc_event`; + +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `procPhase`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(-66799, 0, 15, 4194304, 0, 0, 16, 0, 0, 0, 0, 0), +(-65661, 0, 15, 4194321, 537001988, 0, 16, 0, 0, 0, 100, 0), +(-64127, 0, 6, 1, 1, 0, 0, 0, 0, 0, 0, 0), +(-63730, 0, 6, 2048, 4, 0, 0, 0, 0, 0, 0, 0), +(-63373, 0, 11, 2147483648, 0, 0, 65536, 0, 0, 0, 0, 0), +(-63156, 126, 5, 1, 192, 0, 65536, 0, 0, 0, 0, 0), +(-62764, 0, 9, 0, 268435456, 0, 65536, 0, 0, 0, 100, 0), +(-61846, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), +(-61680, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-59088, 0, 4, 0, 2, 0, 1024, 0, 4, 0, 0, 0), +(-58872, 0, 0, 0, 0, 0, 0, 270403, 0, 0, 0, 0), +(-57878, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0), +(-57470, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 15000), +(-56636, 0, 4, 32, 0, 0, 0, 262144, 0, 0, 0, 5500), +(-56342, 0, 9, 24, 134217728, 409600, 0, 0, 0, 0, 0, 22000), +(-55666, 0, 15, 1, 134217728, 0, 0, 0, 0, 0, 0, 0), +(-54747, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(-54639, 0, 15, 4194304, 65536, 0, 0, 0, 0, 0, 0, 0), +(-53709, 2, 10, 16384, 0, 0, 0, 0, 0, 0, 0, 0), +(-53695, 0, 10, 8388608, 0, 8, 16, 0, 0, 0, 0, 0), +(-53671, 0, 10, 8388608, 0, 0, 0, 0, 0, 0, 0, 0), +(-53569, 0, 10, 2097152, 65536, 0, 0, 2, 0, 0, 0, 0), +(-53551, 0, 10, 4096, 0, 0, 0, 0, 0, 0, 0, 0), +(-53527, 1, 10, 0, 0, 4, 1024, 1, 0, 0, 100, 0), +(-53501, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-53486, 0, 10, 8388608, 163840, 0, 0, 262146, 0, 0, 0, 0), +(-53380, 0, 10, 8388608, 163840, 0, 0, 262146, 0, 0, 0, 0), +(-53290, 0, 9, 2048, 1, 512, 0, 2, 0, 0, 0, 0), +(-53256, 0, 9, 2048, 8388609, 0, 0, 2, 0, 0, 0, 0), +(-53234, 0, 9, 131072, 1, 1, 0, 2, 0, 0, 0, 0), +(-53228, 0, 9, 32, 16777216, 0, 0, 0, 0, 0, 0, 0), +(-53221, 0, 9, 0, 1, 0, 0, 0, 0, 0, 0, 0), +(-53215, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(-53178, 0, 9, 0, 268435456, 0, 65536, 0, 0, 0, 100, 0), +(-52795, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(-52127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(-51940, 0, 0, 0, 0, 0, 16384, 0, 0, 0, 0, 0), +(-51692, 0, 8, 516, 0, 0, 0, 0, 0, 0, 0, 0), +(-51672, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1000), +(-51664, 0, 8, 131072, 8, 0, 0, 0, 0, 0, 0, 0), +(-51634, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-51627, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0), +(-51625, 0, 8, 268476416, 0, 0, 0, 0, 0, 0, 0, 0), +(-51562, 0, 11, 256, 0, 16, 0, 0, 0, 0, 0, 0), +(-51556, 0, 11, 192, 0, 16, 0, 2, 0, 0, 0, 0), +(-51523, 0, 11, 0, 1, 0, 65536, 0, 0, 0, 50, 0), +(-51521, 0, 11, 0, 16, 0, 0, 0, 1, 0, 0, 1), +(-51474, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(-51459, 0, 15, 0, 536870912, 0, 20, 0, 0, 0, 0, 0), +(-50880, 0, 15, 0, 67108864, 0, 0, 0, 0, 0, 0, 0), +(-49467, 0, 15, 16, 131072, 0, 0, 0, 0, 0, 0, 0), +(-49223, 0, 15, 17, 134348800, 0, 0, 0, 0, 0, 0, 0), +(-49219, 0, 15, 0, 536870912, 0, 20, 0, 0, 0, 0, 0), +(-49217, 0, 15, 0, 0, 2, 0, 0, 0, 0, 0, 500), +(-49208, 0, 15, 4194304, 65536, 0, 0, 0, 0, 0, 0, 0), +(-49188, 0, 15, 0, 131072, 0, 0, 0, 0, 0, 0, 0), +(-49149, 0, 15, 6, 131074, 0, 0, 0, 0, 0, 0, 0), +(-49018, 0, 15, 20971520, 0, 0, 0, 0, 0, 0, 0, 0), +(-49004, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0), +(-48988, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-48539, 0, 7, 16, 67108864, 0, 262144, 0, 0, 0, 0, 0), +(-48516, 0, 7, 5, 0, 0, 0, 2, 0, 0, 0, 30000), +(-48506, 0, 7, 5, 0, 0, 0, 0, 0, 0, 0, 0), +(-48496, 0, 7, 96, 33554434, 0, 0, 2, 0, 0, 0, 0), +(-48483, 0, 7, 34816, 1088, 0, 0, 0, 0, 0, 0, 0), +(-47580, 0, 6, 0, 0, 64, 0, 65536, 0, 0, 0, 0), +(-47569, 0, 6, 16384, 0, 0, 16384, 0, 0, 0, 0, 0), +(-47516, 0, 6, 6144, 65536, 0, 0, 0, 0, 0, 0, 0), +(-47509, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-47263, 32, 5, 0, 0, 0, 0, 2, 0, 0, 0, 20000), +(-47258, 0, 5, 0, 8388608, 0, 0, 65536, 0, 0, 0, 0), +(-47245, 0, 5, 2, 0, 0, 0, 1, 0, 0, 0, 0), +(-47201, 0, 5, 16393, 262144, 0, 0, 0, 0, 0, 0, 0), +(-47195, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(-46945, 0, 4, 0, 65536, 0, 0, 0, 0, 0, 0, 0), +(-46913, 0, 4, 64, 1028, 0, 0, 262144, 0, 0, 0, 0), +(-46867, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-46854, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-45234, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-44557, 0, 3, 32, 0, 0, 0, 0, 0, 0, 0, 6000), +(-44449, 0, 3, 551686775, 102472, 0, 0, 2, 0, 0, 0, 0), +(-44445, 0, 3, 19, 69632, 0, 0, 0, 0, 0, 0, 0), +(-44442, 0, 3, 8388608, 64, 0, 0, 65536, 0, 0, 0, 1000), +(-41635, 0, 0, 0, 0, 0, 664232, 0, 0, 0, 0, 0), +(-35541, 0, 0, 0, 0, 0, 8388608, 0, 0, 0, 0, 0), +(-35100, 0, 9, 4096, 0, 1, 0, 0, 0, 0, 0, 0), +(-34950, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-34935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8000), +(-34914, 0, 6, 8192, 0, 0, 131073, 0, 0, 0, 0, 0), +(-34753, 0, 6, 6144, 4, 4096, 0, 2, 0, 0, 0, 0), +(-34500, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-34497, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-33881, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-33191, 0, 6, 8421376, 1024, 0, 0, 0, 0, 0, 0, 0), +(-33150, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-33142, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-33076, 0, 0, 0, 0, 0, 664232, 0, 0, 0, 0, 0), +(-32385, 0, 5, 1, 262144, 0, 0, 0, 0, 0, 0, 0), +(-31876, 0, 10, 8388608, 0, 0, 0, 262144, 0, 0, 0, 0), +(-31871, 0, 10, 16, 0, 0, 16384, 0, 0, 0, 0, 0), +(-31833, 0, 10, 2147483648, 0, 0, 0, 0, 0, 0, 0, 0), +(-31656, 4, 3, 134217728, 0, 0, 0, 0, 0, 0, 0, 0), +(-31571, 0, 3, 0, 34, 0, 16384, 0, 4, 0, 0, 0), +(-31569, 0, 3, 65536, 0, 0, 0, 0, 0, 0, 0, 0), +(-31244, 0, 8, 4063232, 9, 0, 0, 52, 0, 0, 0, 0), +(-31124, 0, 8, 16777222, 0, 0, 0, 0, 0, 0, 0, 0), +(-30881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(-30701, 28, 0, 0, 0, 0, 664232, 0, 0, 0, 100, 0), +(-30675, 0, 11, 3, 0, 0, 0, 0, 0, 0, 0, 0), +(-30299, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(-30293, 0, 5, 897, 8519872, 0, 0, 0, 0, 0, 0, 0), +(-30160, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-29834, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(-29593, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0), +(-29441, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0), +(-29074, 84, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-27811, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-20925, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(-20500, 0, 4, 268435456, 0, 0, 0, 0, 0, 0, 0, 0), +(-20335, 0, 10, 8388608, 0, 0, 16, 0, 0, 0, 100, 0), +(-20234, 0, 10, 32768, 0, 0, 0, 0, 0, 0, 0, 0), +(-20210, 0, 10, 3221225472, 65536, 0, 0, 2, 0, 0, 0, 0), +(-20049, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-19572, 0, 9, 8388608, 0, 0, 262144, 0, 0, 0, 0, 0), +(-19184, 0, 9, 16, 8192, 262144, 0, 0, 4, 0, 0, 0), +(-18119, 0, 5, 0, 8388608, 0, 0, 0, 0, 0, 0, 0), +(-18096, 0, 5, 256, 8388608, 0, 0, 2, 0, 0, 0, 0), +(-18094, 0, 5, 10, 0, 0, 262144, 262144, 0, 0, 0, 0), +(-17793, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(-17106, 0, 7, 524288, 0, 0, 0, 0, 0, 0, 0, 0), +(-16958, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-16952, 0, 7, 233472, 1024, 262144, 0, 2, 0, 0, 0, 0), +(-16880, 72, 7, 103, 58720258, 0, 0, 2, 1, 0, 0, 0), +(-16850, 0, 7, 4, 0, 0, 0, 0, 0, 0, 0, 0), +(-16511, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(-16487, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-16257, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 500), +(-16256, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-16180, 0, 11, 448, 0, 16, 0, 2, 0, 0, 100, 0), +(-16176, 0, 11, 448, 0, 16, 0, 2, 0, 0, 0, 0), +(-16086, 4, 11, 0, 262144, 0, 196608, 0, 0, 0, 0, 0), +(-15337, 0, 6, 8396800, 2, 0, 327680, 2, 0, 0, 100, 0), +(-14892, 0, 6, 268443136, 65540, 0, 0, 2, 0, 0, 0, 0), +(-14531, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-14186, 0, 8, 1082131720, 6, 0, 0, 2, 0, 0, 0, 1000), +(-14156, 0, 8, 4063232, 8, 0, 0, 0, 4, 0, 0, 0), +(-13983, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0), +(-13754, 0, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0), +(-13165, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0), +(-12966, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(-12834, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-12797, 0, 4, 1024, 0, 0, 0, 0, 0, 0, 0, 0), +(-12319, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-12311, 0, 4, 2048, 1, 0, 0, 0, 0, 0, 0, 0), +(-12298, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0), +(-12289, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(-12281, 0, 4, 2858419268, 4194565, 0, 0, 0, 0, 0, 0, 6000), +(-11255, 0, 3, 16384, 0, 0, 0, 0, 0, 0, 0, 0), +(-11213, 0, 3, 0, 0, 0, 0, 2359299, 0, 0, 0, 0), +(-11185, 0, 3, 128, 0, 0, 327680, 0, 0, 0, 0, 0), +(-11180, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(-11119, 4, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-11095, 0, 3, 16, 0, 0, 0, 0, 0, 0, 0, 0), +(-9799, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(-5952, 0, 8, 0, 1, 0, 0, 0, 0, 0, 0, 0), +(-1463, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0), +(-974, 0, 0, 0, 0, 0, 139944, 0, 0, 0, 0, 3000), +(-588, 0, 0, 0, 0, 0, 0, 262144, 0, 0, 0, 0), +(-324, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(1719, 0, 4, 778044484, 4212549, 0, 0, 2, 0, 0, 0, 0), +(1784, 0, 0, 0, 0, 0, 0, 262144, 0, 0, 0, 0), +(3232, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(4524, 0, 0, 0, 0, 0, 1048576, 262144, 0, 0, 0, 0), +(6346, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0), +(7383, 1, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0), +(7434, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(8178, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(9452, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(9782, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(9784, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(11129, 4, 3, 12582935, 200768, 0, 0, 0, 0, 0, 0, 0), +(12169, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(12322, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(12999, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(13000, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0), +(13001, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0), +(13002, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0), +(13163, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0), +(15088, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(15128, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(15257, 32, 6, 0, 0, 0, 327680, 0, 0, 0, 33, 0), +(15277, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(15286, 32, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(15331, 32, 6, 0, 0, 0, 327680, 0, 0, 0, 66, 0), +(15332, 32, 6, 0, 0, 0, 327680, 0, 0, 0, 100, 0), +(15346, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(15600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0), +(16164, 0, 11, 2416967875, 266240, 0, 69968, 2097154, 0, 0, 0, 0), +(16550, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(16620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(16624, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(16864, 0, 0, 0, 0, 0, 87060, 2162688, 0, 3.5, 0, 0), +(17364, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(17495, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(17619, 0, 13, 0, 0, 0, 34816, 3, 0, 0, 0, 0), +(18820, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(19577, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0), +(20128, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(20131, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(20132, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(20164, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0), +(20165, 0, 0, 0, 0, 0, 0, 1027, 0, 10, 0, 0), +(20166, 0, 0, 0, 0, 0, 0, 1027, 0, 12, 0, 0), +(20182, 0, 0, 0, 0, 0, 0, 262211, 0, 0, 0, 0), +(20185, 0, 0, 0, 0, 0, 1048576, 0, 0, 15, 0, 0), +(20186, 0, 0, 0, 0, 0, 1048576, 0, 0, 15, 0, 0), +(20375, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(20705, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(20784, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(20911, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0), +(21084, 3, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0), +(21185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(21882, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(21890, 0, 4, 712396527, 876, 0, 0, 0, 0, 0, 0, 0), +(22007, 0, 3, 2097185, 0, 0, 0, 65536, 0, 0, 0, 0), +(22618, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(22648, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(23547, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0), +(23548, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(23551, 0, 11, 192, 0, 0, 0, 0, 0, 0, 0, 0), +(23552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(23572, 0, 11, 192, 0, 0, 0, 0, 0, 0, 0, 0), +(23578, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0), +(23581, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0), +(23686, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0), +(23688, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(23689, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(23721, 0, 9, 2048, 0, 0, 0, 0, 0, 0, 0, 0), +(23920, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(24353, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(24389, 0, 3, 12582935, 64, 0, 0, 0, 1, 0, 0, 0), +(24658, 0, 0, 0, 0, 0, 82192, 0, 1, 0, 0, 0), +(24905, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(24932, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6000), +(25050, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(25669, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(25899, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0), +(26016, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0), +(26107, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0), +(26119, 0, 11, 2416967683, 0, 0, 65536, 65536, 0, 0, 0, 0), +(26128, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0), +(26135, 0, 10, 8388608, 0, 0, 0, 65536, 0, 0, 0, 0), +(26480, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(26605, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(27419, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(27498, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(27521, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 15000), +(27656, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(27774, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(27787, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(28305, 0, 0, 0, 0, 0, 4, 3, 0, 0, 100, 0), +(28460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5000), +(28716, 0, 7, 16, 0, 0, 262144, 0, 0, 0, 0, 0), +(28719, 0, 7, 32, 0, 0, 0, 2, 0, 0, 0, 0), +(28744, 0, 7, 64, 0, 0, 278528, 0, 0, 0, 0, 0), +(28752, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(28789, 0, 10, 3221225472, 0, 0, 0, 0, 0, 0, 0, 0), +(28802, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(28809, 0, 6, 4096, 0, 0, 0, 2, 0, 0, 0, 0), +(28812, 0, 8, 33554438, 0, 0, 0, 2, 0, 0, 0, 0), +(28816, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(28823, 0, 11, 192, 0, 0, 0, 0, 0, 0, 0, 0), +(28847, 0, 7, 32, 0, 0, 0, 0, 0, 0, 0, 0), +(28849, 0, 11, 128, 0, 0, 0, 0, 0, 0, 0, 0), +(29150, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29307, 0, 0, 0, 0, 0, 4, 65539, 0, 0, 100, 0), +(29385, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0), +(29455, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(29501, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29624, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29625, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29626, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29632, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29633, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29634, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29635, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29636, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29637, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(29977, 0, 3, 12582935, 64, 0, 0, 0, 0, 0, 0, 0), +(30003, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(30823, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0), +(30937, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(31221, 0, 8, 4196352, 0, 0, 1024, 0, 0, 0, 0, 0), +(31222, 0, 8, 4196352, 0, 0, 1024, 0, 0, 0, 0, 0), +(31223, 0, 8, 4196352, 0, 0, 1024, 0, 0, 0, 0, 0), +(31394, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(31794, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(31801, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0), +(31904, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(32216, 0, 4, 0, 256, 0, 16, 0, 4, 0, 0, 0), +(32409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(32587, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(32642, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(32734, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(32748, 0, 8, 0, 1, 0, 320, 0, 1, 0, 0, 0), +(32776, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(32777, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(32837, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 45000), +(32844, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0), +(32885, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(33089, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(33127, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0), +(33297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(33299, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(33510, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0), +(33648, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(33719, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(33746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(33757, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 3000), +(33759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(33953, 0, 0, 0, 0, 0, 278528, 3, 0, 0, 0, 45000), +(34074, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0), +(34080, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0), +(34138, 0, 11, 128, 0, 0, 0, 0, 0, 0, 0, 0), +(34139, 0, 10, 1073741824, 0, 0, 0, 0, 0, 0, 0, 0), +(34258, 0, 10, 8388608, 0, 0, 0, 262144, 0, 0, 0, 0), +(34262, 0, 10, 8388608, 0, 0, 0, 262144, 0, 0, 0, 0), +(34320, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(34355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(34477, 0, 9, 0, 0, 0, 349524, 0, 0, 0, 100, 0), +(34584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(34586, 0, 0, 0, 0, 0, 0, 0, 0, 1.5, 0, 0), +(34598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(34749, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0), +(34774, 0, 0, 0, 0, 0, 0, 0, 0, 1.5, 0, 20000), +(34783, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(34827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(35077, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(35080, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 60000), +(35083, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(35086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(35121, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(36032, 0, 3, 4096, 32768, 0, 0, 0, 1, 0, 0, 0), +(36096, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(36111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(36541, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(37165, 0, 8, 2098176, 0, 0, 0, 0, 0, 0, 0, 0), +(37168, 0, 8, 4063232, 9, 0, 0, 0, 4, 0, 0, 0), +(37170, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(37173, 0, 8, 750519704, 262, 0, 0, 0, 0, 0, 0, 30000), +(37189, 0, 10, 3221225472, 0, 0, 0, 2, 0, 0, 0, 60000), +(37193, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(37195, 0, 10, 8388608, 0, 0, 0, 262144, 0, 0, 0, 0), +(37197, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 45000), +(37213, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(37214, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(37227, 0, 11, 448, 0, 0, 0, 2, 0, 0, 0, 60000), +(37237, 0, 11, 1, 0, 0, 0, 2, 0, 0, 0, 0), +(37247, 8, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 45000), +(37377, 32, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(37379, 32, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(37384, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(37443, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(37447, 0, 3, 0, 256, 0, 17408, 0, 0, 0, 100, 15000), +(37514, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0), +(37516, 0, 4, 1024, 0, 0, 0, 0, 0, 0, 0, 0), +(37519, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0), +(37523, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(37528, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0), +(37536, 0, 4, 65536, 0, 0, 0, 0, 0, 0, 0, 0), +(37568, 0, 6, 2048, 0, 0, 0, 0, 0, 0, 0, 0), +(37594, 0, 6, 4096, 0, 0, 0, 0, 0, 0, 0, 0), +(37600, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(37601, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(37603, 0, 6, 32768, 0, 0, 0, 0, 0, 0, 0, 0), +(37655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(37657, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3000), +(38026, 1, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0), +(38031, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(38290, 0, 0, 0, 0, 0, 0, 0, 0, 1.6, 0, 0), +(38299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15000), +(38326, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(38327, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(38334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(38347, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(38350, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(38394, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0), +(38857, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(39027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(39372, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(39437, 4, 5, 4964, 192, 0, 0, 65536, 0, 0, 0, 0), +(39442, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), +(39443, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(39530, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(39958, 0, 0, 0, 0, 0, 0, 0, 0, 0.7, 0, 40000), +(40407, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(40438, 0, 6, 32832, 0, 0, 0, 0, 0, 0, 0, 0), +(40442, 0, 7, 20, 1088, 0, 0, 0, 1, 0, 0, 0), +(40444, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(40458, 0, 4, 33554432, 1537, 0, 0, 0, 0, 0, 0, 0), +(40463, 0, 11, 129, 16, 0, 0, 0, 0, 0, 0, 0), +(40470, 0, 10, 3229614080, 0, 0, 0, 262144, 0, 0, 0, 0), +(40475, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0), +(40478, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(40482, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(40485, 0, 9, 0, 1, 0, 0, 0, 0, 0, 0, 0), +(40899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(41034, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0), +(41260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(41262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(41350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(41381, 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0), +(41393, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0), +(41434, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 45000), +(41469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0), +(41989, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0), +(42083, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(42135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90000), +(42136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90000), +(42368, 0, 10, 1073741824, 0, 0, 0, 0, 0, 0, 0, 0), +(42370, 0, 11, 128, 0, 0, 0, 0, 0, 0, 0, 0), +(42760, 0, 0, 0, 0, 0, 245966, 0, 0, 0, 20, 0), +(42770, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(43338, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(43443, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(43726, 0, 10, 1073741824, 0, 0, 0, 0, 0, 0, 0, 0), +(43728, 0, 11, 128, 0, 0, 0, 0, 0, 0, 0, 0), +(43737, 0, 7, 0, 1088, 0, 0, 0, 0, 0, 0, 10000), +(43739, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(43741, 0, 10, 2147483648, 0, 0, 0, 0, 0, 0, 0, 0), +(43745, 0, 10, 0, 512, 0, 0, 0, 0, 0, 0, 0), +(43748, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(43750, 0, 11, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(43819, 0, 0, 0, 0, 0, 0, 65536, 1, 0, 0, 0), +(44404, 0, 3, 536870945, 36864, 0, 0, 0, 0, 0, 0, 0), +(44543, 0, 3, 1049120, 4096, 0, 65536, 0, 7, 0, 7, 0), +(44545, 0, 3, 1049120, 4096, 0, 65536, 0, 7, 0, 15, 0), +(44546, 0, 3, 1049120, 4096, 0, 69632, 0, 0, 0, 5, 3000), +(44548, 0, 3, 1049120, 4096, 0, 69632, 0, 0, 0, 10, 3000), +(44549, 0, 3, 1049120, 4096, 0, 69632, 0, 0, 0, 15, 3000), +(44835, 0, 7, 0, 128, 0, 16, 0, 0, 0, 0, 0), +(45054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15000), +(45057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(45354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(45355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(45469, 0, 15, 16, 0, 0, 16, 0, 0, 0, 0, 0), +(45481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(45482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(45483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(45484, 0, 0, 0, 0, 0, 16384, 0, 0, 0, 0, 45000), +(46025, 32, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(46092, 0, 10, 1073741824, 0, 0, 0, 0, 0, 0, 0, 0), +(46098, 0, 11, 128, 0, 0, 0, 0, 0, 0, 0, 0), +(46569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(46662, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20000), +(46832, 0, 7, 1, 0, 0, 0, 65536, 0, 0, 0, 0), +(46910, 0, 4, 64, 0, 0, 20, 0, 0, 5.5, 0, 0), +(46911, 0, 4, 64, 0, 0, 20, 0, 0, 7.5, 0, 0), +(46916, 0, 4, 2097152, 0, 0, 0, 0, 4, 0, 0, 0), +(46951, 0, 4, 1024, 64, 0, 0, 0, 0, 0, 0, 0), +(46952, 0, 0, 1024, 64, 0, 0, 0, 0, 0, 0, 0), +(46953, 0, 0, 1024, 64, 0, 0, 0, 0, 0, 0, 0), +(47981, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(48833, 0, 7, 0, 1088, 0, 0, 0, 0, 0, 0, 0), +(48835, 0, 10, 8388608, 0, 0, 0, 262144, 0, 0, 0, 0), +(48837, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(49027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20000), +(49028, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(49194, 0, 15, 8192, 0, 0, 0, 0, 0, 0, 0, 0), +(49222, 0, 0, 0, 0, 0, 139944, 0, 0, 0, 0, 2000), +(49542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 20000), +(49543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 20000), +(49592, 0, 0, 0, 0, 0, 664232, 262144, 0, 0, 100, 0), +(49622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(50240, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0), +(50421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1000), +(50781, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6000), +(50871, 0, 9, 0, 1342177280, 0, 0, 2, 0, 0, 100, 0), +(51123, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(51127, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0), +(51128, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0), +(51129, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0), +(51130, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0), +(51346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(51349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(51352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(51359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(51414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(51528, 0, 0, 0, 0, 0, 0, 0, 0, 2.5, 0, 0), +(51529, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0), +(51530, 0, 0, 0, 0, 0, 0, 0, 0, 7.5, 0, 0), +(51531, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0), +(51532, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0), +(51682, 0, 8, 0, 524288, 0, 0, 0, 0, 0, 0, 0), +(51698, 0, 0, 0, 0, 0, 0, 2, 4, 0, 33, 1000), +(51700, 0, 0, 0, 0, 0, 0, 2, 4, 0, 66, 1000), +(51701, 0, 0, 0, 0, 0, 0, 2, 4, 0, 100, 1000), +(51915, 0, 0, 0, 0, 0, 16777216, 0, 0, 0, 100, 600000), +(52020, 0, 7, 32768, 1048576, 0, 0, 0, 0, 0, 0, 0), +(52420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(52423, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0), +(52437, 1, 4, 536870912, 0, 0, 16, 0, 4, 0, 0, 0), +(52898, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(53386, 48, 15, 8195, 6, 128, 349456, 0, 0, 0, 0, 0), +(53397, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(53583, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0), +(53585, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0), +(53601, 0, 0, 0, 0, 0, 688808, 0, 0, 0, 0, 6000), +(53646, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 20000), +(53736, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0), +(54278, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(54404, 0, 0, 0, 0, 0, 0, 4, 0, 0, 100, 0), +(54486, 0, 0, 536870945, 36864, 0, 0, 0, 0, 0, 0, 0), +(54488, 0, 0, 536870945, 36864, 0, 0, 0, 0, 0, 0, 0), +(54489, 0, 0, 536870945, 36864, 0, 0, 0, 0, 0, 0, 0), +(54490, 0, 0, 536870945, 36864, 0, 0, 0, 0, 0, 0, 0), +(54646, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(54695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(54707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(54738, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(54754, 0, 7, 16, 0, 0, 0, 0, 0, 0, 0, 0), +(54808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(54815, 0, 7, 32768, 0, 0, 16, 0, 0, 0, 0, 0), +(54821, 0, 7, 4096, 0, 0, 16, 0, 0, 0, 0, 0), +(54832, 0, 7, 0, 4096, 0, 16384, 0, 0, 0, 0, 0), +(54838, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(54841, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3000), +(54845, 0, 7, 4, 0, 0, 65536, 0, 0, 0, 0, 0), +(54909, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 20000), +(54925, 2, 10, 0, 512, 0, 0, 0, 0, 0, 0, 0), +(54937, 0, 10, 2147483648, 0, 0, 0, 0, 0, 0, 0, 0), +(54939, 0, 10, 32768, 0, 0, 0, 0, 0, 0, 0, 0), +(55198, 0, 11, 448, 0, 0, 16384, 2, 0, 0, 0, 0), +(55380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(55381, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 15000), +(55440, 0, 11, 64, 0, 0, 0, 0, 0, 0, 0, 0), +(55610, 0, 15, 0, 67108864, 0, 4096, 0, 0, 0, 0, 0), +(55640, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 45000), +(55677, 0, 6, 0, 1, 0, 0, 0, 0, 0, 0, 0), +(55680, 0, 6, 512, 0, 0, 0, 0, 0, 0, 0, 0), +(55681, 0, 6, 32768, 0, 0, 262144, 0, 0, 0, 0, 0), +(55689, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(55717, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5000), +(55747, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(55768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(55776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(56218, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(56249, 0, 5, 0, 0, 1024, 0, 0, 0, 0, 0, 0), +(56355, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(56364, 0, 3, 0, 16777216, 0, 0, 0, 0, 0, 0, 0), +(56372, 0, 3, 0, 128, 0, 16384, 0, 0, 0, 0, 0), +(56374, 0, 3, 0, 16384, 0, 16384, 0, 0, 0, 0, 0), +(56375, 0, 3, 16777216, 0, 0, 65536, 0, 0, 0, 0, 0), +(56451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3000), +(56800, 0, 8, 4, 0, 0, 16, 0, 0, 0, 0, 0), +(56816, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0), +(56817, 0, 15, 0, 536870912, 0, 0, 0, 0, 0, 0, 0), +(56821, 0, 8, 2, 0, 0, 0, 2, 0, 0, 0, 0), +(56845, 0, 9, 8, 0, 0, 2097152, 0, 0, 0, 0, 0), +(57345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(57351, 0, 0, 0, 0, 0, 1782780, 0, 0, 0, 0, 0), +(57352, 0, 0, 0, 0, 0, 332116, 0, 0, 0, 0, 45000), +(57870, 0, 9, 8388608, 0, 0, 262144, 0, 0, 0, 0, 0), +(57907, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(57989, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0), +(58357, 0, 4, 64, 0, 0, 0, 2, 0, 0, 0, 0), +(58364, 0, 4, 1024, 0, 0, 0, 0, 0, 0, 0, 0), +(58372, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(58375, 0, 4, 0, 512, 0, 65552, 0, 1, 0, 100, 0), +(58386, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0), +(58410, 0, 0, 0, 0, 0, 0, 65539, 0, 0, 0, 0), +(58413, 0, 8, 0, 524288, 0, 0, 0, 0, 0, 0, 0), +(58426, 0, 8, 4196352, 0, 0, 1024, 0, 0, 0, 0, 0), +(58442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15000), +(58444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5000), +(58616, 0, 15, 16777216, 0, 0, 0, 0, 0, 0, 0, 0), +(58620, 0, 15, 4, 0, 0, 0, 0, 0, 0, 0, 0), +(58626, 0, 15, 33554432, 0, 0, 0, 0, 0, 0, 0, 0), +(58642, 0, 15, 0, 134217728, 0, 16, 0, 0, 0, 0, 0), +(58644, 0, 15, 0, 4, 0, 0, 0, 0, 0, 0, 0), +(58647, 0, 15, 0, 4, 0, 0, 0, 0, 0, 0, 0), +(58677, 0, 15, 8192, 0, 0, 0, 0, 0, 0, 0, 0), +(58901, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(59176, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(59327, 0, 15, 134217728, 0, 0, 0, 0, 0, 0, 0, 0), +(59345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(59630, 0, 0, 0, 0, 0, 69648, 0, 1, 0, 0, 35000), +(59725, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(59887, 0, 0, 0, 0, 0, 87040, 3, 1, 0, 0, 0), +(59888, 0, 0, 0, 0, 0, 87040, 3, 0, 0, 0, 0), +(59889, 0, 0, 0, 0, 0, 87040, 3, 0, 0, 0, 0), +(59890, 0, 0, 0, 0, 0, 87040, 3, 0, 0, 0, 0), +(59891, 0, 0, 0, 0, 0, 87040, 3, 0, 0, 0, 0), +(60061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60063, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0, 45000), +(60066, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(60132, 0, 15, 16, 134348800, 0, 0, 0, 0, 0, 0, 0), +(60170, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0), +(60172, 0, 5, 262144, 0, 0, 0, 0, 0, 0, 0, 0), +(60176, 0, 4, 32, 16, 0, 0, 0, 0, 0, 0, 0), +(60221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15000), +(60490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60503, 1, 4, 4, 0, 0, 16, 65536, 0, 0, 0, 0), +(60519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60524, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(60529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(60537, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(60564, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(60571, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(60572, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(60573, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(60574, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(60575, 0, 11, 2416967680, 0, 0, 0, 0, 0, 0, 0, 0), +(60617, 0, 0, 0, 0, 0, 0, 32, 0, 0, 100, 0), +(60710, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(60717, 0, 7, 2, 0, 0, 0, 0, 0, 0, 100, 0), +(60719, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(60722, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(60724, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(60726, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(60770, 0, 11, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(60818, 0, 10, 0, 512, 0, 0, 0, 0, 0, 0, 0), +(60826, 0, 15, 20971520, 0, 0, 0, 0, 0, 0, 0, 0), +(61062, 0, 3, 0, 256, 0, 17408, 0, 0, 0, 100, 15000), +(61188, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0), +(61257, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0), +(61324, 0, 10, 0, 131072, 0, 0, 0, 0, 0, 0, 0), +(61356, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 90000), +(61618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(61848, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0), +(62114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(62115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(62147, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(62337, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0), +(62459, 0, 15, 4, 0, 0, 0, 0, 0, 0, 0, 0), +(62600, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(62933, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0), +(63086, 0, 9, 0, 0, 65536, 0, 0, 0, 0, 0, 0), +(63108, 0, 5, 2, 0, 0, 0, 262144, 0, 0, 0, 0), +(63251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(63310, 0, 5, 0, 65536, 0, 65536, 1027, 0, 0, 0, 0), +(63320, 0, 5, 2147745792, 0, 32768, 1024, 0, 0, 0, 0, 0), +(63335, 0, 15, 0, 2, 0, 0, 0, 0, 0, 0, 0), +(63611, 0, 0, 0, 0, 0, 332116, 0, 0, 0, 0, 0), +(64343, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0), +(64411, 0, 0, 0, 0, 0, 279552, 786432, 0, 0, 0, 0), +(64415, 0, 0, 0, 0, 0, 0, 524288, 0, 0, 0, 45000), +(64440, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 20000), +(64571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000), +(64714, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(64738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(64742, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(64752, 0, 7, 8392704, 256, 2097152, 0, 0, 0, 0, 0, 0), +(64786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(64792, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(64824, 0, 7, 2097152, 0, 0, 0, 0, 0, 0, 0, 0), +(64860, 0, 9, 0, 1, 0, 0, 0, 0, 0, 0, 0), +(64867, 0, 3, 536870945, 4096, 0, 0, 0, 0, 0, 0, 45000), +(64882, 0, 10, 0, 1048576, 0, 0, 0, 0, 0, 0, 0), +(64890, 0, 10, 0, 65536, 0, 0, 2, 0, 0, 0, 0), +(64908, 0, 6, 8192, 0, 0, 0, 0, 0, 0, 0, 0), +(64912, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(64914, 0, 8, 65536, 0, 0, 0, 0, 0, 0, 0, 0), +(64928, 0, 11, 1, 0, 0, 0, 2, 0, 0, 0, 0), +(64936, 0, 4, 4096, 0, 0, 69632, 0, 0, 0, 100, 0), +(64938, 0, 4, 2097216, 0, 0, 0, 2, 0, 0, 0, 0), +(64952, 0, 7, 0, 1088, 0, 0, 0, 0, 0, 0, 0), +(64955, 0, 10, 0, 64, 0, 0, 0, 0, 0, 0, 0), +(64964, 0, 15, 0, 536870912, 0, 0, 0, 0, 0, 0, 0), +(64976, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0), +(64999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(65002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(65005, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 45000), +(65013, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 45000), +(65020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(65025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(66808, 0, 0, 0, 0, 0, 4, 0, 0, 0, 100, 0), +(66865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 3000), +(66889, 0, 0, 0, 0, 0, 4, 0, 0, 0, 100, 0), +(67115, 0, 15, 20971520, 0, 0, 0, 0, 0, 0, 0, 45000), +(67151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(67209, 1, 8, 1048576, 0, 0, 327680, 0, 0, 0, 0, 0), +(67210, 0, 8, 4294967295, 4294967295, 4294967295, 0, 0, 0, 0, 0, 0), +(67353, 0, 7, 32768, 1049856, 0, 0, 0, 0, 0, 0, 0), +(67356, 8, 7, 16, 0, 0, 0, 0, 0, 0, 0, 0), +(67361, 0, 7, 2, 0, 0, 262144, 0, 0, 0, 0, 0), +(67363, 0, 10, 2147483648, 0, 0, 0, 0, 0, 0, 0, 10000), +(67365, 0, 10, 0, 2048, 0, 262144, 0, 0, 0, 0, 6000), +(67379, 0, 10, 0, 262144, 0, 0, 0, 0, 0, 0, 0), +(67381, 0, 15, 0, 536870912, 0, 0, 0, 0, 0, 0, 10000), +(67384, 0, 15, 16, 134348800, 0, 0, 0, 0, 0, 80, 10000), +(67386, 0, 11, 1, 0, 0, 65536, 0, 1, 0, 0, 6000), +(67389, 0, 11, 256, 0, 0, 16384, 0, 1, 0, 0, 8000), +(67392, 0, 11, 0, 0, 4, 16, 0, 0, 0, 0, 0), +(67530, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 5000), +(67653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50000), +(67667, 0, 0, 0, 0, 0, 16384, 0, 1, 0, 0, 45000), +(67670, 0, 0, 0, 0, 0, 65536, 0, 1, 0, 0, 45000), +(67672, 0, 0, 0, 0, 0, 8388948, 0, 0, 0, 0, 45000), +(67698, 0, 0, 0, 0, 0, 87040, 3, 1, 0, 0, 0), +(67702, 1, 0, 0, 0, 0, 332116, 262147, 0, 0, 35, 45000), +(67712, 0, 0, 0, 0, 0, 69632, 2, 0, 0, 0, 2000), +(67752, 0, 0, 0, 0, 0, 87040, 3, 1, 0, 0, 0), +(67758, 0, 0, 0, 0, 0, 69632, 2, 0, 0, 0, 2000), +(67771, 1, 0, 0, 0, 0, 332116, 262147, 0, 0, 35, 45000), +(68051, 1, 4, 4, 0, 0, 16, 0, 0, 0, 0, 0), +(68160, 0, 0, 0, 0, 0, 4, 0, 0, 0, 100, 0), +(69056, 0, 0, 0, 0, 0, 0, 2048, 0, 0, 0, 0), +(69172, 0, 0, 4294967295, 4294967295, 4294967295, 0, 65539, 0, 0, 0, 0), +(69173, 0, 0, 4294967295, 4294967295, 4294967295, 0, 65539, 0, 0, 0, 0), +(69580, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0), +(69739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(69755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(69762, 0, 0, 0, 0, 0, 87040, 3, 1, 0, 100, 0), +(70652, 0, 15, 8, 0, 0, 0, 0, 0, 0, 0, 0), +(70664, 0, 7, 16, 0, 0, 0, 0, 0, 0, 0, 0), +(70672, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(70723, 0, 7, 5, 0, 0, 65536, 2, 0, 0, 100, 0), +(70727, 0, 9, 0, 0, 0, 64, 0, 0, 0, 0, 0), +(70730, 0, 9, 16384, 4096, 0, 262144, 0, 0, 0, 0, 0), +(70748, 0, 3, 0, 2097152, 0, 1024, 0, 0, 0, 0, 0), +(70756, 0, 10, 2097152, 65536, 0, 0, 0, 0, 0, 0, 0), +(70761, 0, 10, 0, 2147500032, 1, 1024, 0, 0, 0, 0, 0), +(70803, 0, 8, 4063232, 8, 0, 0, 0, 0, 0, 0, 0), +(70805, 0, 8, 0, 131072, 0, 0, 0, 0, 0, 0, 1000), +(70807, 0, 11, 0, 0, 16, 0, 0, 0, 0, 100, 0), +(70808, 0, 11, 256, 0, 0, 0, 2, 0, 0, 0, 0), +(70811, 0, 11, 3, 0, 0, 0, 0, 1, 0, 0, 0), +(70817, 0, 11, 0, 4096, 0, 65536, 0, 0, 0, 0, 0), +(70830, 0, 11, 0, 131072, 0, 0, 0, 0, 0, 0, 0), +(70841, 0, 5, 4, 256, 0, 262144, 0, 0, 0, 0, 0), +(70844, 0, 4, 256, 0, 0, 0, 0, 0, 0, 0, 0), +(70854, 0, 4, 0, 16, 0, 0, 0, 0, 0, 0, 0), +(70871, 0, 0, 0, 0, 0, 69972, 3, 0, 0, 100, 0), +(71039, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(71174, 0, 7, 4096, 256, 0, 262144, 0, 0, 0, 0, 0), +(71176, 0, 7, 2097154, 0, 0, 262144, 0, 0, 0, 0, 0), +(71178, 0, 7, 16, 0, 0, 262144, 0, 0, 0, 0, 0), +(71186, 0, 10, 0, 32768, 0, 0, 0, 0, 0, 0, 0), +(71191, 0, 10, 0, 65536, 0, 0, 0, 0, 0, 0, 0), +(71194, 0, 10, 0, 1048576, 0, 0, 0, 0, 0, 0, 0), +(71198, 0, 11, 268435456, 0, 0, 0, 0, 0, 0, 0, 0), +(71214, 0, 11, 5120, 16, 0, 16, 0, 0, 0, 0, 6000), +(71217, 0, 11, 0, 0, 16, 16384, 0, 0, 0, 0, 0), +(71226, 0, 15, 16, 134348800, 0, 0, 0, 0, 0, 0, 0), +(71228, 0, 15, 0, 536870912, 0, 0, 0, 0, 0, 0, 0), +(71402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(71404, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 50000), +(71406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0), +(71494, 0, 0, 0, 0, 0, 0, 16255, 0, 0, 0, 0), +(71519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105000), +(71540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(71545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0), +(71562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105000), +(71564, 126, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0), +(71567, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 400), +(71585, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 45000), +(71604, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 100, 10000), +(71606, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100000), +(71611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(71634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(71637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100000), +(71640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30000), +(71642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(71645, 0, 0, 0, 0, 0, 65536, 3, 1, 0, 0, 45000), +(71770, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(71865, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0), +(71868, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0), +(71880, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(71892, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0), +(71903, 0, 0, 0, 0, 0, 0, 1049603, 0, 0, 75, 0), +(72059, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0), +(72176, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(72178, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(72256, 0, 0, 0, 0, 0, 4, 65536, 0, 0, 0, 0), +(72413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60000), +(72417, 0, 0, 0, 0, 0, 327680, 0, 0, 0, 0, 60000), +(72455, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(72673, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 100, 10000), +(72674, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 100, 10000), +(72675, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 100, 10000), +(72832, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(72833, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(73878, 0, 0, 0, 0, 0, 0, 65536, 0, 0, 0, 0), +(74396, 84, 3, 685904631, 1151040, 0, 65536, 3, 0, 0, 0, 0), +(75455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(75457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(16372, 0, 0, 0, 0, 0, 131072, 1, 0, 0, 100, 0), +(75475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(75481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45000), +(71761, 0, 3, 0, 1048576, 0, 0, 256, 0, 0, 0, 0), +(56841, 0, 9, 2048, 2048, 2048, 256, 0, 0, 0, 0, 0), +(16166, 0, 11, 3, 4096, 0, 0, 0, 1, 0, 0, 0), +(16188, 8, 11, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(16246, 0, 11, 2551185859, 5120, 16, 87376, 0, 1, 0, 0, 0), +(17116, 8, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(4341, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(28200, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(63280, 0, 11, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(65007, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0), +(21747, 0, 10, 0, 0, 0, 20, 0, 0, 20, 0, 50000), +(-16689, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1000), +(71756, 0, 0, 0, 0, 0, 0, 1027, 2, 0, 0, 0); + +-- Restoring the command +DELETE FROM `command` WHERE `name`='reload spell_proc_event'; +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('reload spell_proc_event', 3, 'Syntax: .reload spell_proc_event\nReload spell_proc_event table.'); + +DELETE FROM `updates` WHERE `name` = '2022_10_02_01.sql'; diff --git a/src/server/game/Combat/ThreatMgr.cpp b/src/server/game/Combat/ThreatMgr.cpp index 51c38a0ce0..91751f22a0 100644 --- a/src/server/game/Combat/ThreatMgr.cpp +++ b/src/server/game/Combat/ThreatMgr.cpp @@ -46,7 +46,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, float threat, SpellSchoolMas return threat; if (Player* modOwner = hatedUnit->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_THREAT>(threatSpell->Id, threat); + modOwner->ApplySpellMod(threatSpell->Id, SPELLMOD_THREAT, threat); } return hatedUnit->ApplyTotalThreatModifier(threat, schoolMask); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6b9c4b666a..512e7c39eb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -2751,8 +2751,8 @@ void Creature::AddSpellCooldown(uint32 spell_id, uint32 /*itemid*/, uint32 end_t uint32 categorycooldown = categoryId ? spellInfo->CategoryRecoveryTime : 0; if (Player* modOwner = GetSpellModOwner()) { - modOwner->ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, spellcooldown); - modOwner->ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, categorycooldown); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, spellcooldown); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, categorycooldown); } SpellCategoryStore::const_iterator i_scstore = sSpellsByCategoryStore.find(categoryId); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e152cfe424..79d8565cd3 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -764,7 +764,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) case DAMAGE_LAVA: case DAMAGE_SLIME: { - DamageInfo dmgInfo(this, this, damage, nullptr, type == DAMAGE_LAVA ? SPELL_SCHOOL_MASK_FIRE : SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE, BASE_ATTACK); + DamageInfo dmgInfo(this, this, damage, nullptr, type == DAMAGE_LAVA ? SPELL_SCHOOL_MASK_FIRE : SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE); Unit::CalcAbsorbResist(dmgInfo); absorb = dmgInfo.GetAbsorb(); resist = dmgInfo.GetResist(); @@ -7058,22 +7058,21 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, } } -void Player::CastItemCombatSpell(DamageInfo const& damageInfo) +void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx) { - Unit* target = damageInfo.GetVictim(); if (!target || !target->IsAlive() || target == this) return; // Xinef: do not use disarmed weapons, special exception - shaman ghost wolf form // Xinef: normal forms proc on hit enchants / built in item bonuses - if (!CanUseAttackType(damageInfo.GetAttackType()) || GetShapeshiftForm() == FORM_GHOSTWOLF) + if (!CanUseAttackType(attType) || GetShapeshiftForm() == FORM_GHOSTWOLF) return; for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) { // If usable, try to cast item spell if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (!item->IsBroken() && CanUseAttackType(damageInfo.GetAttackType())) + if (!item->IsBroken()) if (ItemTemplate const* proto = item->GetTemplate()) { // Additional check for weapons @@ -7081,7 +7080,7 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo) { // offhand item cannot proc from main hand hit etc EquipmentSlots slot; - switch (damageInfo.GetAttackType()) + switch (attType) { case BASE_ATTACK: slot = EQUIPMENT_SLOT_MAINHAND; @@ -7100,20 +7099,19 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo) continue; } - CastItemCombatSpell(damageInfo, item, proto); + CastItemCombatSpell(target, attType, procVictim, procEx, item, proto); } } } -void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto) +void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto) { -// if (!sScriptMgr->CanCastItemCombatSpell(this, target, attType, procVictim, procEx, item, proto)) -// return; + if (!sScriptMgr->CanCastItemCombatSpell(this, target, attType, procVictim, procEx, item, proto)) + return; // Can do effect if any damage done to target - // for done procs allow normal + critical + absorbs by default - bool canTrigger = (damageInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL | PROC_HIT_ABSORB)) != 0; - if (canTrigger) + if (procVictim & PROC_FLAG_TAKEN_DAMAGE) + //if (damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE) { for (uint8 i = 0; i < MAX_ITEM_SPELLS; ++i) { @@ -7134,15 +7132,11 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT continue; } - // not allow proc extra attack spell at extra attack - if (m_extraAttacks && spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) - return; - float chance = (float)spellInfo->ProcChance; if (spellData.SpellPPMRate) { - uint32 WeaponSpeed = GetAttackTime(damageInfo.GetAttackType()); + uint32 WeaponSpeed = GetAttackTime(attType); chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate, spellInfo); } else if (chance > 100.0f) @@ -7150,8 +7144,8 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT chance = GetWeaponProcChance(); } - if (roll_chance_f(chance)/* && sScriptMgr->OnCastItemCombatSpell(this, target, spellInfo, item)*/) - CastSpell(damageInfo.GetVictim(), spellInfo->Id, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); + if (roll_chance_f(chance) && sScriptMgr->OnCastItemCombatSpell(this, target, spellInfo, item)) + CastSpell(target, spellInfo->Id, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); } } @@ -7173,14 +7167,14 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT if (entry && entry->procEx) { // Check hit/crit/dodge/parry requirement - if ((entry->procEx & damageInfo.GetHitMask()) == 0) + if ((entry->procEx & procEx) == 0) continue; } else { // Can do effect if any damage done to target - // for done procs allow normal + critical + absorbs by default - if (!canTrigger) + if (!(procVictim & PROC_FLAG_TAKEN_DAMAGE)) + //if (!(damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE)) continue; } @@ -7203,7 +7197,7 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT } // Apply spell mods - ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(pEnchant->spellid[s], chance); + ApplySpellMod(pEnchant->spellid[s], SPELLMOD_CHANCE_OF_SUCCESS, chance); // Shiv has 100% chance to apply the poison if (FindCurrentSpellBySpellId(5938) && e_slot == TEMP_ENCHANTMENT_SLOT) @@ -7226,7 +7220,7 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT if (spellInfo->IsPositive()) CastSpell(this, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); else - CastSpell(damageInfo.GetVictim(), spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); + CastSpell(target, spellInfo, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD), item); } } } @@ -9571,11 +9565,9 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod if (!mod || !spellInfo) return false; - // First time this aura applies a mod to us and is out of charges - if (spell && mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges() && !spell->m_appliedMods.count(mod->ownerAura)) - { + // Mod out of charges + if (spell && mod->charges == -1 && spell->m_appliedMods.find(mod->ownerAura) == spell->m_appliedMods.end()) return false; - } // +duration to infinite duration spells making them limited if (mod->op == SPELLMOD_DURATION && spellInfo->GetDuration() == -1) @@ -9617,46 +9609,50 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) LOG_DEBUG("spells.aura", "Player::AddSpellMod {}", mod->spellId); uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; - flag96 modMask; - for (uint8 i = 0; i < 3; ++i) + int i = 0; + flag96 _mask = 0; + for (int eff = 0; eff < 96; ++eff) { - for (uint32 eff = 0; eff < 32; ++eff) + if (eff != 0 && eff % 32 == 0) + _mask[i++] = 0; + + _mask[i] = uint32(1) << (eff - (32 * i)); + if (mod->mask & _mask) { - modMask[i] = uint32(1) << eff; - if ((mod->mask & modMask)) + int32 val = 0; + for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) { - int32 val = 0; - for (SpellModifier* spellMod : m_spellMods[mod->op]) - { - if (spellMod->type == mod->type && (spellMod->mask & modMask)) - { - val += spellMod->value; - } - } - val += apply ? mod->value : -(mod->value); - WorldPacket data(Opcode, (1 + 1 + 4)); - data << uint8(eff + 32 * i); - data << uint8(mod->op); - data << int32(val); - SendDirectMessage(&data); + if ((*itr)->type == mod->type && (*itr)->mask & _mask) + val += (*itr)->value; } + val += apply ? mod->value : -(mod->value); + WorldPacket data(Opcode, (1 + 1 + 4)); + data << uint8(eff); + data << uint8(mod->op); + data << int32(val); + SendDirectMessage(&data); } - - modMask[i] = 0; } if (apply) { - m_spellMods[mod->op].insert(mod); + m_spellMods[mod->op].push_back(mod); + if (getClass() == CLASS_MAGE) + m_spellMods[mod->op].sort(MageSpellModPred()); + else + m_spellMods[mod->op].sort(SpellModPred()); } else { - m_spellMods[mod->op].erase(mod); + m_spellMods[mod->op].remove(mod); + // mods bound to aura will be removed in AuraEffect::~AuraEffect + if (!mod->ownerAura) + delete mod; } } // Restore spellmods in case of failed cast -void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId /*= 0*/, Aura* aura /*= nullptr*/) +void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId, Aura* aura) { if (!spell || spell->m_appliedMods.empty()) return; @@ -9665,16 +9661,16 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId /*= 0*/, Aura* au for (uint8 i = 0; i < MAX_SPELLMOD; ++i) { - for (auto itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr) + for (SpellModList::iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end(); ++itr) { SpellModifier* mod = *itr; - // Spellmods without charged aura set cannot be charged - if (!mod->ownerAura->IsUsingCharges()) + // Spellmods without aura set cannot be charged + if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges()) continue; // Restore only specific owner aura mods - if (ownerAuraId && mod->spellId != ownerAuraId) + if (ownerAuraId && (ownerAuraId != mod->ownerAura->GetSpellInfo()->Id)) continue; if (aura && mod->ownerAura != aura) @@ -9695,14 +9691,27 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId /*= 0*/, Aura* au // only see the first of its modifier restored) aurasQueue.push_back(mod->ownerAura); - // add charges back to aura - mod->ownerAura->ModCharges(1); + // add mod charges back to mod + if (mod->charges == -1) + mod->charges = 1; + else + mod->charges++; + + // Do not set more spellmods than available + if (mod->ownerAura->GetCharges() < mod->charges) + mod->charges = mod->ownerAura->GetCharges(); + + // Skip this check for now - aura charges may change due to various reason + /// @todo track these changes correctly + //ASSERT (mod->ownerAura->GetCharges() <= mod->charges); } } - for (Aura* aura : aurasQueue) + for (std::list<Aura*>::iterator itr = aurasQueue.begin(); itr != aurasQueue.end(); ++itr) { - spell->m_appliedMods.erase(aura); + Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(*itr); + if (iterMod != spell->m_appliedMods.end()) + spell->m_appliedMods.erase(iterMod); } // Xinef: clear the list just do be sure @@ -9710,32 +9719,77 @@ void Player::RestoreSpellMods(Spell* spell, uint32 ownerAuraId /*= 0*/, Aura* au spell->m_appliedMods.clear(); } -void Player::RestoreAllSpellMods(uint32 ownerAuraId /*= 0*/, Aura* aura /*= nullptr*/) +void Player::RestoreAllSpellMods(uint32 ownerAuraId, Aura* aura) { for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i) - if (Spell* spell = m_currentSpells[i]) - RestoreSpellMods(spell, ownerAuraId, aura); + if (m_currentSpells[i]) + RestoreSpellMods(m_currentSpells[i], ownerAuraId, aura); } -void Player::ApplyModToSpell(SpellModifier* mod, Spell* spell) +void Player::RemoveSpellMods(Spell* spell) { if (!spell) return; - // don't do anything with no charges - if (mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges()) + if (spell->m_appliedMods.empty()) return; - // register inside spell, proc system uses this to drop charges - spell->m_appliedMods.insert(mod->ownerAura); + SpellInfo const* const spellInfo = spell->m_spellInfo; + + for (uint8 i = 0; i < MAX_SPELLMOD; ++i) + { + for (SpellModList::const_iterator itr = m_spellMods[i].begin(); itr != m_spellMods[i].end();) + { + SpellModifier* mod = *itr; + ++itr; + + // spellmods without aura set cannot be charged + if (!mod->ownerAura || !mod->ownerAura->IsUsingCharges()) + continue; + + // check if mod affected this spell + Spell::UsedSpellMods::iterator iterMod = spell->m_appliedMods.find(mod->ownerAura); + if (iterMod == spell->m_appliedMods.end()) + continue; + + // remove from list + // leave this here, if spell have two mods it will remove 2 charges - wrong + spell->m_appliedMods.erase(iterMod); + + // MAGE T8P4 BONUS + if( spellInfo->SpellFamilyName == SPELLFAMILY_MAGE ) + { + SpellInfo const* sp = mod->ownerAura->GetSpellInfo(); + // Missile Barrage, Hot Streak, Brain Freeze (trigger spell - Fireball!) + if( sp->SpellIconID == 3261 || sp->SpellIconID == 2999 || sp->SpellIconID == 2938 ) + if( AuraEffect* aurEff = GetAuraEffectDummy(64869) ) + if( roll_chance_i(aurEff->GetAmount()) ) + { + mod->charges = 1; + continue; + } + } + + if (mod->ownerAura->DropCharge(AURA_REMOVE_BY_EXPIRE)) + itr = m_spellMods[i].begin(); + } + } } -bool Player::HasSpellModApplied(SpellModifier* mod, Spell* spell) +void Player::DropModCharge(SpellModifier* mod, Spell* spell) { - if (!spell) - return false; + // don't handle spells with proc_event entry defined + // this is a temporary workaround, because all spellmods should be handled like that + if (sSpellMgr->GetSpellProcEvent(mod->spellId)) + return; + + if (spell && mod->ownerAura && mod->charges > 0) + { + if (--mod->charges == 0) + mod->charges = -1; - return spell->m_appliedMods.count(mod->ownerAura) != 0; + spell->m_appliedMods.insert(mod->ownerAura); + } } void Player::SetSpellModTakingSpell(Spell* spell, bool apply) @@ -10633,7 +10687,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite if (rec > 0) { int32 oldRec = rec; - ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, rec, spell); + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell); if (oldRec != rec) { useSpellCooldown = true; @@ -10642,7 +10696,7 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite if (catrec > 0 && !spellInfo->HasAttribute(SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS)) { - ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, catrec, spell); + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); } if (int32 cooldownMod = GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN)) @@ -11418,7 +11472,6 @@ void Player::ApplyEquipCooldown(Item* pItem) if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_NO_EQUIP_COOLDOWN)) return; - std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) { _Spell const& spellData = pItem->GetTemplate()->Spells[i]; @@ -11427,15 +11480,11 @@ void Player::ApplyEquipCooldown(Item* pItem) if (!spellData.SpellId) continue; - // apply proc cooldown to equip auras if we have any + // xinef: apply hidden cooldown for procs if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_EQUIP) { - SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(spellData.SpellId); - if (!procEntry) - continue; - - if (Aura* itemAura = GetAura(spellData.SpellId, GetGUID(), pItem->GetGUID())) - itemAura->AddProcCooldown(now + procEntry->Cooldown); + // xinef: uint32(-1) special marker for proc cooldowns + AddSpellCooldown(spellData.SpellId, uint32(-1), 30 * IN_MILLISECONDS); continue; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index b0b03bbc4d..73a6524597 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -89,10 +89,10 @@ typedef void(*bgZoneRef)(Battleground*, WorldPacket&); #define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p) // Note: SPELLMOD_* values is aura types in fact -enum SpellModType : uint8 +enum SpellModType { - SPELLMOD_FLAT = SPELL_AURA_ADD_FLAT_MODIFIER, - SPELLMOD_PCT = SPELL_AURA_ADD_PCT_MODIFIER + SPELLMOD_FLAT = 107, // SPELL_AURA_ADD_FLAT_MODIFIER + SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER }; // 2^n values, Player::m_isunderwater is a bitmask. These are Trinity internal values, they are never send to any client @@ -180,9 +180,10 @@ enum TalentTree // talent tabs // Spell modifier (used for modify other spells) struct SpellModifier { - SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), mask(), ownerAura(_ownerAura) {} - SpellModOp op; - SpellModType type; + SpellModifier(Aura* _ownerAura = nullptr) : op(SPELLMOD_DAMAGE), type(SPELLMOD_FLAT), charges(0), mask(), ownerAura(_ownerAura) {} + SpellModOp op : 8; + SpellModType type : 8; + int16 charges : 16; int32 value{0}; flag96 mask; uint32 spellId{0}; @@ -191,7 +192,7 @@ struct SpellModifier typedef std::unordered_map<uint32, PlayerTalent*> PlayerTalentMap; typedef std::unordered_map<uint32, PlayerSpell*> PlayerSpellMap; -typedef std::unordered_set<SpellModifier*> SpellModContainer; +typedef std::list<SpellModifier*> SpellModList; typedef GuidList WhisperListContainer; @@ -1729,14 +1730,13 @@ public: SpellCooldowns& GetSpellCooldownMap() { return m_spellCooldowns; } void AddSpellMod(SpellModifier* mod, bool apply); - static bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = nullptr); + bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = nullptr); bool HasSpellMod(SpellModifier* mod, Spell* spell); - template <SpellModOp op, class T> - void ApplySpellMod(uint32 spellId, T& basevalue, Spell* spell = nullptr) const; + template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell = nullptr, bool temporaryPet = false); + void RemoveSpellMods(Spell* spell); void RestoreSpellMods(Spell* spell, uint32 ownerAuraId = 0, Aura* aura = nullptr); void RestoreAllSpellMods(uint32 ownerAuraId = 0, Aura* aura = nullptr); - static void ApplyModToSpell(SpellModifier* mod, Spell* spell); - static bool HasSpellModApplied(SpellModifier* mod, Spell* spell); + void DropModCharge(SpellModifier* mod, Spell* spell); void SetSpellModTakingSpell(Spell* spell, bool apply); [[nodiscard]] bool HasSpellCooldown(uint32 spell_id) const override; @@ -2166,9 +2166,9 @@ public: void ApplyItemEquipSpell(Item* item, bool apply, bool form_change = false); void ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool form_change = false); void UpdateEquipSpellsAtFormChange(); - void CastItemCombatSpell(DamageInfo const& damageInfo); - void CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemTemplate const* proto); + void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx); void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex); + void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto); void SendEquipmentSetList(); void SetEquipmentSet(uint32 index, EquipmentSet eqset); @@ -2551,7 +2551,7 @@ public: // mt maps [[nodiscard]] const PlayerTalentMap& GetTalentMap() const { return m_talents; } [[nodiscard]] uint32 GetNextSave() const { return m_nextSave; } - [[nodiscard]] SpellModContainer const& GetSpellModContainer(uint32 type) const { return m_spellMods[type]; } + [[nodiscard]] SpellModList const& GetSpellModList(uint32 type) const { return m_spellMods[type]; } void SetServerSideVisibility(ServerSideVisibilityType type, AccountTypes sec); void SetServerSideVisibilityDetect(ServerSideVisibilityType type, AccountTypes sec); @@ -2756,7 +2756,7 @@ public: uint32 m_baseHealthRegen; int32 m_spellPenetrationItemMod; - SpellModContainer m_spellMods[MAX_SPELLMOD]; + SpellModList m_spellMods[MAX_SPELLMOD]; //uint32 m_pad; // Spell* m_spellModTakingSpell; // Spell for which charges are dropped in spell::finish @@ -2940,132 +2940,130 @@ void AddItemsSetItem(Player* player, Item* item); void RemoveItemsSetItem(Player* player, ItemTemplate const* proto); // "the bodies of template functions must be made available in a header file" -template <SpellModOp op, class T> -void Player::ApplySpellMod(uint32 spellId, T& basevalue, Spell* spell) const +template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell, bool temporaryPet) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) - return; + { + return 0; + } - float totalmul = 1.f; + float totalmul = 1.0f; int32 totalflat = 0; - // Drop charges for triggering spells instead of triggered ones - if (m_spellModTakingSpell) - spell = m_spellModTakingSpell; - - switch (op) + auto calculateSpellMod = [&](SpellModifier* mod) { - // special case, if a mod makes spell instant, only consume that mod - case SPELLMOD_CASTING_TIME: + // xinef: temporary pets cannot use charged mods of owner, needed for mirror image QQ they should use their own auras + if (temporaryPet && mod->charges != 0) { - SpellModifier* modInstantSpell = nullptr; - for (SpellModifier* mod : m_spellMods[SPELLMOD_CASTING_TIME]) + return; + } + + if (mod->type == SPELLMOD_FLAT) + { + // xinef: do not allow to consume more than one 100% crit increasing spell + if (mod->op == SPELLMOD_CRITICAL_CHANCE && totalflat >= 100) { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - { - continue; - } - - if (mod->type == SPELLMOD_PCT && basevalue < T(10000) && mod->value <= -100) - { - modInstantSpell = mod; - break; - } + return; } - if (modInstantSpell) + int32 flatValue = mod->value; + + // SPELL_MOD_THREAT - divide by 100 (in packets we send threat * 100) + if (mod->op == SPELLMOD_THREAT) { - Player::ApplyModToSpell(modInstantSpell, spell); - basevalue = T(0); - return; + flatValue /= 100; } - break; - } - // special case if two mods apply 100% critical chance, only consume one - case SPELLMOD_CRITICAL_CHANCE: + totalflat += flatValue; + } + else if (mod->type == SPELLMOD_PCT) { - SpellModifier* modCritical = nullptr; - for (auto mod : m_spellMods[SPELLMOD_CRITICAL_CHANCE]) + // skip percent mods for null basevalue (most important for spell mods with charges) + if (basevalue == T(0) || totalmul == 0.0f) { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - { - continue; - } - - if (mod->type == SPELLMOD_FLAT && mod->value >= 100) - { - modCritical = mod; - break; - } + return; } - if (modCritical) + // special case (skip > 10sec spell casts for instant cast setting) + if (mod->op == SPELLMOD_CASTING_TIME && basevalue >= T(10000) && mod->value <= -100) { - Player::ApplyModToSpell(modCritical, spell); - basevalue = T(100); return; } - break; + // xinef: special exception for surge of light, dont affect crit chance if previous mods were not applied + else if (mod->op == SPELLMOD_CRITICAL_CHANCE && spell && !HasSpellMod(mod, spell)) + { + return; + } + // xinef: special case for backdraft gcd reduce with backlast time reduction, dont affect gcd if cast time was not applied + else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell)) + { + return; + } + + // xinef: those two mods should be multiplicative (Glyph of Renew) + if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT) + { + totalmul *= CalculatePct(1.0f, 100.0f + mod->value); + } + else + { + totalmul += CalculatePct(1.0f, mod->value); + } } - default: - break; + DropModCharge(mod, spell); + }; + + // Drop charges for triggering spells instead of triggered ones + if (m_spellModTakingSpell) + { + spell = m_spellModTakingSpell; } + SpellModifier* chargedMod = nullptr; for (auto mod : m_spellMods[op]) { + // Charges can be set only for mods with auras + if (!mod->ownerAura) + { + ASSERT(!mod->charges); + } + if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + { continue; + } - switch (mod->type) + if (mod->ownerAura->IsUsingCharges()) { - case SPELLMOD_FLAT: - totalflat += mod->value; - break; - case SPELLMOD_PCT: + if (!chargedMod || (chargedMod->ownerAura->GetSpellInfo()->SpellPriority < mod->ownerAura->GetSpellInfo()->SpellPriority)) { - // skip percent mods for null basevalue (most important for spell mods with charges) - if (basevalue == T(0)) - { - continue; - } - - // special case (skip > 10s spell casts for instant cast setting) - if (op == SPELLMOD_CASTING_TIME) - { - if (mod->value <= -100 && basevalue >= T(10000)) - { - continue; - } - } - - totalmul += CalculatePct(1.f, mod->value); - break; + chargedMod = mod; } - } - /*// xinef: special exception for surge of light, dont affect crit chance if previous mods were not applied - else if (mod->op == SPELLMOD_CRITICAL_CHANCE && spell && !HasSpellMod(mod, spell)) - continue; - // xinef: special case for backdraft gcd reduce with backlast time reduction, dont affect gcd if cast time was not applied - else if (mod->op == SPELLMOD_GLOBAL_COOLDOWN && spell && !HasSpellMod(mod, spell)) continue; - // xinef: those two mods should be multiplicative (Glyph of Renew) - if (mod->op == SPELLMOD_DAMAGE || mod->op == SPELLMOD_DOT) - totalmul *= CalculatePct(1.0f, 100.0f + mod->value); - else - totalmul += CalculatePct(1.0f, mod->value);*/ + } + + calculateSpellMod(mod); + } - Player::ApplyModToSpell(mod, spell); + if (chargedMod) + { + calculateSpellMod(chargedMod); } + float diff = 0.0f; if (op == SPELLMOD_CASTING_TIME || op == SPELLMOD_DURATION) + { diff = ((float)basevalue + totalflat) * (totalmul - 1.0f) + (float)totalflat; + } else + { diff = (float)basevalue * (totalmul - 1.0f) + (float)totalflat; + } + basevalue = T((float)basevalue + diff); + return T(diff); } - #endif diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2ab51a89ee..d190cbdcd1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -98,92 +98,44 @@ float playerBaseMoveSpeed[MAX_MOVE_TYPE] = 3.14f // MOVE_PITCH_RATE }; -DamageInfo::DamageInfo(Unit* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, DamageEffectType damageType, WeaponAttackType attackType, uint32 cleanDamage) - : m_attacker(attacker), m_victim(victim), m_damage(damage), m_spellInfo(spellInfo), m_schoolMask(schoolMask), - m_damageType(damageType), m_attackType(attackType), m_absorb(0), m_resist(0), m_block(0), m_hitMask(0), m_cleanDamage(cleanDamage) -{ +// Used for prepare can/can`t triggr aura +static bool InitTriggerAuraData(); +// Define can trigger auras +static bool isTriggerAura[TOTAL_AURAS]; +// Define can't trigger auras (need for disable second trigger) +static bool isNonTriggerAura[TOTAL_AURAS]; +// Triggered always, even from triggered spells +static bool isAlwaysTriggeredAura[TOTAL_AURAS]; +// Prepare lists +static bool procPrepared = InitTriggerAuraData(); + +DamageInfo::DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage) + : m_attacker(_attacker), m_victim(_victim), m_damage(_damage), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask), + m_damageType(_damageType), m_attackType(BASE_ATTACK), m_cleanDamage(cleanDamage) +{ + m_absorb = 0; + m_resist = 0; + m_block = 0; } DamageInfo::DamageInfo(CalcDamageInfo& dmgInfo) : m_attacker(dmgInfo.attacker), m_victim(dmgInfo.target), m_damage(dmgInfo.damage), m_spellInfo(nullptr), m_schoolMask(SpellSchoolMask(dmgInfo.damageSchoolMask)), m_damageType(DIRECT_DAMAGE), m_attackType(dmgInfo.attackType), m_absorb(dmgInfo.absorb), m_resist(dmgInfo.resist), m_block(dmgInfo.blocked_amount), - m_hitMask(0), m_cleanDamage(dmgInfo.cleanDamage) + m_cleanDamage(dmgInfo.cleanDamage) { - switch (dmgInfo.TargetState) - { - case VICTIMSTATE_IS_IMMUNE: - m_hitMask |= PROC_HIT_IMMUNE; - break; - case VICTIMSTATE_BLOCKS: - m_hitMask |= PROC_HIT_FULL_BLOCK; - break; - } - - if (dmgInfo.HitInfo & (HITINFO_PARTIAL_ABSORB | HITINFO_FULL_ABSORB)) - { - m_hitMask |= PROC_HIT_ABSORB; - } - - if (dmgInfo.HitInfo & HITINFO_FULL_RESIST) - { - m_hitMask |= PROC_HIT_FULL_RESIST; - } - - if (m_block) - { - m_hitMask |= PROC_HIT_BLOCK; - } - - bool const damageNullified = (dmgInfo.HitInfo & (HITINFO_FULL_ABSORB | HITINFO_FULL_RESIST)) != 0 || - (m_hitMask & (PROC_HIT_IMMUNE | PROC_HIT_FULL_BLOCK)) != 0; - - switch (dmgInfo.hitOutCome) - { - case MELEE_HIT_MISS: - m_hitMask |= PROC_HIT_MISS; - break; - case MELEE_HIT_DODGE: - m_hitMask |= PROC_HIT_DODGE; - break; - case MELEE_HIT_PARRY: - m_hitMask |= PROC_HIT_PARRY; - break; - case MELEE_HIT_EVADE: - m_hitMask |= PROC_HIT_EVADE; - break; - case MELEE_HIT_BLOCK: - case MELEE_HIT_CRUSHING: - case MELEE_HIT_GLANCING: - case MELEE_HIT_NORMAL: - if (!damageNullified) - m_hitMask |= PROC_HIT_NORMAL; - break; - case MELEE_HIT_CRIT: - if (!damageNullified) - m_hitMask |= PROC_HIT_CRITICAL; - break; - } } -DamageInfo::DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, uint32 /* hitMask */) +DamageInfo::DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType) : m_attacker(spellNonMeleeDamage.attacker), m_victim(spellNonMeleeDamage.target), m_damage(spellNonMeleeDamage.damage), m_spellInfo(spellNonMeleeDamage.spellInfo), m_schoolMask(SpellSchoolMask(spellNonMeleeDamage.schoolMask)), m_damageType(damageType), - m_attackType(attackType), m_absorb(spellNonMeleeDamage.absorb), m_resist(spellNonMeleeDamage.resist), m_block(spellNonMeleeDamage.blocked), - m_hitMask(0), m_cleanDamage(spellNonMeleeDamage.cleanDamage) + m_absorb(spellNonMeleeDamage.absorb), m_resist(spellNonMeleeDamage.resist), m_block(spellNonMeleeDamage.blocked), + m_cleanDamage(spellNonMeleeDamage.cleanDamage) { - if (spellNonMeleeDamage.blocked) - { - m_hitMask |= PROC_HIT_BLOCK; - } - if (spellNonMeleeDamage.absorb) - { - m_hitMask |= PROC_HIT_ABSORB; - } } void DamageInfo::ModifyDamage(int32 amount) { - amount = std::max(amount, -static_cast<int32>(GetDamage())); + amount = std::min(amount, int32(GetDamage())); m_damage += amount; } @@ -192,7 +144,6 @@ void DamageInfo::AbsorbDamage(uint32 amount) amount = std::min(amount, GetDamage()); m_absorb += amount; m_damage -= amount; - m_hitMask |= PROC_HIT_ABSORB; } void DamageInfo::ResistDamage(uint32 amount) @@ -200,11 +151,6 @@ void DamageInfo::ResistDamage(uint32 amount) amount = std::min(amount, GetDamage()); m_resist += amount; m_damage -= amount; - if (!m_damage) - { - m_hitMask |= PROC_HIT_FULL_RESIST; - m_hitMask &= ~(PROC_HIT_NORMAL | PROC_HIT_CRITICAL); - } } void DamageInfo::BlockDamage(uint32 amount) @@ -212,37 +158,6 @@ void DamageInfo::BlockDamage(uint32 amount) amount = std::min(amount, GetDamage()); m_block += amount; m_damage -= amount; - m_hitMask |= PROC_HIT_BLOCK; - if (!m_damage) - { - m_hitMask |= PROC_HIT_FULL_BLOCK; - m_hitMask &= ~(PROC_HIT_NORMAL | PROC_HIT_CRITICAL); - } -} - -uint32 DamageInfo::GetHitMask() const -{ - return m_hitMask; -} - -HealInfo::HealInfo(Unit* healer, Unit* target, uint32 heal, SpellInfo const* spellInfo, SpellSchoolMask schoolMask) - : m_healer(healer), m_target(target), m_heal(heal), m_effectiveHeal(0), m_absorb(0), m_spellInfo(spellInfo), m_schoolMask(schoolMask), m_hitMask(0) -{ -} - -void HealInfo::AbsorbHeal(uint32 amount) -{ - amount = std::min(amount, GetHeal()); - m_absorb += amount; - m_heal -= amount; - amount = std::min(amount, GetEffectiveHeal()); - m_effectiveHeal -= amount; - m_hitMask |= PROC_HIT_ABSORB; -} - -uint32 HealInfo::GetHitMask() const -{ - return m_hitMask; } uint32 DamageInfo::GetUnmitigatedDamage() const @@ -316,7 +231,6 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), m_modAttackSpeedPct[OFF_ATTACK] = 1.0f; m_modAttackSpeedPct[RANGED_ATTACK] = 1.0f; - m_extraAttacks = 0; m_canDualWield = false; m_rootTimes = 0; @@ -403,6 +317,8 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), _oldFactionId = 0; _isWalkingBeforeCharm = false; + + _lastExtraAttackSpell = 0; } //////////////////////////////////////////////////////////// @@ -528,6 +444,23 @@ void Unit::Update(uint32 p_time) } } + _lastDamagedTargetGuid = ObjectGuid::Empty; + if (_lastExtraAttackSpell) + { + while (!extraAttacksTargets.empty()) + { + auto itr = extraAttacksTargets.begin(); + ObjectGuid targetGuid = itr->first; + uint32 count = itr->second; + extraAttacksTargets.erase(itr); + if (Unit* victim = ObjectAccessor::GetUnit(*this, targetGuid)) + { + HandleProcExtraAttackFor(victim, count); + } + } + _lastExtraAttackSpell = 0; + } + // not implemented before 3.0.2 // xinef: if attack time > 0, reduce by diff // if on next update, attack time < 0 assume player didnt attack - set to 0 @@ -960,7 +893,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage } else { - DamageInfo sharedDamageInfo(attacker, shareDamageTarget, shareDamage, spellProto, damageSchoolMask, damagetype, BASE_ATTACK); + DamageInfo sharedDamageInfo(attacker, shareDamageTarget, shareDamage, spellProto, damageSchoolMask, damagetype); Unit::CalcAbsorbResist(sharedDamageInfo, true); shareAbsorb = sharedDamageInfo.GetAbsorb(); shareResist = sharedDamageInfo.GetResist(); @@ -1089,7 +1022,7 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage //if (attacker && victim->GetTypeId() == TYPEID_PLAYER && victim != attacker) //victim->ToPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, health); // pussywizard: optimization - Unit::Kill(attacker, victim, durabilityLoss, cleanDamage ? cleanDamage->attackType : BASE_ATTACK, spellProto); + Unit::Kill(attacker, victim, durabilityLoss, cleanDamage ? cleanDamage->attackType : BASE_ATTACK, spellProto, damageSpell); } else { @@ -1386,7 +1319,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama uint32 crit_bonus = damage; // Apply crit_damage bonus for melee spells if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRIT_DAMAGE_BONUS>(spellInfo->Id, crit_bonus); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); damage += crit_bonus; // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE @@ -1413,11 +1346,8 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama // double blocked amount if block is critical if (victim->isBlockCritical()) damageInfo->blocked *= 2; - if (damage <= int32(damageInfo->blocked)) - { + if (damage < int32(damageInfo->blocked)) damageInfo->blocked = uint32(damage); - damageInfo->fullBlock = true; - } damage -= damageInfo->blocked; cleanDamage += damageInfo->blocked; @@ -1471,18 +1401,14 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama damageInfo->damage = std::max(0, damage); // Calculate absorb resist - DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, PROC_HIT_NONE); - Unit::CalcAbsorbResist(dmgInfo); - damageInfo->absorb = dmgInfo.GetAbsorb(); - damageInfo->resist = dmgInfo.GetResist(); - - if (damageInfo->absorb) - damageInfo->HitInfo |= (damageInfo->damage - damageInfo->absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB); - - if (damageInfo->resist) - damageInfo->HitInfo |= (damageInfo->damage - damageInfo->resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST); - - damageInfo->damage = dmgInfo.GetDamage(); + if (damageInfo->damage > 0) + { + DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE); + Unit::CalcAbsorbResist(dmgInfo); + damageInfo->absorb = dmgInfo.GetAbsorb(); + damageInfo->resist = dmgInfo.GetResist(); + damageInfo->damage = dmgInfo.GetDamage(); + } } void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell /*= nullptr*/) @@ -1527,6 +1453,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->HitInfo = 0; damageInfo->procAttacker = PROC_FLAG_NONE; damageInfo->procVictim = PROC_FLAG_NONE; + damageInfo->procEx = PROC_EX_NONE; damageInfo->hitOutCome = MELEE_HIT_EVADE; if (!victim) @@ -1557,6 +1484,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->HitInfo |= HITINFO_NORMALSWING; damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE; + damageInfo->procEx |= PROC_EX_IMMUNE; return; } @@ -1589,23 +1517,27 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam case MELEE_HIT_EVADE: damageInfo->HitInfo |= HITINFO_MISS | HITINFO_SWINGNOHITSOUND; damageInfo->TargetState = VICTIMSTATE_EVADES; + damageInfo->procEx |= PROC_EX_EVADE; damageInfo->damage = 0; damageInfo->cleanDamage = 0; return; case MELEE_HIT_MISS: damageInfo->HitInfo |= HITINFO_MISS; damageInfo->TargetState = VICTIMSTATE_INTACT; + damageInfo->procEx |= PROC_EX_MISS; damageInfo->damage = 0; damageInfo->cleanDamage = 0; break; case MELEE_HIT_NORMAL: damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->procEx |= PROC_EX_NORMAL_HIT; break; case MELEE_HIT_CRIT: { damageInfo->HitInfo |= HITINFO_CRITICALHIT; damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->procEx |= PROC_EX_CRITICAL_HIT; // Crit bonus calc damageInfo->damage += damageInfo->damage; float mod = 0.0f; @@ -1630,17 +1562,20 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam } case MELEE_HIT_PARRY: damageInfo->TargetState = VICTIMSTATE_PARRY; + damageInfo->procEx |= PROC_EX_PARRY; damageInfo->cleanDamage += damageInfo->damage; damageInfo->damage = 0; break; case MELEE_HIT_DODGE: damageInfo->TargetState = VICTIMSTATE_DODGE; + damageInfo->procEx |= PROC_EX_DODGE; damageInfo->cleanDamage += damageInfo->damage; damageInfo->damage = 0; break; case MELEE_HIT_BLOCK: damageInfo->TargetState = VICTIMSTATE_HIT; damageInfo->HitInfo |= HITINFO_BLOCK; + damageInfo->procEx |= PROC_EX_BLOCK; damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue(); // double blocked amount if block is critical if (damageInfo->target->isBlockCritical()) @@ -1649,8 +1584,10 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam { damageInfo->TargetState = VICTIMSTATE_BLOCKS; damageInfo->blocked_amount = damageInfo->damage; + damageInfo->procEx |= PROC_EX_FULL_BLOCK; } - + else + damageInfo->procEx |= PROC_EX_NORMAL_HIT; damageInfo->damage -= damageInfo->blocked_amount; damageInfo->cleanDamage += damageInfo->blocked_amount; break; @@ -1658,6 +1595,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam { damageInfo->HitInfo |= HITINFO_GLANCING; damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->procEx |= PROC_EX_NORMAL_HIT; int32 leveldif = int32(victim->getLevel()) - int32(getLevel()); if (leveldif > 3) leveldif = 3; @@ -1669,6 +1607,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam case MELEE_HIT_CRUSHING: damageInfo->HitInfo |= HITINFO_CRUSHING; damageInfo->TargetState = VICTIMSTATE_HIT; + damageInfo->procEx |= PROC_EX_NORMAL_HIT; // 150% normal damage damageInfo->damage += (damageInfo->damage / 2); break; @@ -1710,6 +1649,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam if (damageInfo->absorb) { damageInfo->HitInfo |= (damageInfo->damage - damageInfo->absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB); + damageInfo->procEx |= PROC_EX_ABSORB; } if (damageInfo->resist) @@ -1795,10 +1735,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) } if (GetTypeId() == TYPEID_PLAYER) - { - DamageInfo dmgInfo(*damageInfo); - ToPlayer()->CastItemCombatSpell(dmgInfo); - } + ToPlayer()->CastItemCombatSpell(victim, damageInfo->attackType, damageInfo->procVictim, damageInfo->procEx); // Do effect if any damage done to target if (damageInfo->damage) @@ -1833,7 +1770,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) uint32 absorb = 0; - DamageInfo dmgInfo(victim, this, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); + DamageInfo dmgInfo(victim, this, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE); Unit::CalcAbsorbResist(dmgInfo); absorb = dmgInfo.GetAbsorb(); damage = dmgInfo.GetDamage(); @@ -1899,7 +1836,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit const* attacker, Unit const* victim, co if (spellInfo) if (Player* modOwner = attacker->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_IGNORE_ARMOR>(spellInfo->Id, armor); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor); AuraEffectList const& ResIgnoreAurasAb = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST); for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j) @@ -2077,24 +2014,30 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) } // Ignore Absorption Auras - float auraAbsorbMod = victim->GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, dmgInfo.GetSchoolMask());; - AuraEffectList const& abilityAbsorbAuras = victim->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL); - for (AuraEffect const* aurEff : abilityAbsorbAuras) + float auraAbsorbMod = 0; + if (attacker) { - if (!(aurEff->GetMiscValue() & schoolMask)) - continue; - - if (!aurEff->IsAffectedOnSpell(spellInfo)) - continue; + AuraEffectList const& AbsIgnoreAurasA = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL); + for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr) + { + if (!((*itr)->GetMiscValue() & schoolMask)) + continue; - if (aurEff->GetAmount() > auraAbsorbMod) - auraAbsorbMod = float(aurEff->GetAmount()); - } + if ((*itr)->GetAmount() > auraAbsorbMod) + auraAbsorbMod = float((*itr)->GetAmount()); + } - RoundToInterval(auraAbsorbMod, 0.f, 100.f); + AuraEffectList const& AbsIgnoreAurasB = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL); + for (AuraEffectList::const_iterator itr = AbsIgnoreAurasB.begin(); itr != AbsIgnoreAurasB.end(); ++itr) + { + if (!((*itr)->GetMiscValue() & schoolMask)) + continue; - int32 absorbIgnoringDamage = CalculatePct(dmgInfo.GetDamage(), auraAbsorbMod); - dmgInfo.ModifyDamage(-absorbIgnoringDamage); + if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo)) + auraAbsorbMod = float((*itr)->GetAmount()); + } + RoundToInterval(auraAbsorbMod, 0.0f, 100.0f); + } // We're going to call functions which can modify content of the list during iteration over it's elements // Let's copy the list so we can prevent iterator invalidation @@ -2242,9 +2185,11 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) uint32 splitted_absorb = 0; uint32 splitted_resist = 0; - DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, schoolMask, dmgInfo.GetDamageType(), BASE_ATTACK); + uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT; + DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, schoolMask, dmgInfo.GetDamageType()); if (caster->IsImmunedToDamageOrSchool(schoolMask)) { + procEx |= PROC_EX_IMMUNE; splittedDmgInfo.AbsorbDamage(splitted); } else @@ -2257,6 +2202,10 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) splitted_resist = splittedDmgInfo.GetResist(); splitted = splittedDmgInfo.GetDamage(); + // create procs + createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim); + caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted, nullptr, -1, nullptr, &splittedDmgInfo); + if (attacker) attacker->SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo(), splitted, schoolMask, splitted_absorb, splitted_resist, false, 0, false); @@ -2307,9 +2256,11 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) uint32 splitted_absorb = 0; uint32 splitted_resist = 0; - DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, splitSchoolMask, dmgInfo.GetDamageType(), BASE_ATTACK); + uint32 procAttacker = 0, procVictim = 0, procEx = PROC_EX_NORMAL_HIT; + DamageInfo splittedDmgInfo(attacker, caster, splitted, spellInfo, splitSchoolMask, dmgInfo.GetDamageType()); if (caster->IsImmunedToDamageOrSchool(schoolMask)) { + procEx |= PROC_EX_IMMUNE; splittedDmgInfo.AbsorbDamage(splitted); } else @@ -2322,6 +2273,10 @@ void Unit::CalcAbsorbResist(DamageInfo& dmgInfo, bool Splited) splitted_resist = splittedDmgInfo.GetResist(); splitted = splittedDmgInfo.GetDamage(); + // create procs + createProcFlags(spellInfo, BASE_ATTACK, false, procAttacker, procVictim); + caster->ProcDamageAndSpellFor(true, attacker, procVictim, procEx, BASE_ATTACK, spellInfo, splitted); + if (attacker) attacker->SendSpellNonMeleeDamageLog(caster, splitSpellInfo, splitted, splitSchoolMask, splitted_absorb, splitted_resist, false, 0, false); @@ -2421,6 +2376,11 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_A if (attType != BASE_ATTACK && attType != OFF_ATTACK) return; // ignore ranged case + if (!extra && _lastExtraAttackSpell) + { + _lastExtraAttackSpell = 0; + } + bool meleeAttack = true; // melee attack spell casted at main hand attack only - no normal melee dmg dealt @@ -2460,11 +2420,16 @@ void Unit::AttackerStateUpdate(Unit* victim, WeaponAttackType attType /*= BASE_A Unit::DealDamageMods(victim, damageInfo.damage, &damageInfo.absorb); SendAttackStateUpdate(&damageInfo); - DamageInfo dmgInfo(damageInfo); - ProcSkillsAndAuras(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); + //TriggerAurasProcOnEvent(damageInfo); + + _lastDamagedTargetGuid = victim->GetGUID(); DealMeleeDamage(&damageInfo, true); + DamageInfo dmgInfo(damageInfo); + Unit::ProcDamageAndSpell(damageInfo.attacker, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, + damageInfo.attackType, nullptr, nullptr, -1, nullptr, &dmgInfo); + if (GetTypeId() == TYPEID_PLAYER) LOG_DEBUG("entities.unit", "AttackerStateUpdate: (Player) {} attacked {} for {} dmg, absorbed {}, blocked {}, resisted {}.", GetGUID().ToString(), victim->GetGUID().ToString(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); @@ -2571,15 +2536,31 @@ bool Unit::GetMeleeAttackPoint(Unit* attacker, Position& pos) return true; } -void Unit::HandleProcExtraAttackFor(Unit* victim) +void Unit::HandleProcExtraAttackFor(Unit* victim, uint32 count) { - while (m_extraAttacks) + while (count) { + --count; AttackerStateUpdate(victim, BASE_ATTACK, true); - --m_extraAttacks; } } +void Unit::AddExtraAttacks(uint32 count) +{ + ObjectGuid targetGUID = _lastDamagedTargetGuid; + if (!targetGUID) + { + if (ObjectGuid selection = GetTarget()) + { + targetGUID = selection; // Spell was cast directly (not triggered by aura) + } + else + return; + } + + extraAttacksTargets[targetGUID] += count; +} + MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const { // This is only wrapper @@ -3149,7 +3130,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo // Spellmod from SPELLMOD_RESIST_MISS_CHANCE if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RESIST_MISS_CHANCE>(spellInfo->Id, modHitChance); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance); // Increase from attacker SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT auras modHitChance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT, schoolMask); @@ -3279,6 +3260,8 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spell, bool Ca reflectchance += (*i)->GetAmount(); if (reflectchance > 0 && roll_chance_i(reflectchance)) { + // Start triggers for remove charges if need (trigger only for victim, and mark as active spell) + //ProcDamageAndSpell(victim, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, spell); return SPELL_MISS_REFLECT; } } @@ -5990,20 +5973,15 @@ void Unit::SendSpellNonMeleeDamageLog(Unit* target, SpellInfo const* spellInfo, SendSpellNonMeleeDamageLog(&log); } -void Unit::ProcSkillsAndAuras(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) +void Unit::ProcDamageAndSpell(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpellInfo, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo, uint32 procPhase) { - WeaponAttackType attType = damageInfo ? damageInfo->GetAttackType() : BASE_ATTACK; - if (typeMaskActor) - { - ProcSkillsAndReactives(false, actionTarget, typeMaskActor, hitMask, attType); - } - - if (typeMaskActionTarget && actionTarget) - { - actionTarget->ProcSkillsAndReactives(true, this, typeMaskActionTarget, hitMask, attType); - } - - TriggerAurasProcOnEvent(actionTarget, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); + // Not much to do if no flags are set. + if (procAttacker && actor) + actor->ProcDamageAndSpellFor(false, victim, procAttacker, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase); + // Now go on with a victim's events'n'auras + // Not much to do if no flags are set or there is no victim + if (victim && victim->IsAlive() && procVictim) + victim->ProcDamageAndSpellFor(true, actor, procVictim, procExtra, attType, procSpellInfo, amount, procAura, procAuraEffectIndex, procSpell, damageInfo, healInfo, procPhase); } void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo) @@ -6184,6 +6162,3458 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType SendAttackStateUpdate(&dmgInfo); } +//victim may be nullptr +bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc /*= nullptr*/) +{ + SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); + uint32 effIndex = triggeredByAura->GetEffIndex(); + int32 triggerAmount = triggeredByAura->GetAmount(); + + Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER + ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; + + uint32 triggered_spell_id = 0; + uint32 cooldown_spell_id = 0; // for random trigger, will be one of the triggered spell to avoid repeatable triggers + // otherwise, it's the triggered_spell_id by default + Unit* target = victim; + int32 basepoints0 = 0; + ObjectGuid originalCaster; + + switch (dummySpell->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + switch (dummySpell->Id) + { + // Overkill + case 58426: + { + triggered_spell_id = 58427; + break; + } + // Unstable Power + case 24658: + { + if (!procSpell || procSpell->Id == 24659) + return false; + // Need remove one 24659 aura + RemoveAuraFromStack(24659); + return true; + } + // Restless Strength + case 24661: + { + // Need remove one 24662 aura + RemoveAuraFromStack(24662); + return true; + } + // Mark of Malice + case 33493: + { + if (triggeredByAura->GetBase()->GetCharges() > 1) + return true; + + target = this; + triggered_spell_id = 33494; + break; + } + // Twisted Reflection (boss spell) + case 21063: + triggered_spell_id = 21064; + break; + // Vampiric Aura (boss spell) + case 38196: + { + basepoints0 = 3 * damage; // 300% + if (basepoints0 < 0) + return false; + + triggered_spell_id = 31285; + target = this; + break; + } + // Aura of Madness (Darkmoon Card: Madness trinket) + //===================================================== + // 39511 Sociopath: +35 strength (Paladin, Rogue, Druid, Warrior) + // 40997 Delusional: +70 attack power (Rogue, Hunter, Paladin, Warrior, Druid) + // 40998 Kleptomania: +35 agility (Warrior, Rogue, Paladin, Hunter, Druid) + // 40999 Megalomania: +41 damage/healing (Druid, Shaman, Priest, Warlock, Mage, Paladin) + // 41002 Paranoia: +35 spell/melee/ranged crit strike rating (All classes) + // 41005 Manic: +35 haste (spell, melee and ranged) (All classes) + // 41009 Narcissism: +35 intellect (Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter) + // 41011 Martyr Complex: +35 stamina (All classes) + // 41406 Dementia: Every 5 seconds either gives you +5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) + // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) + case 39446: + { + if (GetTypeId() != TYPEID_PLAYER || !IsAlive()) + return false; + + // Select class defined buff + switch (getClass()) + { + case CLASS_PALADIN: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409 + case CLASS_DRUID: // 39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409 + triggered_spell_id = RAND(39511, 40997, 40998, 40999, 41002, 41005, 41009, 41011, 41409); + cooldown_spell_id = 39511; + break; + case CLASS_ROGUE: // 39511, 40997, 40998, 41002, 41005, 41011 + case CLASS_WARRIOR: // 39511, 40997, 40998, 41002, 41005, 41011 + case CLASS_DEATH_KNIGHT: + triggered_spell_id = RAND(39511, 40997, 40998, 41002, 41005, 41011); + cooldown_spell_id = 39511; + break; + case CLASS_PRIEST: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 + case CLASS_SHAMAN: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 + case CLASS_MAGE: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 + case CLASS_WARLOCK: // 40999, 41002, 41005, 41009, 41011, 41406, 41409 + triggered_spell_id = RAND(40999, 41002, 41005, 41009, 41011, 41406, 41409); + cooldown_spell_id = 40999; + break; + case CLASS_HUNTER: // 40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409 + triggered_spell_id = RAND(40997, 40999, 41002, 41005, 41009, 41011, 41406, 41409); + cooldown_spell_id = 40997; + break; + default: + return false; + } + + target = this; + if (roll_chance_i(10)) + ToPlayer()->Say("This is Madness!", LANG_UNIVERSAL); // TODO: It should be moved to database, shouldn't it? + break; + } + // Sunwell Exalted Caster Neck (??? neck) + // cast ??? Light's Wrath if Exalted by Aldor + // cast ??? Arcane Bolt if Exalted by Scryers + case 46569: + return false; // old unused version + // Sunwell Exalted Caster Neck (Shattered Sun Pendant of Acumen neck) + // cast 45479 Light's Wrath if Exalted by Aldor + // cast 45429 Arcane Bolt if Exalted by Scryers + case 45481: + { + Player* player = ToPlayer(); + if (!player) + return false; + + // Get Aldor reputation rank + if (player->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45479; + break; + } + // Get Scryers reputation rank + if (player->GetReputationRank(934) == REP_EXALTED) + { + // triggered at positive/self casts also, current attack target used then + if (target && IsFriendlyTo(target)) + { + target = GetVictim(); + if (!target) + { + target = player->GetSelectedUnit(); + if (!target) + return false; + } + if (IsFriendlyTo(target)) + return false; + } + + triggered_spell_id = 45429; + break; + } + return false; + } + // Sunwell Exalted Melee Neck (Shattered Sun Pendant of Might neck) + // cast 45480 Light's Strength if Exalted by Aldor + // cast 45428 Arcane Strike if Exalted by Scryers + case 45482: + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45480; + break; + } + // Get Scryers reputation rank + if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45428; + break; + } + return false; + } + // Sunwell Exalted Tank Neck (Shattered Sun Pendant of Resolve neck) + // cast 45431 Arcane Insight if Exalted by Aldor + // cast 45432 Light's Ward if Exalted by Scryers + case 45483: + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45432; + break; + } + // Get Scryers reputation rank + if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45431; + break; + } + return false; + } + // Sunwell Exalted Healer Neck (Shattered Sun Pendant of Restoration neck) + // cast 45478 Light's Salvation if Exalted by Aldor + // cast 45430 Arcane Surge if Exalted by Scryers + case 45484: + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (ToPlayer()->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45478; + break; + } + // Get Scryers reputation rank + if (ToPlayer()->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45430; + break; + } + return false; + } + // Kill command + case 58914: + { + // Remove aura stack from pet + RemoveAuraFromStack(58914); + Unit* owner = GetOwner(); + if (!owner) + return true; + // reduce the owner's aura stack + owner->RemoveAuraFromStack(34027); + return true; + } + // Vampiric Touch (generic, used by some boss) + case 52723: + case 60501: + { + triggered_spell_id = 52724; + basepoints0 = damage / 2; + target = this; + break; + } + // Divine purpose + case 31871: + case 31872: + { + // Roll chane + if (!victim || !victim->IsAlive() || !roll_chance_i(triggerAmount)) + return false; + + // Remove any stun effect on target + victim->RemoveAurasWithMechanic(1 << MECHANIC_STUN, AURA_REMOVE_BY_ENEMY_SPELL); + return true; + } + // Glyph of Life Tap + case 63320: + { + triggered_spell_id = 63321; // Life Tap + break; + } + case 71519: // Deathbringer's Will Normal + { + if (GetTypeId() != TYPEID_PLAYER || HasSpellCooldown(71484)) + return false; + + AddSpellCooldown(71484, 0, cooldown); + + std::vector<uint32> RandomSpells; + switch (getClass()) + { + case CLASS_WARRIOR: + case CLASS_PALADIN: + case CLASS_DEATH_KNIGHT: + RandomSpells.push_back(71484); + RandomSpells.push_back(71491); + RandomSpells.push_back(71492); + break; + case CLASS_SHAMAN: + case CLASS_ROGUE: + RandomSpells.push_back(71486); + RandomSpells.push_back(71485); + RandomSpells.push_back(71492); + break; + case CLASS_DRUID: + RandomSpells.push_back(71484); + RandomSpells.push_back(71485); + RandomSpells.push_back(71492); + break; + case CLASS_HUNTER: + RandomSpells.push_back(71486); + RandomSpells.push_back(71491); + RandomSpells.push_back(71485); + break; + default: + return false; + } + if (RandomSpells.empty()) // shouldn't happen + return false; + + uint8 rand_spell = irand(0, (RandomSpells.size() - 1)); + CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster); + break; + } + case 71562: // Deathbringer's Will Heroic + { + if (GetTypeId() != TYPEID_PLAYER || HasSpellCooldown(71561)) + return false; + + AddSpellCooldown(71561, 0, cooldown); + + std::vector<uint32> RandomSpells; + switch (getClass()) + { + case CLASS_WARRIOR: + case CLASS_PALADIN: + case CLASS_DEATH_KNIGHT: + RandomSpells.push_back(71561); + RandomSpells.push_back(71559); + RandomSpells.push_back(71560); + break; + case CLASS_SHAMAN: + case CLASS_ROGUE: + RandomSpells.push_back(71558); + RandomSpells.push_back(71556); + RandomSpells.push_back(71560); + break; + case CLASS_DRUID: + RandomSpells.push_back(71561); + RandomSpells.push_back(71556); + RandomSpells.push_back(71560); + break; + case CLASS_HUNTER: + RandomSpells.push_back(71558); + RandomSpells.push_back(71559); + RandomSpells.push_back(71556); + break; + default: + return false; + } + if (RandomSpells.empty()) // shouldn't happen + return false; + + uint8 rand_spell = irand(0, (RandomSpells.size() - 1)); + CastSpell(target, RandomSpells[rand_spell], true, castItem, triggeredByAura, originalCaster); + break; + } + // Freya, Petrified Bark + case 62933: + case 62337: + { + if (!victim) + return false; + + int32 dmg = damage; + victim->CastCustomSpell(this, 62379, &dmg, 0, 0, true); + return true; + } + // Trial of the Champion, Earth Shield + case 67534: + { + const int32 dmg = (int32)damage; + CastCustomSpell(this, 67535, &dmg, nullptr, nullptr, true, 0, triggeredByAura, triggeredByAura->GetCasterGUID()); + return true; + } + // Trial of the Crusader, Faction Champions, Retaliation + case 65932: + { + // check attack comes not from behind + if (!victim || !HasInArc(M_PI, victim)) + return false; + + triggered_spell_id = 65934; + break; + } + // Pit of Saron, Tyrannus, Overlord's Brand + case 69172: // everything except for DoTs + { + if (!target) + return false; + if (Unit* caster = triggeredByAura->GetCaster()) + { + if (procFlag & (PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS)) + { + int32 dmg = 5.5f * damage; + target->CastCustomSpell(caster, 69190, &dmg, 0, 0, true); + } + else + { + if (caster->GetVictim()) + { + int32 dmg = damage; + target->CastCustomSpell(caster->GetVictim(), 69189, &dmg, 0, 0, true); + } + } + } + return true; + } + // Pit of Saron, Tyrannus, Overlord's Brand + case 69173: // only DoTs + { + if (!target) + return false; + if (Unit* caster = triggeredByAura->GetCaster()) + { + if (procEx & PROC_EX_INTERNAL_HOT) + { + int32 dmg = 5.5f * damage; + target->CastCustomSpell(caster, 69190, &dmg, 0, 0, true); + } + else + { + if (caster->GetVictim()) + { + int32 dmg = damage; + target->CastCustomSpell(caster->GetVictim(), 69189, &dmg, 0, 0, true); + } + } + } + return true; + } + // Icecrown Citadel, Lady Deathwhisper, Vampiric Might + case 70674: + { + if (Unit* caster = triggeredByAura->GetCaster()) + { + int32 dmg = 3 * damage; + caster->CastCustomSpell(caster, 70677, &dmg, 0, 0, true); + } + return true; + } + // Item: Purified Shard of the Gods + case 69755: + { + triggered_spell_id = ((procFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) ? 69733 : 69729); + break; + } + // Item: Shiny Shard of the Gods + case 69739: + { + triggered_spell_id = ((procFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) ? 69734 : 69730); + break; + } + // VoA: Meteor Fists koralon + case 66725: + case 68161: + { + triggered_spell_id = 66765; // handled by spell_difficulty + break; + } + } + break; + } + case SPELLFAMILY_MAGE: + { + // Magic Absorption + if (dummySpell->SpellIconID == 459) // only this spell has SpellIconID == 459 and dummy aura + { + if (getPowerType() != POWER_MANA) + return false; + + // mana reward + basepoints0 = CalculatePct(int32(GetMaxPower(POWER_MANA)), triggerAmount); + target = this; + triggered_spell_id = 29442; + break; + } + // Hot Streak + if (dummySpell->SpellIconID == 2999) + { + if (effIndex != 0) + return false; + AuraEffect* counter = triggeredByAura->GetBase()->GetEffect(EFFECT_1); + if (!counter) + return true; + + // Count spell criticals in a row in second aura + if (procEx & PROC_EX_CRITICAL_HIT) + { + counter->SetAmount(counter->GetAmount() * 2); + if (counter->GetAmount() < 100) // not enough + return true; + // Crititcal counted -> roll chance + if (roll_chance_i(triggerAmount)) + CastSpell(this, 48108, true, castItem, triggeredByAura); + } + counter->SetAmount(25); + return true; + } + // Incanter's Regalia set (add trigger chance to Mana Shield) + if (dummySpell->SpellFamilyFlags[0] & 0x8000) + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + target = this; + triggered_spell_id = 37436; + break; + } + switch (dummySpell->Id) + { + // Glyph of Polymorph + case 56375: + { + if (!target) + return false; + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, ObjectGuid::Empty, target->GetAura(32409)); // SW:D shall not be removed. + target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); + target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); + return true; + } + // Glyph of Icy Veins + case 56374: + { + RemoveAurasByType(SPELL_AURA_HASTE_SPELLS, ObjectGuid::Empty, 0, true, false); + RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); + return true; + } + // Glyph of Ice Block + case 56372: + { + Player* player = ToPlayer(); + if (!player) + return false; + + SpellCooldowns const cooldowns = player->GetSpellCooldowns(); + // remove cooldowns on all ranks of Frost Nova + for (SpellCooldowns::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr) + { + SpellInfo const* cdSpell = sSpellMgr->GetSpellInfo(itr->first); + // Frost Nova + if (cdSpell && cdSpell->SpellFamilyName == SPELLFAMILY_MAGE + && cdSpell->SpellFamilyFlags[0] & 0x00000040) + player->RemoveSpellCooldown(cdSpell->Id, true); + } + break; + } + } + break; + } + case SPELLFAMILY_WARRIOR: + { + switch (dummySpell->Id) + { + // Victorious + case 32216: + { + RemoveAura(dummySpell->Id); + return false; + } + } + + // Second Wind + if (dummySpell->SpellIconID == 1697) + { + // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example) + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim) + return false; + // Need stun or root mechanic + if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN)))) + return false; + + switch (dummySpell->Id) + { + case 29838: + triggered_spell_id = 29842; + break; + case 29834: + triggered_spell_id = 29841; + break; + case 42770: + triggered_spell_id = 42771; + break; + default: + LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled spell id: {} (SW)", dummySpell->Id); + return false; + } + + target = this; + break; + } + break; + } + case SPELLFAMILY_WARLOCK: + { + // Seed of Corruption + if (dummySpell->SpellFamilyFlags[1] & 0x00000010) + { + if (procSpell && procSpell->SpellFamilyFlags[1] & 0x8000) + return false; + // if damage is more than need or target die from damage deal finish spell + if (triggeredByAura->GetAmount() <= int32(damage) || GetHealth() <= damage) + { + // remember guid before aura delete + ObjectGuid casterGuid = triggeredByAura->GetCasterGUID(); + + // Remove aura (before cast for prevent infinite loop handlers) + RemoveAurasDueToSpell(triggeredByAura->GetId()); + + uint32 spell = sSpellMgr->GetSpellWithRank(27285, dummySpell->GetRank()); + + // Cast finish spell (triggeredByAura already not exist!) + if (Unit* caster = ObjectAccessor::GetUnit(*this, casterGuid)) + { + this->CastSpell(this, 37826, true); // VISUAL! + caster->CastSpell(this, spell, true, castItem); + } + + return true; // no hidden cooldown + } + + // Damage counting + triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage); + return true; + } + // Seed of Corruption (Mobs cast) - no die req + if (dummySpell->SpellFamilyFlags.IsEqual(0, 0, 0) && dummySpell->SpellIconID == 1932) + { + // if damage is more than need deal finish spell + if (triggeredByAura->GetAmount() <= int32(damage)) + { + // remember guid before aura delete + ObjectGuid casterGuid = triggeredByAura->GetCasterGUID(); + + // Remove aura (before cast for prevent infinite loop handlers) + RemoveAurasDueToSpell(triggeredByAura->GetId()); + + // Cast finish spell (triggeredByAura already not exist!) + if (Unit* caster = ObjectAccessor::GetUnit(*this, casterGuid)) + { + this->CastSpell(this, 37826, true); // VISUAL! + caster->CastSpell(this, 32865, true, castItem); + } + return true; // no hidden cooldown + } + // Damage counting + triggeredByAura->SetAmount(triggeredByAura->GetAmount() - damage); + return true; + } + switch (dummySpell->Id) + { + // Nightfall + case 18094: + case 18095: + // Glyph of corruption + case 56218: + { + target = this; + triggered_spell_id = 17941; + break; + } + // Soul Leech + case 30293: + case 30295: + case 30296: + { + // Improved Soul Leech + AuraEffectList const& SoulLeechAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); + for (Unit::AuraEffectList::const_iterator i = SoulLeechAuras.begin(); i != SoulLeechAuras.end(); ++i) + { + if ((*i)->GetId() == 54117 || (*i)->GetId() == 54118) + { + if ((*i)->GetEffIndex() != 0) + continue; + basepoints0 = int32((*i)->GetAmount()); + target = GetGuardianPet(); + if (target) + { + // regen mana for pet + CastCustomSpell(target, 54607, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); + } + // regen mana for caster + CastCustomSpell(this, 59117, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); + // Get second aura of spell for replenishment effect on party + if (AuraEffect const* aurEff = (*i)->GetBase()->GetEffect(EFFECT_1)) + { + // Replenishment - roll chance + if (roll_chance_i(aurEff->GetAmount())) + { + CastSpell(this, 57669, true, castItem, triggeredByAura); + } + } + break; + } + } + // health + basepoints0 = CalculatePct(int32(damage), triggerAmount); + target = this; + triggered_spell_id = 30294; + break; + } + // Shadowflame (Voidheart Raiment set bonus) + case 37377: + { + triggered_spell_id = 37379; + break; + } + // Pet Healing (Corruptor Raiment or Rift Stalker Armor) + case 37381: + { + target = GetGuardianPet(); + if (!target) + return false; + + // heal amount + basepoints0 = CalculatePct(int32(damage), triggerAmount); + triggered_spell_id = 37382; + break; + } + // Shadowflame Hellfire (Voidheart Raiment set bonus) + case 39437: + { + triggered_spell_id = 37378; + break; + } + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Body and Soul + if (dummySpell->SpellIconID == 2218) + { + // Proc only from Abolish desease on self cast + if (procSpell->Id != 552 || victim != this || !roll_chance_i(triggerAmount)) + return false; + triggered_spell_id = 64136; + target = this; + break; + } + switch (dummySpell->Id) + { + // Vampiric Embrace + case 15286: + { + if (!victim || !victim->IsAlive() || procSpell->SpellFamilyFlags[1] & 0x80000) + return false; + + // heal amount + int32 total = CalculatePct(int32(damage), triggerAmount); + int32 team = total / 5; + int32 self = total - team; + CastCustomSpell(this, 15290, &team, &self, nullptr, true, castItem, triggeredByAura); + return true; // no hidden cooldown + } + // Priest Tier 6 Trinket (Ashtongue Talisman of Acumen) + case 40438: + { + // Shadow Word: Pain + if (procSpell->SpellFamilyFlags[0] & 0x8000) + triggered_spell_id = 40441; + // Renew + else if (procSpell->SpellFamilyFlags[0] & 0x40) + triggered_spell_id = 40440; + else + return false; + + target = this; + break; + } + // Improved Shadowform + case 47570: + case 47569: + { + if (!roll_chance_i(triggerAmount)) + return false; + + RemoveMovementImpairingAuras(true); + break; + } + // Glyph of Dispel Magic + case 55677: + { + // Dispel Magic shares spellfamilyflag with abolish disease + if (procSpell->SpellIconID != 74) + return false; + if (!target || !target->IsFriendlyTo(this)) + return false; + + basepoints0 = int32(target->CountPctFromMaxHealth(triggerAmount)); + triggered_spell_id = 56131; + break; + } + // Oracle Healing Bonus ("Garments of the Oracle" set) + case 26169: + { + // heal amount + basepoints0 = int32(CalculatePct(damage, 10)); + target = this; + triggered_spell_id = 26170; + break; + } + // Frozen Shadoweave (Shadow's Embrace set) warning! its not only priest set + case 39372: + { + if (!procSpell || (procSpell->GetSchoolMask() & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW)) == 0) + return false; + + // heal amount + basepoints0 = CalculatePct(int32(damage), triggerAmount); + target = this; + triggered_spell_id = 39373; + break; + } + // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus) + case 28809: + { + triggered_spell_id = 28810; + break; + } + // Priest T10 Healer 2P Bonus + case 70770: + // Flash Heal + if (procSpell->SpellFamilyFlags[0] & 0x800) + { + triggered_spell_id = 70772; + SpellInfo const* blessHealing = sSpellMgr->GetSpellInfo(triggered_spell_id); + if (!blessHealing || !victim) + return false; + basepoints0 = int32(CalculatePct(damage, triggerAmount) / (blessHealing->GetMaxDuration() / blessHealing->Effects[0].Amplitude)); + victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_HEAL, basepoints0); + return true; + } + break; + } + break; + } + case SPELLFAMILY_DRUID: + { + switch (dummySpell->Id) + { + // Glyph of Innervate + case 54832: + { + if (procSpell->SpellIconID != 62) + return false; + + int32 mana_perc = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcValue(); + basepoints0 = int32(CalculatePct(GetCreatePowers(POWER_MANA), mana_perc) / 10); + triggered_spell_id = 54833; + target = this; + break; + } + // Glyph of Starfire + case 54845: + { + triggered_spell_id = 54846; + break; + } + // Glyph of Shred + case 54815: + { + if (!target) + return false; + + // try to find spell Rip on the target + if (AuraEffect const* AurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00800000, 0x0, 0x0, GetGUID())) + { + // Rip's max duration, note: spells which modifies Rip's duration also counted like Glyph of Rip + uint32 CountMin = AurEff->GetBase()->GetMaxDuration(); + + // just Rip's max duration without other spells + uint32 CountMax = AurEff->GetSpellInfo()->GetMaxDuration(); + + // add possible auras' and Glyph of Shred's max duration + CountMax += 3 * triggerAmount * IN_MILLISECONDS; // Glyph of Shred -> +6 seconds + CountMax += HasAura(54818) ? 4 * IN_MILLISECONDS : 0; // Glyph of Rip -> +4 seconds + CountMax += HasAura(60141) ? 4 * IN_MILLISECONDS : 0; // Rip Duration/Lacerate Damage -> +4 seconds + + // if min < max -> that means caster didn't cast 3 shred yet + // so set Rip's duration and max duration + if (CountMin < CountMax) + { + AurEff->GetBase()->SetDuration(AurEff->GetBase()->GetDuration() + triggerAmount * IN_MILLISECONDS); + AurEff->GetBase()->SetMaxDuration(CountMin + triggerAmount * IN_MILLISECONDS); + return true; + } + } + // if not found Rip + return false; + } + // Glyph of Rake + case 54821: + { + if (procSpell->SpellVisual[0] == 750 && procSpell->Effects[1].ApplyAuraName == 3) + { + if (target && target->GetTypeId() == TYPEID_UNIT) + { + triggered_spell_id = 54820; + break; + } + } + return false; + } + // Leader of the Pack + case 24932: + { + if (triggerAmount <= 0) + return false; + basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); + target = this; + triggered_spell_id = 34299; + if (triggeredByAura->GetCasterGUID() != GetGUID()) + break; + int32 basepoints1 = CalculatePct(GetMaxPower(Powers(POWER_MANA)), triggerAmount * 2); + // Improved Leader of the Pack + // Check cooldown of heal spell cooldown + if (GetTypeId() == TYPEID_PLAYER && !ToPlayer()->HasSpellCooldown(34299)) + CastCustomSpell(this, 68285, &basepoints1, 0, 0, true, 0, triggeredByAura); + break; + } + // Healing Touch (Dreamwalker Raiment set) + case 28719: + { + // mana back + basepoints0 = int32(CalculatePct(spellProc->GetPowerCost(), 30)); + target = this; + triggered_spell_id = 28742; + break; + } + // Glyph of Rejuvenation + case 54754: + { + if (!victim || !victim->HealthBelowPct(uint32(triggerAmount))) + return false; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + triggered_spell_id = 54755; + break; + } + // Healing Touch Refund (Idol of Longevity trinket) + case 28847: + { + target = this; + triggered_spell_id = 28848; + break; + } + // Mana Restore (Malorne Raiment set / Malorne Regalia set) + case 37288: + case 37295: + { + target = this; + triggered_spell_id = 37238; + break; + } + // Druid Tier 6 Trinket + case 40442: + { + float chance; + + // Starfire + if (procSpell->SpellFamilyFlags[0] & 0x4) + { + triggered_spell_id = 40445; + chance = 25.0f; + } + // Rejuvenation + else if (procSpell->SpellFamilyFlags[0] & 0x10) + { + triggered_spell_id = 40446; + chance = 25.0f; + } + // Mangle (Bear) and Mangle (Cat) + else if (procSpell->SpellFamilyFlags[1] & 0x00000440) + { + triggered_spell_id = 40452; + chance = 40.0f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + target = this; + break; + } + // Maim Interrupt + case 44835: + { + // Deadly Interrupt Effect + triggered_spell_id = 32747; + break; + } + // Item - Druid T10 Restoration 4P Bonus (Rejuvenation) + case 70664: + { + // xinef: proc only from normal Rejuvenation, and proc rejuvenation + if (!victim || !procSpell || procSpell->SpellIconID != 64) + return false; + + Player* caster = ToPlayer(); + if (!caster) + return false; + if (!caster->GetGroup() && victim == this) + return false; + + CastCustomSpell(70691, SPELLVALUE_BASE_POINT0, damage, victim, true); + return true; + } + } + // Eclipse + if (dummySpell->SpellIconID == 2856 && GetTypeId() == TYPEID_PLAYER) + { + if (!procSpell || effIndex != 0) + return false; + + bool isWrathSpell = (procSpell->SpellFamilyFlags[0] & 1); + + if (!roll_chance_f(dummySpell->ProcChance * (isWrathSpell ? 0.6f : 1.0f))) + return false; + + target = this; + if (target->HasAura(isWrathSpell ? 48517 : 48518)) + return false; + + triggered_spell_id = isWrathSpell ? 48518 : 48517; + break; + } + [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked. + } + case SPELLFAMILY_ROGUE: + { + switch(dummySpell->Id) + { + // Glyph of Backstab + case 56800: + { + if (victim) + if (AuraEffect* aurEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x100000, 0, 0, GetGUID())) + if (Aura* aur = aurEff->GetBase()) + if (!aur->IsRemoved() && aur->GetDuration() > 0) + if ((aur->GetApplyTime() + aur->GetMaxDuration() / 1000 + 5) > (GameTime::GetGameTime().count() + aur->GetDuration() / 1000) ) + { + aur->SetDuration(aur->GetDuration() + 2000); + return true; + } + return false; + } + // Deadly Throw Interrupt + case 32748: + { + // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw + if (this == victim) + return false; + + triggered_spell_id = 32747; + break; + } + } + // Master of subtlety + if( dummySpell->SpellIconID == 2114 ) + { + triggered_spell_id = 31665; + basepoints0 = triggerAmount; + break; + } + // Cut to the Chase + if (dummySpell->SpellIconID == 2909) + { + // "refresh your Slice and Dice duration to its 5 combo point maximum" + // lookup Slice and Dice + if (AuraEffect const* aur = GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0)) + { + aur->GetBase()->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true); + return true; + } + return false; + } + // Deadly Brew + else if (dummySpell->SpellIconID == 2963) + { + triggered_spell_id = 3409; + break; + } + // Quick Recovery + else if (dummySpell->SpellIconID == 2116) + { + if (!procSpell) + return false; + + // energy cost save + basepoints0 = CalculatePct(int32(procSpell->ManaCost), triggerAmount); + if (basepoints0 <= 0) + return false; + + target = this; + triggered_spell_id = 31663; + break; + } + break; + } + case SPELLFAMILY_HUNTER: + { + switch (dummySpell->SpellIconID) + { + case 2236: // Thrill of the Hunt + { + if (!procSpell) + return false; + + Spell* spell = ToPlayer()->m_spellModTakingSpell; + + // Disable charge drop because of Lock and Load + if (spell) + ToPlayer()->SetSpellModTakingSpell(spell, false); + + // Explosive Shot + if (procSpell->SpellFamilyFlags[2] & 0x200) + { + if (!victim) + return false; + if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, GetGUID())) + basepoints0 = pEff->GetSpellInfo()->CalcPowerCost(this, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4 / 10 / 3; + } + else + basepoints0 = procSpell->CalcPowerCost(this, SpellSchoolMask(procSpell->SchoolMask)) * 4 / 10; + + if (spell) + ToPlayer()->SetSpellModTakingSpell(spell, true); + + if (basepoints0 <= 0) + return false; + + target = this; + triggered_spell_id = 34720; + break; + } + case 3406: // Hunting Party + { + triggered_spell_id = 57669; + target = this; + break; + } + case 3560: // Rapid Recuperation + { + // This effect only from Rapid Killing (mana regen) + if (!(procSpell->SpellFamilyFlags[1] & 0x01000000)) + return false; + + target = this; + + switch (dummySpell->Id) + { + case 53228: // Rank 1 + triggered_spell_id = 56654; + break; + case 53232: // Rank 2 + triggered_spell_id = 58882; + break; + } + break; + } + } + + switch (dummySpell->Id) + { + case 57870: // Glyph of Mend Pet + { + if (!victim) + return false; + + victim->CastSpell(victim, 57894, true, nullptr, nullptr, GetGUID()); + return true; + } + } + break; + } + case SPELLFAMILY_PALADIN: + { + // Light's Beacon - Beacon of Light + if (dummySpell->Id == 53651) + { + if (!victim) + return false; + + // Do not proc from Glyph of Holy Light and Judgement of Light + if (procSpell->Id == 20267 || procSpell->Id == 54968) + { + return false; + } + + Unit* beaconTarget = triggeredByAura->GetBase()->GetCaster(); + if (!beaconTarget || beaconTarget == this || !beaconTarget->GetAura(53563, victim->GetGUID())) + return false; + + basepoints0 = int32(damage); + triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654; + + victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, nullptr, nullptr, true, 0, triggeredByAura, victim->GetGUID()); + return true; + } + // Judgements of the Wise + if (dummySpell->SpellIconID == 3017) + { + target = this; + triggered_spell_id = 31930; + // replenishment + CastSpell(this, 57669, true, castItem, triggeredByAura); + break; + } + // Righteous Vengeance + if (dummySpell->SpellIconID == 3025) + { + if (!victim) + return false; + + // 4 damage tick + basepoints0 = triggerAmount * damage / 400; + triggered_spell_id = 61840; + // Add remaining ticks to damage done + victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0); + return true; + } + // Sheath of Light + if (dummySpell->SpellIconID == 3030) + { + // 4 healing tick + basepoints0 = triggerAmount * damage / 400; + triggered_spell_id = 54203; + break; + } + switch (dummySpell->Id) + { + // Judgement of Light + case 20185: + { + if (!victim || !victim->IsAlive() || victim->HasSpellCooldown(20267)) + return false; + // 2% of base mana + basepoints0 = int32(victim->CountPctFromMaxHealth(2)); + victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura); + victim->AddSpellCooldown(20267, 0, 4 * IN_MILLISECONDS); + return true; + } + // Judgement of Wisdom + case 20186: + { + if (!victim || !victim->IsAlive() || victim->getPowerType() != POWER_MANA || victim->HasSpellCooldown(20268)) + return false; + + // 2% of base mana + basepoints0 = int32(CalculatePct(victim->GetCreateMana(), 2)); + victim->CastCustomSpell(victim, 20268, &basepoints0, nullptr, nullptr, true, 0, triggeredByAura); + victim->AddSpellCooldown(20268, 0, 4 * IN_MILLISECONDS); + return true; + } + // Holy Power (Redemption Armor set) + case 28789: + { + if (!victim) + return false; + + // Set class defined buff + switch (victim->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + triggered_spell_id = 28795; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + triggered_spell_id = 28793; // Increases the friendly target's spell damage and healing by up to $s1 for $d. + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + triggered_spell_id = 28791; // Increases the friendly target's attack power by $s1 for $d. + break; + case CLASS_WARRIOR: + triggered_spell_id = 28790; // Increases the friendly target's armor + break; + default: + return false; + } + break; + } + // Seal of Vengeance (damage calc on apply aura) + case 31801: + { + if (effIndex != 0 || !victim) // effect 1, 2 used by seal unleashing code + return false; + + // At melee attack or Hammer of the Righteous spell damage considered as melee attack + bool stacker = !procSpell || procSpell->Id == 53595; + // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements + bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39)); + + if (!stacker && !damager) + return false; + + triggered_spell_id = 31803; + + // On target with 5 stacks of Holy Vengeance direct damage is done + if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID())) + { + if (aur->GetStackAmount() == 5) + { + if (stacker) + aur->RefreshDuration(); + + CastSpell(victim, 42463, true, castItem, triggeredByAura); + return true; + } + } + + if (!stacker) + return false; + break; + } + // Seal of Corruption + case 53736: + { + if (effIndex != 0 || !victim) // effect 1, 2 used by seal unleashing code + return false; + + // At melee attack or Hammer of the Righteous spell damage considered as melee attack + bool stacker = !procSpell || procSpell->Id == 53595; + // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements + bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39)); + + if (!stacker && !damager) + return false; + + triggered_spell_id = 53742; + + // On target with 5 stacks of Blood Corruption direct damage is done + if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID())) + { + if (aur->GetStackAmount() == 5) + { + if (stacker) + aur->RefreshDuration(); + + CastSpell(victim, 53739, true, castItem, triggeredByAura); + return true; + } + } + + if (!stacker) + return false; + break; + } + // Spiritual Attunement + case 31785: + case 33776: + { + // if healed by another unit (victim) + if (this == victim) + return false; + + // dont allow non-positive dots to proc + if (!procSpell || !procSpell->IsPositive()) + return false; + + // heal amount + basepoints0 = int32(CalculatePct(std::min(damage, GetMaxHealth() - GetHealth()), triggerAmount)); + target = this; + + if (basepoints0) + triggered_spell_id = 31786; + break; + } + // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) + case 40470: + { + if (!procSpell) + return false; + + float chance = 0.0f; + + // Flash of light/Holy light + if (procSpell->SpellFamilyFlags[0] & 0xC0000000) + { + triggered_spell_id = 40471; + chance = 15.0f; + } + // Judgement (any) + else if (procSpell->SpellFamilyFlags[0] & 0x800000) + { + triggered_spell_id = 40472; + chance = 50.0f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + break; + } + // Glyph of Holy Light + case 54937: + { + triggered_spell_id = 54968; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + break; + } + // Item - Paladin T8 Holy 2P Bonus + case 64890: + { + triggered_spell_id = 64891; + basepoints0 = triggerAmount * damage / 300; + break; + } + case 71406: // Tiny Abomination in a Jar + case 71545: // Tiny Abomination in a Jar (Heroic) + { + if (!victim || !victim->IsAlive()) + return false; + + CastSpell(this, 71432, true, nullptr, triggeredByAura); + + Aura const* dummy = GetAura(71432); + if (!dummy || dummy->GetStackAmount() < (dummySpell->Id == 71406 ? 8 : 7)) + return false; + + RemoveAurasDueToSpell(71432); + triggered_spell_id = 71433; // default main hand attack + // roll if offhand + if (Player const* player = ToPlayer()) + if (player->GetWeaponForAttack(OFF_ATTACK, true) && urand(0, 1)) + triggered_spell_id = 71434; + target = victim; + break; + } + // Item - Icecrown 25 Normal Dagger Proc + case 71880: + { + switch (getPowerType()) + { + case POWER_MANA: + triggered_spell_id = 71881; + break; + case POWER_RAGE: + triggered_spell_id = 71883; + break; + case POWER_ENERGY: + triggered_spell_id = 71882; + break; + case POWER_RUNIC_POWER: + triggered_spell_id = 71884; + break; + default: + return false; + } + break; + } + // Item - Icecrown 25 Heroic Dagger Proc + case 71892: + { + switch (getPowerType()) + { + case POWER_MANA: + triggered_spell_id = 71888; + break; + case POWER_RAGE: + triggered_spell_id = 71886; + break; + case POWER_ENERGY: + triggered_spell_id = 71887; + break; + case POWER_RUNIC_POWER: + triggered_spell_id = 71885; + break; + default: + return false; + } + break; + } + } + break; + } + case SPELLFAMILY_SHAMAN: + { + switch (dummySpell->Id) + { + // Tidal Force + case 55198: + { + // Remove aura stack from caster + RemoveAuraFromStack(55166); + // drop charges + return false; + } + // Totemic Power (The Earthshatterer set) + case 28823: + { + if (!victim) + return false; + + // Set class defined buff + switch (victim->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + triggered_spell_id = 28824; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + triggered_spell_id = 28825; // Increases the friendly target's spell damage and healing by up to $s1 for $d. + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + triggered_spell_id = 28826; // Increases the friendly target's attack power by $s1 for $d. + break; + case CLASS_WARRIOR: + triggered_spell_id = 28827; // Increases the friendly target's armor + break; + default: + return false; + } + break; + } + // Lesser Healing Wave (Totem of Flowing Water Relic) + case 28849: + { + target = this; + triggered_spell_id = 28850; + break; + } + // Windfury Weapon (Passive) 1-8 Ranks + case 33757: + { + Player* player = ToPlayer(); + if (!player || !castItem || !castItem->IsEquipped() || !victim || !victim->IsAlive()) + return false; + + if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID()) + return false; + + WeaponAttackType attType = WeaponAttackType(player->GetAttackBySlot(castItem->GetSlot())); + if ((attType != BASE_ATTACK && attType != OFF_ATTACK) + || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) + || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)) + return false; + + // Now amount of extra power stored in 1 effect of Enchant spell + // Get it by item enchant id + uint32 spellId; + switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT))) + { + case 283: + spellId = 8232; + break; // 1 Rank + case 284: + spellId = 8235; + break; // 2 Rank + case 525: + spellId = 10486; + break; // 3 Rank + case 1669: + spellId = 16362; + break; // 4 Rank + case 2636: + spellId = 25505; + break; // 5 Rank + case 3785: + spellId = 58801; + break; // 6 Rank + case 3786: + spellId = 58803; + break; // 7 Rank + case 3787: + spellId = 58804; + break; // 8 Rank + default: + { + LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled item enchantment (rank?) {} for spell id: {} (Windfury)", + castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)), dummySpell->Id); + return false; + } + } + + SpellInfo const* windfurySpellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!windfurySpellInfo) + { + LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non-existing spell id: {} (Windfury)", spellId); + return false; + } + + int32 extra_attack_power = CalculateSpellDamage(victim, windfurySpellInfo, 1); + + // Value gained from additional AP + basepoints0 = int32(extra_attack_power / 14.0f * GetAttackTime(attType) / 1000); + + if (procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK) + triggered_spell_id = 25504; + + if (procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) + triggered_spell_id = 33750; + + // custom cooldown processing case + if (player->HasSpellCooldown(dummySpell->Id)) + return false; + + // apply cooldown before cast to prevent processing itself + player->AddSpellCooldown(dummySpell->Id, 0, 3 * IN_MILLISECONDS); + + // Attack Twice + for (uint32 i = 0; i < 2; ++i) + CastCustomSpell(victim, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); + + return true; + } + // Shaman Tier 6 Trinket + case 40463: + { + if (!procSpell) + return false; + + float chance; + if (procSpell->SpellFamilyFlags[0] & 0x1) + { + triggered_spell_id = 40465; // Lightning Bolt + chance = 15.0f; + } + else if (procSpell->SpellFamilyFlags[0] & 0x80) + { + triggered_spell_id = 40465; // Lesser Healing Wave + chance = 10.0f; + } + else if (procSpell->SpellFamilyFlags[1] & 0x00000010) + { + triggered_spell_id = 40466; // Stormstrike + chance = 50.0f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + target = this; + break; + } + // Glyph of Healing Wave + case 55440: + { + // Not proc from self heals + if (this == victim) + return false; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + target = this; + triggered_spell_id = 55533; + break; + } + // Spirit Hunt + case 58877: + { + // Cast on owner + target = GetOwner(); + if (!target) + return false; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + triggered_spell_id = 58879; + // Heal wolf + CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); + break; + } + // Shaman T8 Elemental 4P Bonus + case 64928: + { + basepoints0 = CalculatePct(int32(damage), triggerAmount); + triggered_spell_id = 64930; // Electrified + break; + } + // Shaman T9 Elemental 4P Bonus + case 67228: + { + // Lava Burst + if (procSpell->SpellFamilyFlags[1] & 0x1000) + { + triggered_spell_id = 71824; + SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id); + if (!triggeredSpell) + return false; + basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].Amplitude); + } + break; + } + // Item - Shaman T10 Elemental 4P Bonus + case 70817: + { + if (!target) + return false; + // try to find spell Flame Shock on the target + if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x0, 0x0, GetGUID())) + { + Aura* flameShock = aurEff->GetBase(); + int32 extraTime = 2 * aurEff->GetAmplitude(); + flameShock->SetMaxDuration(flameShock->GetMaxDuration() + extraTime); + flameShock->SetDuration(flameShock->GetDuration() + extraTime); + + return true; + } + // if not found Flame Shock + return false; + } + break; + } + // Frozen Power + if (dummySpell->SpellIconID == 3780) + { + if (!target) + return false; + if (GetDistance(target) < 15.0f) + return false; + float chance = (float)triggerAmount; + if (!roll_chance_f(chance)) + return false; + + triggered_spell_id = 63685; + break; + } + // Ancestral Awakening + if (dummySpell->SpellIconID == 3065) + { + triggered_spell_id = 52759; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + target = this; + break; + } + // Flametongue Weapon (Passive) + if (dummySpell->SpellFamilyFlags[0] & 0x200000) + { + if (GetTypeId() != TYPEID_PLAYER || !victim || !victim->IsAlive() || !castItem || !castItem->IsEquipped()) + return false; + + WeaponAttackType attType = WeaponAttackType(Player::GetAttackBySlot(castItem->GetSlot())); + if ((attType != BASE_ATTACK && attType != OFF_ATTACK) + || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) + || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)) + return false; + + float fire_onhit = float(CalculatePct(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f)); + + float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) + + victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE)); + + // 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84% + ApplyPct(add_spellpower, 3.84f); + + // Enchant on Off-Hand and ready? + if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK) + { + float BaseWeaponSpeed = GetAttackTime(OFF_ATTACK) / 1000.0f; + + // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed + basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed)); + triggered_spell_id = 10444; + } + + // Enchant on Main-Hand and ready? + else if (castItem->GetSlot() == EQUIPMENT_SLOT_MAINHAND && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK) + { + float BaseWeaponSpeed = GetAttackTime(BASE_ATTACK) / 1000.0f; + + // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed + basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed)); + triggered_spell_id = 10444; + } + + // If not ready, we should return, shouldn't we?! + else + return false; + + CastCustomSpell(victim, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); + return true; + } + // Improved Water Shield + if (dummySpell->SpellIconID == 2287) + { + if (!procSpell) + return false; + + // Default chance for Healing Wave and Riptide + float chance = (float)triggeredByAura->GetAmount(); + + if (procSpell->SpellFamilyFlags[0] & 0x80) + // Lesser Healing Wave - 0.6 of default + chance *= 0.6f; + else if (procSpell->SpellFamilyFlags[0] & 0x100) + // Chain heal - 0.3 of default + chance *= 0.3f; + + if (!roll_chance_f(chance)) + return false; + + // Water Shield + if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020, 0)) + { + uint32 spell = aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell; + CastSpell(this, spell, true, castItem, triggeredByAura); + return true; + } + return false; + } + // Lightning Overload + if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura + { + if(!procSpell || GetTypeId() != TYPEID_PLAYER || !victim) + return false; + + if (procEx & PROC_EX_CRITICAL_HIT) + damage /= 2; + + do + { + uint32 spell = 0; + + if (procSpell->SpellFamilyFlags[0] & 0x2) + { + // 1/3 of 33% if 11% + if (!roll_chance_i(33)) + return false; + + spell = 45297; + } + else + spell = 45284; + + // do not reduce damage-spells have correct basepoints + damage /= 2; + int32 dmg = damage; + + // Cast + CastCustomSpell(victim, spell, &dmg, 0, 0, true, castItem, triggeredByAura); + } while (roll_chance_i(33)); + return true; + } + // Static Shock + if (dummySpell->SpellIconID == 3059) + { + // Lightning Shield + if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0)) + { + uint32 spell = sSpellMgr->GetSpellWithRank(26364, aurEff->GetSpellInfo()->GetRank()); + CastSpell(target, spell, true, castItem, triggeredByAura); + aurEff->GetBase()->DropCharge(); + return true; + } + return false; + } + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Improved Blood Presence + if (dummySpell->SpellIconID == 2636) + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + break; + } + // Butchery + if (dummySpell->SpellIconID == 2664) + { + basepoints0 = triggerAmount; + triggered_spell_id = 50163; + target = this; + break; + } + // Mark of Blood + if (dummySpell->Id == 49005) + { + // TODO: need more info (cooldowns/PPM) + triggered_spell_id = 61607; + break; + } + // Unholy Blight + if (dummySpell->Id == 49194) + { + triggered_spell_id = 50536; + SpellInfo const* unholyBlight = sSpellMgr->GetSpellInfo(triggered_spell_id); + if (!unholyBlight || !victim) + return false; + + basepoints0 = CalculatePct(int32(damage), triggerAmount); + + //Glyph of Unholy Blight + if (AuraEffect* glyph = GetAuraEffect(63332, 0)) + AddPct(basepoints0, glyph->GetAmount()); + + basepoints0 = basepoints0 / (unholyBlight->GetMaxDuration() / unholyBlight->Effects[0].Amplitude); + victim->CastDelayedSpellWithPeriodicAmount(this, triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0); + return true; + } + // Vendetta + if (dummySpell->SpellFamilyFlags[0] & 0x10000) + { + basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); + triggered_spell_id = 50181; + target = this; + break; + } + // Necrosis + if (dummySpell->SpellIconID == 2709) + { + basepoints0 = CalculatePct(int32(damage), triggerAmount); + triggered_spell_id = 51460; + break; + } + // Threat of Thassarian + if (dummySpell->SpellIconID == 2023) + { + // Must Dual Wield + if (!procSpell || !haveOffhandWeapon()) + return false; + // Chance as basepoints for dummy aura + if (!roll_chance_i(triggerAmount)) + return false; + + switch (procSpell->Id) + { + // Obliterate + case 49020: + triggered_spell_id = 66198; + break; // Rank 1 + case 51423: + triggered_spell_id = 66972; + break; // Rank 2 + case 51424: + triggered_spell_id = 66973; + break; // Rank 3 + case 51425: + triggered_spell_id = 66974; + break; // Rank 4 + + // Frost Strike + case 49143: + triggered_spell_id = 66196; + break; // Rank 1 + case 51416: + triggered_spell_id = 66958; + break; // Rank 2 + case 51417: + triggered_spell_id = 66959; + break; // Rank 3 + case 51418: + triggered_spell_id = 66960; + break; // Rank 4 + case 51419: + triggered_spell_id = 66961; + break; // Rank 5 + case 55268: + triggered_spell_id = 66962; + break; // Rank 6 + + // Plague Strike + case 45462: + triggered_spell_id = 66216; + break; // Rank 1 + case 49917: + triggered_spell_id = 66988; + break; // Rank 2 + case 49918: + triggered_spell_id = 66989; + break; // Rank 3 + case 49919: + triggered_spell_id = 66990; + break; // Rank 4 + case 49920: + triggered_spell_id = 66991; + break; // Rank 5 + case 49921: + triggered_spell_id = 66992; + break; // Rank 6 + + // Death Strike + case 49998: + triggered_spell_id = 66188; + break; // Rank 1 + case 49999: + triggered_spell_id = 66950; + break; // Rank 2 + case 45463: + triggered_spell_id = 66951; + break; // Rank 3 + case 49923: + triggered_spell_id = 66952; + break; // Rank 4 + case 49924: + triggered_spell_id = 66953; + break; // Rank 5 + + // Rune Strike + case 56815: + triggered_spell_id = 66217; + break; // Rank 1 + + // Blood Strike + case 45902: + triggered_spell_id = 66215; + break; // Rank 1 + case 49926: + triggered_spell_id = 66975; + break; // Rank 2 + case 49927: + triggered_spell_id = 66976; + break; // Rank 3 + case 49928: + triggered_spell_id = 66977; + break; // Rank 4 + case 49929: + triggered_spell_id = 66978; + break; // Rank 5 + case 49930: + triggered_spell_id = 66979; + break; // Rank 6 + default: + return false; + } + + // This should do, restore spell mod so next attack can also use this! + // crit chance for first strike is already computed + ToPlayer()->RestoreSpellMods(m_currentSpells[CURRENT_GENERIC_SPELL], 51124, nullptr); // Killing Machine + ToPlayer()->RestoreSpellMods(m_currentSpells[CURRENT_GENERIC_SPELL], 49796, nullptr); // Deathchill + + // Xinef: Somehow basepoints are divided by 2 which is later divided by 2 (offhand multiplier) + SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); + if (triggerEntry->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) + basepoints0 = triggerEntry->Effects[EFFECT_0].BasePoints * 2; + + SetCantProc(true); + if(basepoints0) + CastCustomSpell(target, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); + else + CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster); + SetCantProc(false); + return true; + } + // Runic Power Back on Snare/Root + if (dummySpell->Id == 61257) + { + // only for spells and hit/crit (trigger start always) and not start from self casted spells + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim) + return false; + // Need snare or root mechanic + if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_SNARE)))) + return false; + triggered_spell_id = 61258; + target = this; + break; + } + // Sudden Doom + if (dummySpell->SpellIconID == 1939 && GetTypeId() == TYPEID_PLAYER) + { + SpellChainNode const* chain = nullptr; + // get highest rank of the Death Coil spell + PlayerSpellMap const& sp_list = ToPlayer()->GetSpellMap(); + for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + { + // check if shown in spell book + if (!itr->second->Active || !itr->second->IsInSpec(ToPlayer()->GetActiveSpec()) || itr->second->State == PLAYERSPELL_REMOVED) + continue; + + SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(itr->first); + if (!spellProto) + continue; + + if (spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT + && spellProto->SpellFamilyFlags[0] & 0x2000) + { + SpellChainNode const* newChain = sSpellMgr->GetSpellChainNode(itr->first); + + // No chain entry or entry lower than found entry + if (!chain || !newChain || (chain->rank < newChain->rank)) + { + triggered_spell_id = itr->first; + chain = newChain; + } + else + continue; + // Found spell is last in chain - do not need to look more + // Optimisation for most common case + if (chain && chain->last->Id == itr->first) + break; + } + } + } + break; + } + case SPELLFAMILY_POTION: + { + // alchemist's stone + if (dummySpell->Id == 17619) + { + if (procSpell->SpellFamilyName == SPELLFAMILY_POTION) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++) + { + if (procSpell->Effects[i].Effect == SPELL_EFFECT_HEAL) + { + triggered_spell_id = 21399; + } + else if (procSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE) + { + triggered_spell_id = 21400; + } + else + continue; + + basepoints0 = int32(CalculateSpellDamage(this, procSpell, i) * 0.4f); + CastCustomSpell(this, triggered_spell_id, &basepoints0, nullptr, nullptr, true, nullptr, triggeredByAura); + } + return true; + } + } + break; + } + case SPELLFAMILY_PET: + { + switch (dummySpell->SpellIconID) + { + // Guard Dog + case 201: + { + if (!victim) + return false; + + triggered_spell_id = 54445; + target = this; + float addThreat = float(CalculatePct(procSpell->Effects[0].CalcValue(this), triggerAmount)); + victim->AddThreat(this, addThreat); + break; + } + // Silverback + case 1582: + triggered_spell_id = dummySpell->Id == 62765 ? 62801 : 62800; + target = this; + break; + } + break; + } + default: + break; + } + + // if not handled by custom case, get triggered spell from dummySpell proto + if (!triggered_spell_id) + triggered_spell_id = dummySpell->Effects[triggeredByAura->GetEffIndex()].TriggerSpell; + + // processed charge only counting case + if (!triggered_spell_id) + return true; + + SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); + if (!triggerEntry) + { + LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: Spell {} has non-existing triggered spell {}", dummySpell->Id, triggered_spell_id); + return false; + } + + if (cooldown_spell_id == 0) + cooldown_spell_id = triggered_spell_id; + + if (cooldown) + { + if (HasSpellCooldown(cooldown_spell_id)) + return false; + + AddSpellCooldown(cooldown_spell_id, 0, cooldown); + } + + if(basepoints0) + CastCustomSpell(target, triggered_spell_id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura, originalCaster); + else + CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura, originalCaster); + + return true; +} + +// Used in case when access to whole aura is needed +// All procs should be handled like this... +bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 /*procFlag*/, uint32 procEx, uint32 cooldown, bool* handled) +{ + SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo(); + + switch (dummySpell->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + switch (dummySpell->Id) + { + // Nevermelting Ice Crystal + case 71564: + RemoveAuraFromStack(71564); + *handled = true; + break; + // Gaseous Bloat + case 70672: + case 72455: + case 72832: + case 72833: + { + if (Unit* caster = triggeredByAura->GetCaster()) + if (victim && caster->GetGUID() == victim->GetGUID()) + { + *handled = true; + uint32 stack = triggeredByAura->GetStackAmount(); + int32 const mod = (GetMap()->GetSpawnMode() & 1) ? 1500 : 1250; + int32 dmg = 0; + for (uint8 i = 1; i <= stack; ++i) + dmg += mod * i; + caster->CastCustomSpell(70701, SPELLVALUE_BASE_POINT0, dmg); + } + break; + } + // Ball of Flames Proc + case 71756: + case 72782: + case 72783: + case 72784: + RemoveAuraFromStack(dummySpell->Id); + *handled = true; + break; + // Discerning Eye of the Beast + case 59915: + { + CastSpell(this, 59914, true); // 59914 already has correct basepoints in DBC, no need for custom bp + *handled = true; + break; + } + // Swift Hand of Justice + case 59906: + { + int32 bp0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_0]. CalcValue()); + CastCustomSpell(this, 59913, &bp0, nullptr, nullptr, true); + *handled = true; + break; + } + } + + break; + case SPELLFAMILY_MAGE: + { + // Combustion + switch (dummySpell->Id) + { + case 11129: + { + *handled = true; + Unit* caster = triggeredByAura->GetCaster(); + if (!caster || !damage) + return false; + + // last charge and crit + if (triggeredByAura->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT)) + return true; // charge counting (will removed) + + CastSpell(this, 28682, true); + + return procEx & PROC_EX_CRITICAL_HIT; + } + // Empowered Fire + case 31656: + case 31657: + case 31658: + { + *handled = true; + + SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(67545); + if (!spInfo) + return false; + + int32 bp0 = int32(CalculatePct(GetMaxPower(POWER_MANA), spInfo->Effects[0].CalcValue())); + CastCustomSpell(this, 67545, &bp0, nullptr, nullptr, true, nullptr, triggeredByAura->GetEffect(EFFECT_0), GetGUID()); + return true; + } + } + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Blood of the North + // Reaping + // Death Rune Mastery + // xinef: Icon 22 is used for item bonus, skip + if (dummySpell->SpellIconID == 3041 || (dummySpell->SpellIconID == 22 && dummySpell->Id != 62459) || dummySpell->SpellIconID == 2622) + { + *handled = true; + // Convert recently used Blood Rune to Death Rune + if (Player* player = ToPlayer()) + { + if (player->getClass() != CLASS_DEATH_KNIGHT) + return false; + + // xinef: not true + //RuneType rune = ToPlayer()->GetLastUsedRune(); + // can't proc from death rune use + //if (rune == RUNE_DEATH) + // return false; + AuraEffect* aurEff = triggeredByAura->GetEffect(EFFECT_0); + if (!aurEff) + return false; + + // Reset amplitude - set death rune remove timer to 30s + aurEff->ResetPeriodic(true); + uint32 runesLeft; + + if (dummySpell->SpellIconID == 2622) + runesLeft = 2; + else + runesLeft = 1; + + for (uint8 i = 0; i < MAX_RUNES && runesLeft; ++i) + { + if (dummySpell->SpellIconID == 2622) + { + if (player->GetCurrentRune(i) == RUNE_DEATH || + player->GetBaseRune(i) == RUNE_BLOOD) + continue; + } + else + { + if (player->GetCurrentRune(i) == RUNE_DEATH || + player->GetBaseRune(i) != RUNE_BLOOD) + continue; + } + if (player->GetRuneCooldown(i) != player->GetRuneBaseCooldown(i, false)) + continue; + + --runesLeft; + // Mark aura as used + player->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff); + } + return true; + } + return false; + } + break; + } + case SPELLFAMILY_WARRIOR: + { + switch (dummySpell->Id) + { + // Item - Warrior T10 Protection 4P Bonus + case 70844: + { + int32 basepoints0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_1]. CalcValue()); + CastCustomSpell(this, 70845, &basepoints0, nullptr, nullptr, true); + break; + } + default: + break; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + // Flurry + if ((dummySpell->SpellFamilyFlags[1] & 0x00000200) != 0) + { + if (cooldown) + { + if (HasSpellCooldown(dummySpell->Id)) + { + *handled = true; + break; + } + + AddSpellCooldown(dummySpell->Id, 0, cooldown); + } + } + break; + } + } + return false; +} + +bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo) +{ + // Get triggered aura spell info + SpellInfo const* auraSpellInfo = triggeredByAura->GetSpellInfo(); + + // Basepoints of trigger aura + int32 triggerAmount = triggeredByAura->GetAmount(); + + // Set trigger spell id, target, custom basepoints + uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell; + + Unit* target = nullptr; + int32 basepoints0 = 0; + + if (triggeredByAura->GetAuraType() == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE) + basepoints0 = triggerAmount; + + Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER + ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; + + // Try handle unknown trigger spells + //if (sSpellMgr->GetSpellInfo(trigger_spell_id) == nullptr) + { + switch (auraSpellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + switch (auraSpellInfo->Id) + { + case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket) + // Pct value stored in dummy + if (!victim) + return false; + basepoints0 = victim->GetCreateHealth() * auraSpellInfo->Effects[1].CalcValue() / 100; + target = victim; + break; + case 57345: // Darkmoon Card: Greatness + { + float stat = 0.0f; + // strength + if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229; stat = GetStat(STAT_STRENGTH); } + // agility + if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233; stat = GetStat(STAT_AGILITY); } + // intellect + if (GetStat(STAT_INTELLECT) > stat) { trigger_spell_id = 60234; stat = GetStat(STAT_INTELLECT);} + // spirit + if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235; } + break; + } + case 67702: // Death's Choice, Item - Coliseum 25 Normal Melee Trinket + { + if (!damage) + return false; + float stat = 0.0f; + // strength + if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67708; stat = GetStat(STAT_STRENGTH); } + // agility + if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67703; } + break; + } + case 67771: // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket + { + if (!damage) + return false; + float stat = 0.0f; + // strength + if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67773; stat = GetStat(STAT_STRENGTH); } + // agility + if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67772; } + break; + } + // Mana Drain Trigger + case 27522: + case 40336: + { + // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target. + if (IsAlive()) + CastSpell(this, 29471, true, castItem, triggeredByAura); + if (victim && victim->IsAlive()) + CastSpell(victim, 27526, true, castItem, triggeredByAura); + return true; + } + // Forge of Souls, Devourer of Souls, Mirrored Soul + case 69023: + { + int32 dmg = damage * 0.45f; + if (dmg > 0) + if (Aura* a = GetAura(69023)) + if (Unit* c = a->GetCaster()) + CastCustomSpell(c, 69034, &dmg, 0, 0, true); + return true; + } + // Soul-Trader Beacon proc aura + case 50051: + { + if (!victim) + return false; + + if (Creature* cr = ObjectAccessor::GetCreature(*this, m_SummonSlot[SUMMON_SLOT_MINIPET])) + cr->CastSpell(victim, 50101, true); + + return false; + } + } + break; + case SPELLFAMILY_MAGE: + if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed + { + switch (auraSpellInfo->Id) + { + case 31641: // Rank 1 + case 31642: // Rank 2 + trigger_spell_id = 31643; + break; + default: + LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} miss posibly Blazing Speed", auraSpellInfo->Id); + return false; + } + } + else if (auraSpellInfo->Id == 71761) // Deep Freeze Immunity State (only permanent) + { + Creature* creature = victim->ToCreature(); + if (!creature || !creature->HasMechanicTemplateImmunity(1 << (MECHANIC_STUN - 1))) + return false; + } + break; + case SPELLFAMILY_WARLOCK: + { + // Nether Protection + if (auraSpellInfo->SpellIconID == 1985) + { + if (!procSpell) + return false; + switch (GetFirstSchoolInMask(procSpell->GetSchoolMask())) + { + case SPELL_SCHOOL_NORMAL: + return false; // ignore + case SPELL_SCHOOL_HOLY: + trigger_spell_id = 54370; + break; + case SPELL_SCHOOL_FIRE: + trigger_spell_id = 54371; + break; + case SPELL_SCHOOL_NATURE: + trigger_spell_id = 54375; + break; + case SPELL_SCHOOL_FROST: + trigger_spell_id = 54372; + break; + case SPELL_SCHOOL_SHADOW: + trigger_spell_id = 54374; + break; + case SPELL_SCHOOL_ARCANE: + trigger_spell_id = 54373; + break; + default: + return false; + } + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Blessed Recovery + if (auraSpellInfo->SpellIconID == 1875) + { + switch (auraSpellInfo->Id) + { + case 27811: + trigger_spell_id = 27813; + break; + case 27815: + trigger_spell_id = 27817; + break; + case 27816: + trigger_spell_id = 27818; + break; + default: + LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} not handled in BR", auraSpellInfo->Id); + return false; + } + basepoints0 = CalculatePct(int32(damage), triggerAmount) / 3; + target = this; + // Add remaining ticks to healing done + CastDelayedSpellWithPeriodicAmount(this, trigger_spell_id, SPELL_AURA_PERIODIC_HEAL, basepoints0); + return true; + } + break; + } + case SPELLFAMILY_DRUID: + { + switch (auraSpellInfo->Id) + { + // Druid Forms Trinket + case 37336: + { + switch (GetShapeshiftForm()) + { + case FORM_NONE: + trigger_spell_id = 37344; + break; + case FORM_CAT: + trigger_spell_id = 37341; + break; + case FORM_BEAR: + case FORM_DIREBEAR: + trigger_spell_id = 37340; + break; + case FORM_TREE: + trigger_spell_id = 37342; + break; + case FORM_MOONKIN: + trigger_spell_id = 37343; + break; + default: + return false; + } + break; + } + // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) + case 67353: + { + switch (GetShapeshiftForm()) + { + case FORM_CAT: + trigger_spell_id = 67355; + break; + case FORM_BEAR: + case FORM_DIREBEAR: + trigger_spell_id = 67354; + break; + default: + return false; + } + break; + } + default: + break; + } + break; + } + case SPELLFAMILY_HUNTER: + { + if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots + { + if (!victim) + return false; + + switch (auraSpellInfo->Id) + { + case 53234: // Rank 1 + case 53237: // Rank 2 + case 53238: // Rank 3 + trigger_spell_id = 63468; + break; + default: + LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} miss posibly Piercing Shots", auraSpellInfo->Id); + return false; + } + SpellInfo const* TriggerPS = sSpellMgr->GetSpellInfo(trigger_spell_id); + if (!TriggerPS) + return false; + + basepoints0 = CalculatePct(int32(damage), triggerAmount) / (TriggerPS->GetMaxDuration() / TriggerPS->Effects[0].Amplitude); + victim->CastDelayedSpellWithPeriodicAmount(this, trigger_spell_id, SPELL_AURA_PERIODIC_DAMAGE, basepoints0); + return true; + } + // Item - Hunter T9 4P Bonus (Steady Shot) + else if (auraSpellInfo->Id == 67151) + { + if (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->GetPet()) + return false; + + target = ToPlayer()->GetPet(); + trigger_spell_id = 68130; + break; + } + break; + } + case SPELLFAMILY_PALADIN: + { + switch (auraSpellInfo->Id) + { + // Soul Preserver + case 60510: + { + switch (getClass()) + { + case CLASS_DRUID: + trigger_spell_id = 60512; + break; + case CLASS_PALADIN: + trigger_spell_id = 60513; + break; + case CLASS_PRIEST: + trigger_spell_id = 60514; + break; + case CLASS_SHAMAN: + trigger_spell_id = 60515; + break; + } + + target = this; + break; + } + case 37657: // Lightning Capacitor + case 54841: // Thunder Capacitor + case 67712: // Item - Coliseum 25 Normal Caster Trinket + case 67758: // Item - Coliseum 25 Heroic Caster Trinket + { + if (!victim || !victim->IsAlive() || GetTypeId() != TYPEID_PLAYER) + return false; + + uint32 stack_spell_id = 0; + switch (auraSpellInfo->Id) + { + case 37657: + stack_spell_id = 37658; + trigger_spell_id = 37661; + break; + case 54841: + stack_spell_id = 54842; + trigger_spell_id = 54843; + break; + case 67712: + stack_spell_id = 67713; + trigger_spell_id = 67714; + break; + case 67758: + stack_spell_id = 67759; + trigger_spell_id = 67760; + break; + } + + if (cooldown && GetTypeId() == TYPEID_PLAYER) + { + if (ToPlayer()->HasSpellCooldown(stack_spell_id)) + return false; + + ToPlayer()->AddSpellCooldown(stack_spell_id, 0, cooldown); + } + + CastSpell(this, stack_spell_id, true, nullptr, triggeredByAura); + + Aura* dummy = GetAura(stack_spell_id); + if (!dummy || dummy->GetStackAmount() < triggerAmount) + return false; + + RemoveAurasDueToSpell(stack_spell_id); + CastSpell(victim, trigger_spell_id, true, nullptr, triggeredByAura); + return true; + } + default: + // Illumination + if (auraSpellInfo->SpellIconID == 241) + { + if (!procSpell) + return false; + // procspell is triggered spell but we need mana cost of original casted spell + uint32 originalSpellId = procSpell->Id; + // Holy Shock heal + if (procSpell->SpellFamilyFlags[1] & 0x00010000) + { + switch (procSpell->Id) + { + case 25914: + originalSpellId = 20473; + break; + case 25913: + originalSpellId = 20929; + break; + case 25903: + originalSpellId = 20930; + break; + case 27175: + originalSpellId = 27174; + break; + case 33074: + originalSpellId = 33072; + break; + case 48820: + originalSpellId = 48824; + break; + case 48821: + originalSpellId = 48825; + break; + default: + LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} not handled in HShock", procSpell->Id); + return false; + } + } + SpellInfo const* originalSpell = sSpellMgr->GetSpellInfo(originalSpellId); + if (!originalSpell) + { + LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} unknown but selected as original in Illu", originalSpellId); + return false; + } + // percent stored in effect 1 (class scripts) base points + int32 cost = int32(originalSpell->ManaCost + CalculatePct(GetCreateMana(), originalSpell->ManaCostPercentage)); + basepoints0 = CalculatePct(cost, auraSpellInfo->Effects[1].CalcValue()); + trigger_spell_id = 20272; + target = this; + } + break; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + // Lightning Shield (overwrite non existing triggered spell call in spell.dbc + if (auraSpellInfo->SpellFamilyFlags[0] & 0x400) + { + // Do not proc off from self-casted items + if (Spell const* spell = eventInfo.GetProcSpell()) + { + if (spell->m_castItemGUID && victim->GetGUID() == GetGUID()) + { + return false; + } + } + + trigger_spell_id = sSpellMgr->GetSpellWithRank(26364, auraSpellInfo->GetRank()); + } + // Nature's Guardian + else if (auraSpellInfo->SpellIconID == 2013) + { + // Check health condition - should drop to less 30% (damage deal after this!) + if (!HealthBelowPctDamaged(30, damage)) + return false; + + if (victim && victim->IsAlive()) + victim->GetThreatMgr().ModifyThreatByPercent(this, -10); + + basepoints0 = int32(CountPctFromMaxHealth(triggerAmount)); + trigger_spell_id = 31616; + target = this; + } + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Acclimation + if (auraSpellInfo->SpellIconID == 1930) + { + if (!procSpell) + return false; + switch (GetFirstSchoolInMask(procSpell->GetSchoolMask())) + { + case SPELL_SCHOOL_NORMAL: + return false; // ignore + case SPELL_SCHOOL_HOLY: + trigger_spell_id = 50490; + break; + case SPELL_SCHOOL_FIRE: + trigger_spell_id = 50362; + break; + case SPELL_SCHOOL_NATURE: + trigger_spell_id = 50488; + break; + case SPELL_SCHOOL_FROST: + trigger_spell_id = 50485; + break; + case SPELL_SCHOOL_SHADOW: + trigger_spell_id = 50489; + break; + case SPELL_SCHOOL_ARCANE: + trigger_spell_id = 50486; + break; + default: + return false; + } + } + // Blood Presence (Improved) + else if (auraSpellInfo->Id == 63611) + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + trigger_spell_id = 50475; + basepoints0 = CalculatePct(int32(damage), triggerAmount); + } + break; + } + } + } + + // All ok. Check current trigger spell + SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(trigger_spell_id); + if (!triggerEntry) + { + // Don't cast unknown spell + LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell {} (effIndex: {}) has unknown TriggerSpell {}. Unhandled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex(), trigger_spell_id); + return false; + } + + // not allow proc extra attack spell at extra attack + if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + { + uint32 lastExtraAttackSpell = eventInfo.GetActor()->GetLastExtraAttackSpell(); + + // Patch 1.12.0(?) extra attack abilities can no longer chain proc themselves + if (lastExtraAttackSpell == trigger_spell_id) + { + return false; + } + + // Patch 2.2.0 Sword Specialization (Warrior, Rogue) extra attack can no longer proc additional extra attacks + // 3.3.5 Sword Specialization (Warrior), Hack and Slash (Rogue) + if (lastExtraAttackSpell == 16459 || lastExtraAttackSpell == 66923) + { + return false; + } + } + + // Custom requirements (not listed in procEx) Warning! damage dealing after this + // Custom triggered spells + switch (auraSpellInfo->Id) + { + // Deep Wounds + case 12834: + case 12849: + case 12867: + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + if (procFlags & PROC_FLAG_DONE_OFFHAND_ATTACK) + basepoints0 = int32((GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE)) / 2.0f); + else + basepoints0 = int32((GetFloatValue(UNIT_FIELD_MAXDAMAGE) + GetFloatValue(UNIT_FIELD_MINDAMAGE)) / 2.0f); + break; + } + // Persistent Shield (Scarab Brooch trinket) + // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect) + case 26467: + { + basepoints0 = int32(CalculatePct(damage, 15)); + target = victim; + trigger_spell_id = 26470; + break; + } + // Unyielding Knights (item exploit 29108\29109) + case 38164: + { + if (!victim || victim->GetEntry() != 19457) // Proc only if your target is Grillok + return false; + break; + } + // Deflection + case 52420: + { + if (!HealthBelowPct(35)) + return false; + break; + } + + // Cheat Death + case 28845: + { + // When your health drops below 20% + if (HealthBelowPctDamaged(20, damage) || HealthBelowPct(20)) + return false; + break; + } + // Deadly Swiftness (Rank 1) + case 31255: + { + // whenever you deal damage to a target who is below 20% health. + if (!victim || !victim->IsAlive() || victim->HealthAbovePct(20)) + return false; + + target = this; + trigger_spell_id = 22588; + [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked. + } + // Bonus Healing (Crystal Spire of Karabor mace) + case 40971: + { + // If your target is below $s1% health + if (!victim || !victim->IsAlive() || victim->HealthAbovePct(triggerAmount)) + return false; + break; + } + // Rapid Recuperation + case 53228: + case 53232: + { + // This effect only from Rapid Fire (ability cast) + if (!procSpell || !(procSpell->SpellFamilyFlags[0] & 0x20)) + return false; + break; + } + // Decimation + case 63156: + case 63158: + // Can proc only if target has hp below 35% + if (!victim || !victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, procSpell, this)) + return false; + break; + // Ulduar, Hodir, Toasty Fire + case 62821: + if (this->GetTypeId() != TYPEID_PLAYER) // spell has Attribute, but persistent area auras ignore it + return false; + break; + case 15337: // Improved Spirit Tap (Rank 1) + case 15338: // Improved Spirit Tap (Rank 2) + { + if (!procSpell) + return false; + + if (procSpell->SpellFamilyFlags[0] & 0x800000) + if ((procSpell->Id != 58381) || !roll_chance_i(50)) + return false; + + target = victim; + break; + } + // Professor Putricide - Ooze Spell Tank Protection + case 71770: + if (victim) + victim->CastSpell(victim, trigger_spell_id, true); // EffectImplicitTarget is self + return true; + case 45057: // Evasive Maneuvers (Commendation of Kael`thas trinket) + case 71634: // Item - Icecrown 25 Normal Tank Trinket 1 + case 71640: // Item - Icecrown 25 Heroic Tank Trinket 1 + case 75475: // Item - Chamber of Aspects 25 Normal Tank Trinket + case 75481: // Item - Chamber of Aspects 25 Heroic Tank Trinket + { + // Procs only if damage takes health below $s1% + if (!HealthBelowPctDamaged(triggerAmount, damage)) + return false; + break; + } + default: + break; + } + + if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT) + { + // Xinef: keep this order, Aura 70656 has SpellIconID 85! + // Item - Death Knight T10 Melee 4P Bonus + if (auraSpellInfo->Id == 70656) + { + if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT) + return false; + + for (uint8 i = 0; i < MAX_RUNES; ++i) + if (ToPlayer()->GetRuneCooldown(i) == 0) + return false; + } + // Blade Barrier + else if (auraSpellInfo->SpellIconID == 85) + { + Player* plr = ToPlayer(); + if (!plr || plr->getClass() != CLASS_DEATH_KNIGHT || !procSpell) + return false; + + if (!plr->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) + return false; + } + // Rime + else if (auraSpellInfo->SpellIconID == 56) + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + // Howling Blast + ToPlayer()->RemoveCategoryCooldown(1248); + } + } + + // Custom basepoints/target for exist spell + // dummy basepoints or other customs + switch (trigger_spell_id) + { + // Auras which should proc on area aura source (caster in this case): + // Turn the Tables + case 52914: + case 52915: + case 52910: + // Honor Among Thieves + case 51699: + { + target = triggeredByAura->GetBase()->GetCaster(); + if (!target) + return false; + + if (Player* pTarget = target->ToPlayer()) + { + if (cooldown) + { + if (pTarget->HasSpellCooldown(trigger_spell_id) ) + return false; + pTarget->AddSpellCooldown(trigger_spell_id, 0, cooldown); + } + + Unit* cptarget = nullptr; + if (trigger_spell_id == 51699) + { + cptarget = pTarget->GetComboTarget(); + if (!cptarget) + { + cptarget = pTarget->GetSelectedUnit(); + } + } + else + cptarget = target; + + if (cptarget) + { + target->CastSpell(cptarget, trigger_spell_id, true); + return true; + } + } + return false; + } + // Cast positive spell on enemy target + case 7099: // Curse of Mending + case 39703: // Curse of Mending + case 29494: // Temptation + case 20233: // Improved Lay on Hands (cast on target) + { + target = victim; + break; + } + // Ruby Drake, Evasive Aura + case 50241: + { + if( GetAura(50240) ) + return false; + + break; + } + // Combo points add triggers (need add combopoint only for main target, and after possible combopoints reset) + case 15250: // Rogue Setup + { + // applied only for main target + if (!victim || (GetTypeId() == TYPEID_PLAYER && victim != ToPlayer()->GetSelectedUnit())) + return false; + break; // continue normal case + } + // Finish movies that add combo + case 14189: // Seal Fate (Netherblade set) + case 14157: // Ruthlessness + { + victim = nullptr; + // Need add combopoint AFTER finish movie (or they dropped in finish phase) + break; + } + // Item - Druid T10 Balance 2P Bonus + case 16870: + { + if (HasAura(70718)) + CastSpell(this, 70721, true); + RemoveAurasDueToSpell(trigger_spell_id); + break; + } + // Shamanistic Rage triggered spell + case 30824: + { + basepoints0 = int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), triggerAmount)); + break; + } + // Enlightenment (trigger only from mana cost spells) + case 35095: + { + if (!procSpell || procSpell->PowerType != POWER_MANA || (procSpell->ManaCost == 0 && procSpell->ManaCostPercentage == 0 && procSpell->ManaCostPerlevel == 0)) + return false; + break; + } + // Demonic Pact + case 48090: + { + // Get talent aura from owner + if (IsPet()) + if (Unit* owner = GetOwner()) + { + if (HasSpellCooldown(trigger_spell_id)) + return false; + AddSpellCooldown(trigger_spell_id, 0, cooldown); + + if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 3220, 0)) + { + int32 spellPower = owner->SpellBaseDamageBonusDone(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)); + if (AuraEffect const* demonicAuraEffect = GetAuraEffect(trigger_spell_id, EFFECT_0)) + spellPower -= demonicAuraEffect->GetAmount(); + + basepoints0 = int32((aurEff->GetAmount() * spellPower + 100.0f) / 100.0f); + CastCustomSpell(this, trigger_spell_id, &basepoints0, &basepoints0, nullptr, true, castItem, triggeredByAura); + return true; + } + } + break; + } + case 46916: // Slam! (Bloodsurge proc) + case 52437: // Sudden Death + { + // Item - Warrior T10 Melee 4P Bonus + if (AuraEffect const* aurEff = GetAuraEffect(70847, 0)) + { + if (!roll_chance_i(aurEff->GetAmount())) + { + // Xinef: dont allow normal proc to override set one + if (GetAura((trigger_spell_id == 46916) ? 71072 : 71069)) + return false; + // Xinef: just to be sure + RemoveAurasDueToSpell(70849); + break; + } + + // Xinef: fully remove all auras and reapply once more + RemoveAurasDueToSpell(70849); + RemoveAurasDueToSpell(71072); + RemoveAurasDueToSpell(71069); + + CastSpell(this, 70849, true, castItem, triggeredByAura); // Extra Charge! + if (trigger_spell_id == 46916) + CastSpell(this, 71072, true, castItem, triggeredByAura); // Slam GCD Reduced + else + CastSpell(this, 71069, true, castItem, triggeredByAura); // Execute GCD Reduced + } + break; + } + // Sword and Board + case 50227: + { + // Remove cooldown on Shield Slam + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->RemoveCategoryCooldown(1209); + break; + } + // Maelstrom Weapon + case 53817: + { + // have rank dependent proc chance, ignore too often cases + // PPM = 2.5 * (rank of talent), + uint32 rank = auraSpellInfo->GetRank(); + // 5 rank -> 100% 4 rank -> 80% and etc from full rate + if (!roll_chance_i(20 * rank)) + return false; + + // Item - Shaman T10 Enhancement 4P Bonus + if (AuraEffect const* aurEff = GetAuraEffect(70832, 0)) + if (Aura const* maelstrom = GetAura(53817)) + // xinef: we have 4 charges and all proc conditions are met - aura reaches 5 charges + if ((maelstrom->GetStackAmount() == 4) && roll_chance_i(aurEff->GetAmount())) + CastSpell(this, 70831, true, castItem, triggeredByAura); + + break; + } + // Astral Shift + case 52179: + { + if (!procSpell || !(procEx & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) || this == victim) + return false; + + // Need stun, fear or silence mechanic + if (!(procSpell->GetAllEffectsMechanicMask() & ((1 << MECHANIC_SILENCE) | (1 << MECHANIC_STUN) | (1 << MECHANIC_FEAR)))) + return false; + break; + } + // Glyph of Death's Embrace + case 58679: + { + // Proc only from healing part of Death Coil. Check is essential as all Death Coil spells have 0x2000 mask in SpellFamilyFlags + if (!procSpell || !(procSpell->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && procSpell->SpellFamilyFlags[0] == 0x80002000)) + return false; + break; + } + // Glyph of Death Grip + case 58628: + { + // remove cooldown of Death Grip + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->RemoveSpellCooldown(49576, true); + return true; + } + // Savage Defense + case 62606: + { + basepoints0 = CalculatePct(triggerAmount, GetTotalAttackPowerValue(BASE_ATTACK)); + break; + } + // Body and Soul + case 64128: + case 65081: + { + // Proc only from PW:S cast + if (!procSpell || !(procSpell->SpellFamilyFlags[0] & 0x00000001)) + return false; + break; + } + // Culling the Herd + case 70893: + { + if (!procSpell) + { + return false; + } + // check if we're doing a critical hit + if (!(procSpell->SpellFamilyFlags[1] & 0x10000000) && (procEx != PROC_EX_CRITICAL_HIT)) + return false; + // check if we're procced by Claw, Bite or Smack (need to use the spell icon ID to detect it) + if (!(procSpell->SpellIconID == 262 || procSpell->SpellIconID == 1680 || procSpell->SpellIconID == 473)) + return false; + break; + } + // Fingers of Frost, synchronise with Frostbite + case 44544: + { + if (procPhase == PROC_SPELL_PHASE_HIT) + { + // Find Frostbite + if (AuraEffect* aurEff = this->GetAuraEffect(SPELL_AURA_ADD_TARGET_TRIGGER, SPELLFAMILY_MAGE, 119, EFFECT_0)) + { + if (!victim) + return false; + + uint8 fofRank = sSpellMgr->GetSpellRank(triggeredByAura->GetId()); + uint8 fbRank = sSpellMgr->GetSpellRank(aurEff->GetId()); + uint8 chance = uint8(std::ceil(fofRank * fbRank * 16.6f)); + + if (roll_chance_i(chance)) + CastSpell(victim, aurEff->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true); + } + } + break; + } + } + + // try detect target manually if not set + if (!target) + target = !(procFlags & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry->IsPositive() ? this : victim; + + if (cooldown) + { + if (HasSpellCooldown(triggerEntry->Id)) + return false; + + AddSpellCooldown(triggerEntry->Id, 0, cooldown); + } + + if(basepoints0) + CastCustomSpell(target, triggerEntry->Id, &basepoints0, nullptr, nullptr, true, castItem, triggeredByAura); + else + CastSpell(target, triggerEntry->Id, true, castItem, triggeredByAura); + + return true; +} + +bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown) +{ + int32 scriptId = triggeredByAura->GetMiscValue(); + + if (!victim || !victim->IsAlive()) + return false; + + Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER + ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : nullptr; + + uint32 triggered_spell_id = 0; + + switch (scriptId) + { + case 836: // Improved Blizzard (Rank 1) + { + if (!procSpell || procSpell->SpellVisual[0] != 9487) + return false; + triggered_spell_id = 12484; + break; + } + case 988: // Improved Blizzard (Rank 2) + { + if (!procSpell || procSpell->SpellVisual[0] != 9487) + return false; + triggered_spell_id = 12485; + break; + } + case 989: // Improved Blizzard (Rank 3) + { + if (!procSpell || procSpell->SpellVisual[0] != 9487) + return false; + triggered_spell_id = 12486; + break; + } + case 4533: // Dreamwalker Raiment 2 pieces bonus + { + // Chance 50% + if (!roll_chance_i(50)) + return false; + + switch (victim->getPowerType()) + { + case POWER_MANA: + triggered_spell_id = 28722; + break; + case POWER_RAGE: + triggered_spell_id = 28723; + break; + case POWER_ENERGY: + triggered_spell_id = 28724; + break; + default: + return false; + } + break; + } + case 4537: // Dreamwalker Raiment 6 pieces bonus + triggered_spell_id = 28750; // Blessing of the Claw + break; + case 5497: // Improved Mana Gems + triggered_spell_id = 37445; // Mana Surge + break; + case 7010: // Revitalize - can proc on full hp target + case 7011: + case 7012: + { + if (!roll_chance_i(triggeredByAura->GetAmount())) + return false; + switch (victim->getPowerType()) + { + case POWER_MANA: + triggered_spell_id = 48542; + break; + case POWER_RAGE: + triggered_spell_id = 48541; + break; + case POWER_ENERGY: + triggered_spell_id = 48540; + break; + case POWER_RUNIC_POWER: + triggered_spell_id = 48543; + break; + default: + break; + } + break; + } + default: + break; + } + + // not processed + if (!triggered_spell_id) + return false; + + // standard non-dummy case + SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(triggered_spell_id); + + if (!triggerEntry) + { + LOG_ERROR("entities.unit", "Unit::HandleOverrideClassScriptAuraProc: Spell {} triggering for class script id {}", triggered_spell_id, scriptId); + return false; + } + + if (cooldown) + { + if (HasSpellCooldown(triggered_spell_id)) + return false; + + AddSpellCooldown(triggered_spell_id, 0, cooldown); + } + + CastSpell(victim, triggered_spell_id, true, castItem, triggeredByAura); + + return true; +} + void Unit::setPowerType(Powers new_powertype) { SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype); @@ -6230,7 +9660,7 @@ void Unit::setPowerType(Powers new_powertype) break; } - if (const Player* player = ToPlayer()) + if (Player const* player = ToPlayer()) if (player->NeedSendSpectatorData()) { ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "PWT", new_powertype); @@ -6335,7 +9765,7 @@ ReputationRank Unit::GetReactionTo(Unit const* target, bool checkOriginalFaction { // check contested flags if (targetFactionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS - && selfPlayerOwner->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP)) + && selfPlayerOwner->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP)) return REP_HOSTILE; // if faction has reputation, hostile state depends only from AtWar state @@ -6408,7 +9838,7 @@ ReputationRank Unit::GetFactionReactionTo(FactionTemplateEntry const* factionTem { // check contested flags if (factionTemplateEntry->factionFlags & FACTION_TEMPLATE_FLAG_ATTACK_PVP_ACTIVE_PLAYERS - && targetPlayerOwner->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP)) + && targetPlayerOwner->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP)) return REP_HOSTILE; if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(factionTemplateEntry)) return *repRank; @@ -6750,8 +10180,8 @@ bool Unit::HasAuraState(AuraStateType flag, SpellInfo const* spellProto, Unit co if (spellProto) { AuraEffectList const& stateAuras = Caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE); - for (AuraEffect const* aurEff : stateAuras) - if (aurEff->IsAffectedOnSpell(spellProto)) + for (AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j) + if ((*j)->IsAffectedOnSpell(spellProto)) return true; } // Check per caster aura state @@ -7147,12 +10577,9 @@ void Unit::SetCharm(Unit* charm, bool apply) } } -void Unit::DealHeal(HealInfo& healInfo) +int32 Unit::DealHeal(Unit* healer, Unit* victim, uint32 addhealth) { int32 gain = 0; - Unit* victim = healInfo.GetTarget(); - Unit* healer = healInfo.GetHealer(); - uint32 addhealth = healInfo.GetHeal(); if (healer) { @@ -7175,7 +10602,7 @@ void Unit::DealHeal(HealInfo& healInfo) unit = healer->GetOwner(); if (!unit) - return; + return gain; if (Player* player = unit->ToPlayer()) { @@ -7195,10 +10622,7 @@ void Unit::DealHeal(HealInfo& healInfo) //player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED, addhealth); // pussywizard: optimization }*/ - if (gain) - { - healInfo.SetEffectiveHeal(gain > 0 ? static_cast<uint32>(gain) : 0UL); - } + return gain; } bool RedirectSpellEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) @@ -7429,16 +10853,16 @@ void Unit::UnsummonAllTotems(bool onDeath /*= false*/) } } -void Unit::SendHealSpellLog(HealInfo& healInfo, bool critical /*= false*/) +void Unit::SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical) { // we guess size WorldPacket data(SMSG_SPELLHEALLOG, (8 + 8 + 4 + 4 + 4 + 4 + 1 + 1)); - data << healInfo.GetTarget()->GetPackGUID(); - data << healInfo.GetHealer()->GetPackGUID(); - data << uint32(healInfo.GetSpellInfo()->Id); - data << uint32(healInfo.GetHeal()); - data << uint32(healInfo.GetHeal() - healInfo.GetEffectiveHeal()); - data << uint32(healInfo.GetAbsorb()); // Absorb amount + data << victim->GetPackGUID(); + data << GetPackGUID(); + data << uint32(SpellID); + data << uint32(Damage); + data << uint32(OverHeal); + data << uint32(Absorb); // Absorb amount data << uint8(critical ? 1 : 0); data << uint8(0); // unused SendMessageToSet(&data, true); @@ -7453,9 +10877,9 @@ int32 Unit::HealBySpell(HealInfo& healInfo, bool critical) // calculate heal absorb and reduce healing CalcHealAbsorb(healInfo); - DealHeal(healInfo); - SendHealSpellLog(healInfo, critical); - return healInfo.GetEffectiveHeal(); + int32 gain = Unit::DealHeal(healInfo.GetHealer(), healInfo.GetTarget(), healInfo.GetHeal()); + SendHealSpellLog(healInfo.GetTarget(), healInfo.GetSpellInfo()->Id, healInfo.GetHeal(), uint32(healInfo.GetHeal() - gain), healInfo.GetAbsorb(), critical); + return gain; } void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellID, uint32 damage, Powers powerType) @@ -7471,15 +10895,15 @@ void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellID, uint32 damage, Pow void Unit::EnergizeBySpell(Unit* victim, uint32 spellID, uint32 damage, Powers powerType) { - SendEnergizeSpellLog(victim, spellID, damage, powerType); - // needs to be called after sending spell log - victim->ModifyPower(powerType, damage); + victim->ModifyPower(powerType, damage, false); if (powerType != POWER_HAPPINESS) { SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID); victim->getHostileRefMgr().threatAssist(this, float(damage) * 0.5f, spellInfo); } + + SendEnergizeSpellLog(victim, spellID, damage, powerType); } float Unit::SpellPctDamageModsDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) @@ -7941,7 +11365,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } @@ -7951,16 +11375,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin float tmpDamage = (float(pdamage) + DoneTotal) * DoneTotalMod; // apply spellmod to Done damage (flat and pct) if (Player* modOwner = GetSpellModOwner()) - { - if (damagetype == DOT) - { - modOwner->ApplySpellMod<SPELLMOD_DOT>(spellProto->Id, tmpDamage); - } - else - { - modOwner->ApplySpellMod<SPELLMOD_DAMAGE>(spellProto->Id, tmpDamage); - } - } + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage); return uint32(std::max(tmpDamage, 0.0f)); } @@ -8237,7 +11652,7 @@ float Unit::SpellDoneCritChance(Unit const* /*victim*/, SpellInfo const* spellPr // percent done // only players use intelligence for critical chance computations if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRITICAL_CHANCE>(spellProto->Id, crit_chance); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance); // xinef: can be negative! return crit_chance; @@ -8487,7 +11902,7 @@ uint32 Unit::SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spell // adds additional damage to critBonus (from talents) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRIT_DAMAGE_BONUS>(spellProto->Id, crit_bonus); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); crit_bonus += damage; } @@ -8522,7 +11937,7 @@ uint32 Unit::SpellCriticalHealingBonus(Unit const* caster, SpellInfo const* spel // adds additional damage to critBonus (from talents) // xinef: used for death knight death coil if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRIT_DAMAGE_BONUS>(spellProto->Id, crit_bonus); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); } if (crit_bonus > 0) @@ -8707,7 +12122,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); @@ -8732,16 +12147,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui // apply spellmod to Done amount if (Player* modOwner = GetSpellModOwner()) - { - if (damagetype == DOT) - { - modOwner->ApplySpellMod<SPELLMOD_DOT>(spellProto->Id, heal); - } - else - { - modOwner->ApplySpellMod<SPELLMOD_DAMAGE>(spellProto->Id, heal); - } - } + modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); return uint32(std::max(heal, 0.0f)); } @@ -8837,7 +12243,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } @@ -9344,7 +12750,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType // apply spellmod to Done damage if (spellProto) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DAMAGE>(spellProto->Id, tmpDamage); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); // bonus result can be negative return uint32(std::max(tmpDamage, 0.0f)); @@ -9534,7 +12940,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spe // Apply chance modifer aura if (spellProto) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_PROC_PER_MINUTE>(spellProto->Id, PPM); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_PROC_PER_MINUTE, PPM); return floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60)) } @@ -9961,7 +13367,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo // can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit. //Ignore stealth if target is player and unit in combat with same player - if (GetEntry() != WORLD_TRIGGER && (!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target))))) + if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, (bySpell && bySpell->IsAffectingArea()) || (target->GetTypeId() == TYPEID_PLAYER && target->HasStealthAura() && target->IsInCombat() && IsInCombatWith(target))))) return false; // can't attack dead @@ -10209,7 +13615,7 @@ int32 Unit::GetHealthGain(int32 dVal) } // returns negative amount on power reduction -int32 Unit::ModifyPower(Powers power, int32 dVal) +int32 Unit::ModifyPower(Powers power, int32 dVal, bool withPowerUpdate /*= true*/) { if (dVal == 0) return 0; @@ -10221,7 +13627,7 @@ int32 Unit::ModifyPower(Powers power, int32 dVal) int32 val = dVal + curPower; if (val <= 0) { - SetPower(power, 0); + SetPower(power, 0, withPowerUpdate); return -curPower; } @@ -10229,12 +13635,12 @@ int32 Unit::ModifyPower(Powers power, int32 dVal) if (val < maxPower) { - SetPower(power, val); + SetPower(power, val, withPowerUpdate); gain = val - curPower; } else if (curPower != maxPower) { - SetPower(power, maxPower); + SetPower(power, maxPower, withPowerUpdate); gain = maxPower - curPower; } @@ -10860,17 +14266,17 @@ float Unit::ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index { if (Player* modOwner = GetSpellModOwner()) { - modOwner->ApplySpellMod<SPELLMOD_ALL_EFFECTS>(spellProto->Id, value); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_ALL_EFFECTS, value); switch (effect_index) { - case EFFECT_0: - modOwner->ApplySpellMod<SPELLMOD_EFFECT1>(spellProto->Id, value); + case 0: + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT1, value); break; - case EFFECT_1: - modOwner->ApplySpellMod<SPELLMOD_EFFECT2>(spellProto->Id, value); + case 1: + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT2, value); break; - case EFFECT_2: - modOwner->ApplySpellMod<SPELLMOD_EFFECT3>(spellProto->Id, value); + case 2: + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT3, value); break; } } @@ -11011,7 +14417,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32& castTime, Spell* // called from caster if (Player* modOwner = GetSpellModOwner()) // TODO:(MadAgos) Eventually check and delete the bool argument - modOwner->ApplySpellMod<SPELLMOD_CASTING_TIME>(spellInfo->Id, castTime, spell); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell, bool(modOwner != this && !IsPet())); switch (spellInfo->DmgClass) { @@ -11593,7 +14999,7 @@ void Unit::SetMaxHealth(uint32 val) SetHealth(val); } -void Unit::SetPower(Powers power, uint32 val) +void Unit::SetPower(Powers power, uint32 val, bool withPowerUpdate /*= true*/) { if (GetPower(power) == val) return; @@ -11604,11 +15010,14 @@ void Unit::SetPower(Powers power, uint32 val) SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power, val); - WorldPacket data(SMSG_POWER_UPDATE); - data << GetPackGUID(); - data << uint8(power); - data << uint32(val); - SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER); + if (withPowerUpdate) + { + WorldPacket data(SMSG_POWER_UPDATE); + data << GetPackGUID(); + data << uint8(power); + data << uint32(val); + SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER); + } // group update if (GetTypeId() == TYPEID_PLAYER) @@ -12099,6 +15508,92 @@ bool Unit::isFrozen() const return HasAuraState(AURA_STATE_FROZEN); } +struct ProcTriggeredData +{ + ProcTriggeredData(Aura* _aura) : aura(_aura) + { + effMask = 0; + spellProcEvent = nullptr; + triggerSpelId.fill(0); + } + + SpellProcEventEntry const* spellProcEvent; + Aura* aura; + uint32 effMask; + std::array<uint32, EFFECT_ALL> triggerSpelId; + + bool operator==(const uint32 spellId) const + { + return aura->GetId() == spellId; + } +}; + +typedef std::list< ProcTriggeredData > ProcTriggeredList; + +// List of auras that CAN be trigger but may not exist in spell_proc_event +// in most case need for drop charges +// in some types of aura need do additional check +// for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic +bool InitTriggerAuraData() +{ + for (uint16 i = 0; i < TOTAL_AURAS; ++i) + { + isTriggerAura[i] = false; + isNonTriggerAura[i] = false; + isAlwaysTriggeredAura[i] = false; + } + isTriggerAura[SPELL_AURA_DUMMY] = true; + isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true; + isTriggerAura[SPELL_AURA_MOD_THREAT] = true; + isTriggerAura[SPELL_AURA_MOD_STUN] = true; // Aura does not have charges but needs to be removed on trigger + isTriggerAura[SPELL_AURA_MOD_DAMAGE_DONE] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_TAKEN] = true; + isTriggerAura[SPELL_AURA_MOD_RESISTANCE] = true; + isTriggerAura[SPELL_AURA_MOD_STEALTH] = true; + isTriggerAura[SPELL_AURA_MOD_FEAR] = true; // Aura does not have charges but needs to be removed on trigger + isTriggerAura[SPELL_AURA_MOD_ROOT] = true; + isTriggerAura[SPELL_AURA_TRANSFORM] = true; + isTriggerAura[SPELL_AURA_REFLECT_SPELLS] = true; + isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true; + isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true; + isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true; + isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true; + isTriggerAura[SPELL_AURA_SCHOOL_ABSORB] = true; // Savage Defense untested + isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true; + isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true; + isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true; + isTriggerAura[SPELL_AURA_MECHANIC_IMMUNITY] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN] = true; + isTriggerAura[SPELL_AURA_SPELL_MAGNET] = true; + isTriggerAura[SPELL_AURA_MOD_ATTACK_POWER] = true; + isTriggerAura[SPELL_AURA_ADD_CASTER_HIT_TRIGGER] = true; + isTriggerAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; + isTriggerAura[SPELL_AURA_MOD_MECHANIC_RESISTANCE] = true; + isTriggerAura[SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS] = true; + isTriggerAura[SPELL_AURA_MOD_MELEE_HASTE] = true; + isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE] = true; + isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE] = true; + isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE] = true; + isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true; + isTriggerAura[SPELL_AURA_MOD_SPELL_CRIT_CHANCE] = true; + isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true; + + isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN] = true; + isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK] = true; + + isAlwaysTriggeredAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_FEAR] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_ROOT] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_STUN] = true; + isAlwaysTriggeredAura[SPELL_AURA_TRANSFORM] = true; + isAlwaysTriggeredAura[SPELL_AURA_SPELL_MAGNET] = true; + isAlwaysTriggeredAura[SPELL_AURA_SCHOOL_ABSORB] = true; + isAlwaysTriggeredAura[SPELL_AURA_MOD_STEALTH] = true; + + return true; +} + void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim) { if (spellInfo) @@ -12173,88 +15668,73 @@ void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bo } } -uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition) +uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition) { - uint32 hitMask = PROC_HIT_NONE; + uint32 procEx = PROC_EX_NONE; // Check victim state if (missCondition != SPELL_MISS_NONE) - { switch (missCondition) { case SPELL_MISS_MISS: - hitMask |= PROC_HIT_MISS; + procEx |= PROC_EX_MISS; + break; + case SPELL_MISS_RESIST: + procEx |= PROC_EX_RESIST; break; case SPELL_MISS_DODGE: - hitMask |= PROC_HIT_DODGE; + procEx |= PROC_EX_DODGE; break; case SPELL_MISS_PARRY: - hitMask |= PROC_HIT_PARRY; + procEx |= PROC_EX_PARRY; break; case SPELL_MISS_BLOCK: - // spells can't be partially blocked (it's damage can though) - hitMask |= PROC_HIT_BLOCK | PROC_HIT_FULL_BLOCK; + procEx |= PROC_EX_BLOCK; break; case SPELL_MISS_EVADE: - hitMask |= PROC_HIT_EVADE; + procEx |= PROC_EX_EVADE; break; case SPELL_MISS_IMMUNE: + procEx |= PROC_EX_IMMUNE; + break; case SPELL_MISS_IMMUNE2: - hitMask |= PROC_HIT_IMMUNE; + procEx |= PROC_EX_IMMUNE; break; case SPELL_MISS_DEFLECT: - hitMask |= PROC_HIT_DEFLECT; + procEx |= PROC_EX_DEFLECT; break; case SPELL_MISS_ABSORB: - hitMask |= PROC_HIT_ABSORB; + procEx |= PROC_EX_ABSORB; break; case SPELL_MISS_REFLECT: - hitMask |= PROC_HIT_REFLECT; - break; - case SPELL_MISS_RESIST: - hitMask |= PROC_HIT_FULL_RESIST; + procEx |= PROC_EX_REFLECT; break; default: break; } - } else { // On block if (damageInfo->blocked) - { - hitMask |= PROC_HIT_BLOCK; - if (damageInfo->fullBlock) - hitMask |= PROC_HIT_FULL_BLOCK; - } + procEx |= PROC_EX_BLOCK; // On absorb if (damageInfo->absorb) - hitMask |= PROC_HIT_ABSORB; - - // Don't set hit/crit hitMask if damage is nullified - bool const damageNullified = (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_FULL_RESIST)) != 0 || (hitMask & PROC_HIT_FULL_BLOCK) != 0; - if (!damageNullified) - { - // On crit - if (damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT) - hitMask |= PROC_HIT_CRITICAL; - else - hitMask |= PROC_HIT_NORMAL; - } - else if ((damageInfo->HitInfo & HITINFO_FULL_RESIST) != 0) - hitMask |= PROC_HIT_FULL_RESIST; + procEx |= PROC_EX_ABSORB; + // On crit + if (damageInfo->HitInfo & SPELL_HIT_TYPE_CRIT) + procEx |= PROC_EX_CRITICAL_HIT; + else + procEx |= PROC_EX_NORMAL_HIT; } - - return hitMask; + return procEx; } -void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMask, uint32 hitMask, WeaponAttackType attType) +void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura, int8 procAuraEffectIndex, Spell const* procSpell, DamageInfo* damageInfo, HealInfo* healInfo, uint32 procPhase) { // Player is loaded now - do not allow passive spell casts to proc if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetSession()->PlayerLoading()) return; - // For melee/ranged based attack need update skills and set some Aura states if victim present - if (typeMask & MELEE_BASED_TRIGGER_MASK && procTarget) + if (procFlag & MELEE_BASED_TRIGGER_MASK && target && procPhase == PROC_SPELL_PHASE_HIT) { // Xinef: Shaman in ghost wolf form cant proc anything melee based if (!isVictim && GetShapeshiftForm() == FORM_GHOSTWOLF) @@ -12262,30 +15742,27 @@ void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMa // Update skills here for players // only when you are not fighting other players or their pets/totems (pvp) - if (GetTypeId() == TYPEID_PLAYER && - procTarget->GetTypeId() != TYPEID_PLAYER && - !(procTarget->IsTotem() && procTarget->ToTotem()->GetOwner()->IsPlayer()) && - !procTarget->IsPet() - ) + if (IsPlayer() && !target->IsCharmedOwnedByPlayerOrPlayer()) { // On melee based hit/miss/resist/parry/dodge need to update skill (for victim and attacker) - if (hitMask & (PROC_HIT_NORMAL | PROC_HIT_MISS | PROC_HIT_FULL_RESIST)) + if (procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_MISS | PROC_EX_RESIST | PROC_EX_PARRY | PROC_EX_DODGE)) + { + ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr); + } + // Update defence if player is victim and we block - TODO: confirm that blocked attacks only have a chance to increase defence skill + else if (isVictim && procExtra & (PROC_EX_BLOCK)) { - if (procTarget->GetTypeId() != TYPEID_PLAYER && !procTarget->IsCritter()) - ToPlayer()->UpdateCombatSkills(procTarget, attType, isVictim); + ToPlayer()->UpdateCombatSkills(target, attType, true); } - // Update defence if player is victim and we block - else if (isVictim && (hitMask & (PROC_HIT_DODGE | PROC_HIT_PARRY | PROC_HIT_BLOCK))) - ToPlayer()->UpdateCombatSkills(procTarget, attType, true); } // If exist crit/parry/dodge/block need update aura state (for victim and attacker) - if (hitMask & (PROC_HIT_CRITICAL | PROC_HIT_PARRY | PROC_HIT_DODGE | PROC_HIT_BLOCK)) + if (procExtra & (PROC_EX_CRITICAL_HIT | PROC_EX_PARRY | PROC_EX_DODGE | PROC_EX_BLOCK)) { // for victim if (isVictim) { // if victim and dodge attack - if (hitMask & PROC_HIT_DODGE) + if (procExtra & PROC_EX_DODGE) { // Update AURA_STATE on dodge if (getClass() != CLASS_ROGUE) // skip Rogue Riposte @@ -12295,7 +15772,7 @@ void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMa } } // if victim and parry attack - if (hitMask & PROC_HIT_PARRY) + if (procExtra & PROC_EX_PARRY) { // For Hunters only Counterattack (skip Mongoose bite) if (getClass() == CLASS_HUNTER) @@ -12310,7 +15787,7 @@ void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMa } } // if and victim block attack - if (hitMask & PROC_HIT_BLOCK) + if (procExtra & PROC_EX_BLOCK) { ModifyAuraState(AURA_STATE_DEFENSE, true); StartReactiveTimer(REACTIVE_DEFENSE); @@ -12319,38 +15796,416 @@ void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMa else // For attacker { // Overpower on victim dodge - if (hitMask & PROC_HIT_DODGE && GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) + if (procExtra & PROC_EX_DODGE) { - AddComboPoints(procTarget, 1); - StartReactiveTimer(REACTIVE_OVERPOWER); + if (getClass() == CLASS_WARRIOR) + { + AddComboPoints(target, 1); + StartReactiveTimer(REACTIVE_OVERPOWER); + } } // Wolverine Bite - if ((hitMask & PROC_HIT_CRITICAL) && IsHunterPet()) + if ((procExtra & PROC_HIT_CRITICAL) && IsHunterPet()) { - AddComboPoints(procTarget, 1); + AddComboPoints(target, 1); StartReactiveTimer(REACTIVE_WOLVERINE_BITE); } } } } + + Unit* actor = isVictim ? target : this; + Unit* actionTarget = !isVictim ? target : this; + + ProcEventInfo eventInfo = ProcEventInfo(actor, actionTarget, target, procFlag, 0, procPhase, procExtra, procSpell, damageInfo, healInfo, procAura, procAuraEffectIndex); + + ProcTriggeredList procTriggered; + // Fill procTriggered list + for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr) + { + // Do not allow auras to proc from effect triggered by itself + if (procAura && procAura->Id == itr->first) + continue; + + // Xinef: Generic Item Equipment cooldown, -1 is a special marker + if (itr->second->GetBase()->GetCastItemGUID() && HasSpellItemCooldown(itr->first, uint32(-1))) + continue; + + ProcTriggeredData triggerData(itr->second->GetBase()); + // Defensive procs are active on absorbs (so absorption effects are not a hindrance) + bool active = damage || (procExtra & PROC_EX_BLOCK && isVictim); + if (isVictim) + procExtra &= ~PROC_EX_INTERNAL_REQ_FAMILY; + + SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo(); + + // only auras that have trigger spell should proc from fully absorbed damage + if (procExtra & PROC_EX_ABSORB && isVictim) + if (damage || spellProto->Effects[EFFECT_0].TriggerSpell || spellProto->Effects[EFFECT_1].TriggerSpell || spellProto->Effects[EFFECT_2].TriggerSpell) + active = true; + + // xinef: fix spell procing from damaging / healing casts if spell has DoT / HoT effect only + // only player spells are taken into account + if (!active && !isVictim && !(procFlag & PROC_FLAG_DONE_PERIODIC) && procSpellInfo && procSpellInfo->SpellFamilyName && (procSpellInfo->HasAura(SPELL_AURA_PERIODIC_DAMAGE) || procSpellInfo->HasAura(SPELL_AURA_PERIODIC_HEAL))) + active = true; + + // AuraScript Hook + if (!triggerData.aura->CallScriptCheckProcHandlers(itr->second, eventInfo)) + { + continue; + } + + bool isTriggeredAtSpellProcEvent = IsTriggeredAtSpellProcEvent(target, triggerData.aura, attType, isVictim, active, triggerData.spellProcEvent, eventInfo); + + // AuraScript Hook + triggerData.aura->CallScriptCheckAfterProcHandlers(itr->second, eventInfo); + + if (!isTriggeredAtSpellProcEvent) + { + continue; + } + + // do checks using conditions table + ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id); + ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget()); + if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions)) + { + continue; + } + + // Triggered spells not triggering additional spells + //bool triggered = !spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_FROM_PROCS) ? + // (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false; + + bool hasTriggeredProc = false; + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (itr->second->HasEffect(i)) + { + AuraEffect* aurEff = itr->second->GetBase()->GetEffect(i); + + // Skip this auras + if (isNonTriggerAura[aurEff->GetAuraType()]) + continue; + + // If not trigger by default and spellProcEvent == nullptr - skip + if (!isTriggerAura[aurEff->GetAuraType()] && !triggerData.spellProcEvent) + continue; + + switch (aurEff->GetAuraType()) + { + case SPELL_AURA_PROC_TRIGGER_SPELL: + case SPELL_AURA_MANA_SHIELD: + case SPELL_AURA_DUMMY: + case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: + if (uint32 triggerSpellId = aurEff->GetSpellInfo()->Effects[i].TriggerSpell) + { + triggerData.triggerSpelId[i] = triggerSpellId; + hasTriggeredProc = true; + } + break; + default: + break; + } + + // Some spells must always trigger + //if (isAlwaysTriggeredAura[aurEff->GetAuraType()]) + triggerData.effMask |= 1 << i; + } + } + + if (triggerData.effMask) + { + // If there is aura that triggers another proc aura, make sure that the triggered one is going to be proccessed on top of it + if (hasTriggeredProc) + { + bool proccessed = false; + for (uint8 i = 0; i < EFFECT_ALL; ++i) + { + if (uint32 triggeredSpellId = triggerData.triggerSpelId[i]) + { + auto iter = std::find(procTriggered.begin(), procTriggered.end(), triggeredSpellId); + if (iter != procTriggered.end()) + { + std::advance(iter, 1); + procTriggered.insert(iter, triggerData); + proccessed = true; + break; + } + } + } + + if (!proccessed) + { + procTriggered.push_front(triggerData); + } + } + else + { + procTriggered.push_front(triggerData); + } + } + } + + // Nothing found + if (procTriggered.empty()) + return; + + // Note: must SetCantProc(false) before return + if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC)) + SetCantProc(true); + + // Handle effects proceed this time + for (ProcTriggeredList::const_iterator i = procTriggered.begin(); i != procTriggered.end(); ++i) + { + // look for aura in auras list, it may be removed while proc event processing + if (i->aura->IsRemoved()) + continue; + + bool useCharges = i->aura->IsUsingCharges(); + // no more charges to use, prevent proc + if (useCharges && !i->aura->GetCharges()) + continue; + + bool takeCharges = false; + SpellInfo const* spellInfo = i->aura->GetSpellInfo(); + + AuraApplication* aurApp = i->aura->GetApplicationOfTarget(GetGUID()); + + bool prepare = i->aura->CallScriptPrepareProcHandlers(aurApp, eventInfo); + + // For players set spell cooldown if need + uint32 cooldown = 0; + if (prepare && i->spellProcEvent && i->spellProcEvent->cooldown) + cooldown = i->spellProcEvent->cooldown; + + // Xinef: set cooldown for actual proc + eventInfo.SetProcCooldown(cooldown); + + // Note: must SetCantProc(false) before return + if (spellInfo->HasAttribute(SPELL_ATTR3_INSTANT_TARGET_PROCS)) + SetCantProc(true); + + bool handled = i->aura->CallScriptProcHandlers(aurApp, eventInfo); + + // "handled" is needed as long as proc can be handled in multiple places + if (!handled && HandleAuraProc(target, damage, i->aura, procSpellInfo, procFlag, procExtra, cooldown, &handled)) + { + uint32 Id = i->aura->GetId(); + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), Id); + takeCharges = true; + } + + if (!handled) + for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) + { + if (!(i->effMask & (1 << effIndex))) + continue; + + AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex); + ASSERT(triggeredByAura); + + bool prevented = i->aura->CallScriptEffectProcHandlers(triggeredByAura, aurApp, eventInfo); + if (prevented) + { + takeCharges = true; + continue; + } + + switch (triggeredByAura->GetAuraType()) + { + case SPELL_AURA_PROC_TRIGGER_SPELL: + { + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); + // Don`t drop charge or add cooldown for not started trigger + if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo)) + takeCharges = true; + break; + } + case SPELL_AURA_PROC_TRIGGER_DAMAGE: + { + // target has to be valid + if (!eventInfo.GetProcTarget()) + break; + + triggeredByAura->HandleProcTriggerDamageAuraProc(aurApp, eventInfo); // this function is part of the new proc system + takeCharges = true; + break; + } + case SPELL_AURA_MANA_SHIELD: + case SPELL_AURA_DUMMY: + { + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} dummy aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); + if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procSpell)) + takeCharges = true; + break; + } + case SPELL_AURA_OBS_MOD_POWER: + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: + case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: + case SPELL_AURA_MOD_MELEE_HASTE: + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} aura of spell {})", spellInfo->Id, isVictim ? "a victim's" : "an attacker's", triggeredByAura->GetId()); + takeCharges = true; + break; + case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: + { + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell id {} (triggered by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); + if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpellInfo, cooldown)) + takeCharges = true; + break; + } + case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE: + { + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting mending (triggered by {} dummy aura of spell {})", + (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); + if (damage > 0) + { + HandleAuraRaidProcFromChargeWithValue(triggeredByAura); + takeCharges = true; + } + break; + } + case SPELL_AURA_RAID_PROC_FROM_CHARGE: + { + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting mending (triggered by {} dummy aura of spell {})", + (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); + HandleAuraRaidProcFromCharge(triggeredByAura); + takeCharges = true; + break; + } + case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: + { + LOG_DEBUG("spells.aura", "ProcDamageAndSpell: casting spell {} (triggered with value by {} aura of spell {})", spellInfo->Id, (isVictim ? "a victim's" : "an attacker's"), triggeredByAura->GetId()); + + if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpellInfo, procFlag, procExtra, cooldown, procPhase, eventInfo)) + takeCharges = true; + break; + } + case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: + // Skip melee hits or instant cast spells + // xinef: check channeled spells which are affected by haste also + if (procSpellInfo && (procSpellInfo->SpellFamilyName || GetTypeId() != TYPEID_PLAYER) && + (procSpellInfo->CalcCastTime() > 0 /*|| + (procSpell->IsChanneled() && procSpell->GetDuration() > 0 && (HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, procSpell) || procSpell->HasAttribute(SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC)))*/)) + takeCharges = true; + break; + case SPELL_AURA_REFLECT_SPELLS_SCHOOL: + // Skip Melee hits and spells ws wrong school + if (procSpellInfo && (triggeredByAura->GetMiscValue() & procSpellInfo->SchoolMask)) // School check + takeCharges = true; + break; + case SPELL_AURA_SPELL_MAGNET: + // Skip Melee hits and targets with magnet aura + if (procSpellInfo && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet + takeCharges = true; + break; + case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: + case SPELL_AURA_MOD_POWER_COST_SCHOOL: + // Skip melee hits and spells ws wrong school or zero cost + if (procSpellInfo && + (procSpellInfo->ManaCost != 0 || procSpellInfo->ManaCostPercentage != 0 || (procSpellInfo->SpellFamilyFlags[1] & 0x2)) && // Cost check, mutilate include + (triggeredByAura->GetMiscValue() & procSpellInfo->SchoolMask)) // School check + takeCharges = true; + break; + case SPELL_AURA_MECHANIC_IMMUNITY: + case SPELL_AURA_MOD_MECHANIC_RESISTANCE: + // Compare mechanic + if (procSpellInfo && procSpellInfo->Mechanic == uint32(triggeredByAura->GetMiscValue())) + takeCharges = true; + break; + case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: + // Compare casters + if (target && triggeredByAura->GetCasterGUID() == target->GetGUID()) + takeCharges = true; + break; + // CC Auras which use their amount amount to drop + // Are there any more auras which need this? + case SPELL_AURA_MOD_CONFUSE: + case SPELL_AURA_MOD_FEAR: + case SPELL_AURA_MOD_STUN: + case SPELL_AURA_MOD_ROOT: + case SPELL_AURA_TRANSFORM: + { + // Spell own direct damage at apply wont break the CC + // Xinef: Or when the aura is at full duration (assume that such auras should be added at the end, skipping all damage procs etc.) + if (procSpellInfo) + if ((!i->aura->IsPermanent() && i->aura->GetDuration() == i->aura->GetMaxDuration()) || procSpellInfo->Id == triggeredByAura->GetId() || + procSpellInfo->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC)) + break; + + // chargeable mods are breaking on hit + if (useCharges) + takeCharges = true; + else if (triggeredByAura->GetAmount()) // aura must have amount + { + int32 damageLeft = triggeredByAura->GetAmount(); + // No damage left + if (damageLeft < int32(damage)) + i->aura->Remove(); + else + triggeredByAura->SetAmount(damageLeft - damage); + } + break; + } + case SPELL_AURA_ABILITY_IGNORE_AURASTATE: + if (procSpellInfo && procSpellInfo->Id == 20647) // hack for warriors execute, both dummy and damage spell are affected by ignore aurastate aura + break; + takeCharges = true; + break; + case SPELL_AURA_ADD_FLAT_MODIFIER: + case SPELL_AURA_ADD_PCT_MODIFIER: + { + if (SpellModifier* mod = triggeredByAura->GetSpellModifier()) + { + if (mod->op == SPELLMOD_CASTING_TIME && mod->value < 0 && procSpell) + { + // Skip instant spells + if (procSpellInfo->CalcCastTime() <= 0 || (procSpell->GetTriggeredCastFlags() & TRIGGERED_CAST_DIRECTLY) != 0) + { + break; + } + } + } + takeCharges = true; + break; + } + default: + takeCharges = true; + break; + } + i->aura->CallScriptAfterEffectProcHandlers(triggeredByAura, aurApp, eventInfo); + } + // Remove charge (aura can be removed by triggers) + // xinef: take into account attribute6 of proc spell + if (prepare && useCharges && takeCharges) + if (!procSpellInfo || isVictim || !procSpellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES)) + i->aura->DropCharge(); + + i->aura->CallScriptAfterProcHandlers(aurApp, eventInfo); + + if (spellInfo->HasAttribute(SPELL_ATTR3_INSTANT_TARGET_PROCS)) + SetCantProc(false); + } + + // Cleanup proc requirements + if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC)) + SetCantProc(false); } -void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, AuraApplicationList* procAuras, ProcEventInfo& eventInfo) +void Unit::GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo) { - std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); - // use provided list of auras which can proc if (procAuras) { - for (AuraApplication* aurApp : *procAuras) + for (std::list<AuraApplication*>::iterator itr = procAuras->begin(); itr != procAuras->end(); ++itr) { - ASSERT(aurApp->GetTarget() == this); - if (!aurApp->GetRemoveMode()) - if (uint8 procEffectMask = aurApp->GetBase()->GetProcEffectMask(aurApp, eventInfo, now)) + ASSERT((*itr)->GetTarget() == this); + if (!(*itr)->GetRemoveMode()) + if ((*itr)->GetBase()->IsProcTriggeredOnEvent(*itr, eventInfo)) { - aurApp->GetBase()->PrepareProcToTrigger(aurApp, eventInfo, now); - aurasTriggeringProc.emplace_back(procEffectMask, aurApp); + (*itr)->GetBase()->PrepareProcToTrigger(*itr, eventInfo); + aurasTriggeringProc.push_back(*itr); } } } @@ -12359,10 +16214,10 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg { for (AuraApplicationMap::iterator itr = GetAppliedAuras().begin(); itr != GetAppliedAuras().end(); ++itr) { - if (uint8 procEffectMask = itr->second->GetBase()->GetProcEffectMask(itr->second, eventInfo, now)) + if (itr->second->GetBase()->IsProcTriggeredOnEvent(itr->second, eventInfo)) { - itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo, now); - aurasTriggeringProc.emplace_back(procEffectMask, itr->second); + itr->second->GetBase()->PrepareProcToTrigger(itr->second, eventInfo); + aurasTriggeringProc.push_back(itr->second); } } } @@ -12371,80 +16226,35 @@ void Unit::GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTrigg void Unit::TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo) { DamageInfo dmgInfo = DamageInfo(damageInfo); - TriggerAurasProcOnEvent(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, PROC_SPELL_TYPE_NONE, PROC_SPELL_PHASE_NONE, dmgInfo.GetHitMask(), nullptr, &dmgInfo, nullptr); + TriggerAurasProcOnEvent(nullptr, nullptr, damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, 0, 0, damageInfo.procEx, nullptr, &dmgInfo, nullptr); } -void Unit::TriggerAurasProcOnEvent(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) +void Unit::TriggerAurasProcOnEvent(std::list<AuraApplication*>* myProcAuras, std::list<AuraApplication*>* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo) { // prepare data for self trigger - ProcEventInfo myProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); - if (typeMaskActor) - { - AuraApplicationProcContainer myAurasTriggeringProc; - GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, nullptr, myProcEventInfo); + ProcEventInfo myProcEventInfo = ProcEventInfo(this, actionTarget, actionTarget, typeMaskActor, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); + std::list<AuraApplication*> myAurasTriggeringProc; + GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, myProcAuras, myProcEventInfo); - // needed for example for Cobra Strikes, pet does the attack, but aura is on owner - if (Player* modOwner = GetSpellModOwner()) - { - if (modOwner != this && spell) - { - AuraApplicationList modAuras; - for (auto itr = modOwner->GetAppliedAuras().begin(); itr != modOwner->GetAppliedAuras().end(); ++itr) - { - if (spell->m_appliedMods.count(itr->second->GetBase()) != 0) - modAuras.push_back(itr->second); - } - modOwner->GetProcAurasTriggeredOnEvent(myAurasTriggeringProc, &modAuras, myProcEventInfo); - } - } + // prepare data for target trigger + ProcEventInfo targetProcEventInfo = ProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); + std::list<AuraApplication*> targetAurasTriggeringProc; + if (typeMaskActionTarget) + GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, targetProcAuras, targetProcEventInfo); - TriggerAurasProcOnEvent(myProcEventInfo, myAurasTriggeringProc); - } + TriggerAurasProcOnEvent(myProcEventInfo, myAurasTriggeringProc); - // prepare data for target trigger - ProcEventInfo targetProcEventInfo(this, actionTarget, this, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, spell, damageInfo, healInfo); - if (typeMaskActionTarget && actionTarget) - { - AuraApplicationProcContainer targetAurasTriggeringProc; - actionTarget->GetProcAurasTriggeredOnEvent(targetAurasTriggeringProc, nullptr, targetProcEventInfo); - actionTarget->TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc); - } + if (typeMaskActionTarget) + TriggerAurasProcOnEvent(targetProcEventInfo, targetAurasTriggeringProc); } -void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& aurasTriggeringProc) +void Unit::TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list<AuraApplication*>& aurasTriggeringProc) { - Spell const* triggeringSpell = eventInfo.GetProcSpell(); - bool const disableProcs = triggeringSpell && triggeringSpell->IsProcDisabled(); - if (disableProcs) - SetCantProc(true); - - for (auto const& aurAppProc : aurasTriggeringProc) + for (std::list<AuraApplication*>::iterator itr = aurasTriggeringProc.begin(); itr != aurasTriggeringProc.end(); ++itr) { - AuraApplication* aurApp; - uint8 procEffectMask; - std::tie(procEffectMask, aurApp) = aurAppProc; - - if (aurApp->GetRemoveMode()) - { - continue; - } - - SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo(); - if (spellInfo->HasAttribute(SPELL_ATTR3_DISABLE_PROC)) - { - SetCantProc(true); - } - - aurApp->GetBase()->TriggerProcOnEvent(procEffectMask, aurApp, eventInfo); - - if (spellInfo->HasAttribute(SPELL_ATTR3_DISABLE_PROC)) - { - SetCantProc(false); - } + if (!(*itr)->GetRemoveMode()) + (*itr)->GetBase()->TriggerProcOnEvent(*itr, eventInfo); } - - if (disableProcs) - SetCantProc(false); } SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const @@ -12677,10 +16487,6 @@ void Unit::AddComboPoints(Unit* target, int8 count) return; } - // remove Premed-like effects - // (NB: this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore) - RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS); - if (target && target != m_comboTarget) { if (m_comboTarget) @@ -13248,7 +17054,280 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) return true; } -void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackType /* attackType */, SpellInfo const* /* spellProto */) +bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo) +{ + SpellInfo const* spellProto = aura->GetSpellInfo(); + SpellInfo const* procSpell = eventInfo.GetSpellInfo(); + + // let the aura be handled by new proc system if it has new entry + if (sSpellMgr->GetSpellProcEntry(spellProto->Id)) + return false; + + // Get proc Event Entry + spellProcEvent = sSpellMgr->GetSpellProcEvent(spellProto->Id); + + // Get EventProcFlag + uint32 EventProcFlag; + if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags + EventProcFlag = spellProcEvent->procFlags; + else + EventProcFlag = spellProto->ProcFlags; // else get from spell proto + // Continue if no trigger exist + if (!EventProcFlag) + return false; + + // Additional checks for triggered spells (ignore trap casts) + //if (procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) + //{ + // if (!spellProto->HasAttribute(SPELL_ATTR3_CAN_PROC_TRIGGERED)) + // return false; + //} + + // Xinef: additional check for player auras - only player spells can trigger player proc auras + // Xinef: skip victim auras + // Excluded player shoot spells + if (!isVictim && GetTypeId() == TYPEID_PLAYER) //spellProto->SpellFamilyName != SPELLFAMILY_GENERIC) + if (!(EventProcFlag & (PROC_FLAG_KILL | PROC_FLAG_DEATH)) && procSpell && procSpell->SpellFamilyName == SPELLFAMILY_GENERIC && procSpell->GetCategory() != 76 && + (!eventInfo.GetTriggerAuraSpell() || eventInfo.GetTriggerAuraSpell()->SpellFamilyName == SPELLFAMILY_GENERIC)) + return false; + + // Check spellProcEvent data requirements + if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProto, spellProcEvent, EventProcFlag, eventInfo, active)) + return false; + // In most cases req get honor or XP from kill + if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER) + { + bool allow = false; + + if (victim) + allow = ToPlayer()->isHonorOrXPTarget(victim); + + // Shadow Word: Death - can trigger from every kill + if (aura->GetId() == 32409 || aura->GetId() == 18372 || aura->GetId() == 18213) + allow = true; + if (!allow) + return false; + } + // Aura added by spell can`t trigger from self (prevent drop charges/do triggers) + // But except periodic and kill triggers (can triggered from self) + if (procSpell && procSpell->Id == spellProto->Id + && !(spellProto->ProcFlags & (PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_KILL))) + return false; + + // Check if current equipment allows aura to proc + if (!isVictim && GetTypeId() == TYPEID_PLAYER && !spellProto->HasAttribute(SPELL_ATTR3_NO_PROC_EQUIP_REQUIREMENT)) + { + Player* player = ToPlayer(); + if (spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) + { + Item* item = nullptr; + if (attType == BASE_ATTACK) + item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + else if (attType == OFF_ATTACK) + item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + else + item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); + + if (player->IsInFeralForm()) + return false; + + if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_WEAPON || !((1 << item->GetTemplate()->SubClass) & spellProto->EquippedItemSubClassMask)) + return false; + } + else if (spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) + { + // Check if player is wearing shield + Item* item = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + if (!item || item->IsBroken() || item->GetTemplate()->Class != ITEM_CLASS_ARMOR || !((1 << item->GetTemplate()->SubClass) & spellProto->EquippedItemSubClassMask)) + return false; + } + } + // Get chance from spell + float chance = float(spellProto->ProcChance); + // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance; + if (spellProcEvent && spellProcEvent->customChance) + chance = spellProcEvent->customChance; + // If PPM exist calculate chance from PPM + if (spellProcEvent && spellProcEvent->ppmRate != 0) + { + if (!isVictim) + { + uint32 WeaponSpeed = GetAttackTime(attType); + chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto); + } + else if (victim) + { + uint32 WeaponSpeed = victim->GetAttackTime(attType); + chance = victim->GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate, spellProto); + } + } + + // Custom chances + switch (spellProto->SpellFamilyName) + { + case SPELLFAMILY_WARRIOR: + { + // Recklessness, allow to proc only once for whirlwind + if (spellProto->Id == 1719 && procSpell && procSpell->Id == 44949) + return false; + } + } + + if (eventInfo.GetProcChance()) + { + chance = *eventInfo.GetProcChance(); + } + + // Apply chance modifer aura + if (Player* modOwner = GetSpellModOwner()) + { + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CHANCE_OF_SUCCESS, chance); + } + + return roll_chance_f(chance); +} + +bool Unit::HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura) +{ + // aura can be deleted at casts + SpellInfo const* spellProto = triggeredByAura->GetSpellInfo(); + int32 heal = triggeredByAura->GetAmount(); + ObjectGuid caster_guid = triggeredByAura->GetCasterGUID(); + + // Currently only Prayer of Mending + if (!(spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && spellProto->SpellFamilyFlags[1] & 0x20)) + { + LOG_DEBUG("spells.aura", "Unit::HandleAuraRaidProcFromChargeWithValue, received not handled spell: {}", spellProto->Id); + return false; + } + + // jumps + int32 jumps = triggeredByAura->GetBase()->GetCharges() - 1; + + // current aura expire + triggeredByAura->GetBase()->SetCharges(1); // will removed at next charges decrease + + // next target selection + if (jumps > 0) + { + if (Unit* caster = triggeredByAura->GetCaster()) + { + // smart healing + float radius = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcRadius(caster); + std::list<Unit*> nearMembers; + + Player* player = nullptr; + if (GetTypeId() == TYPEID_PLAYER) + player = ToPlayer(); + else if (GetOwner()) + player = GetOwner()->ToPlayer(); + + if (player) + { + Group* group = player->GetGroup(); + if (!group) + { + if (player != this) + { + if (IsWithinDistInMap(player, radius)) + nearMembers.push_back(player); + } + else if (Unit* pet = GetGuardianPet()) + { + if (IsWithinDistInMap(pet, radius)) + nearMembers.push_back(pet); + } + } + else + { + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* Target = itr->GetSource()) + { + if (Target != this && !IsWithinDistInMap(Target, radius)) + continue; + + // IsHostileTo check duel and controlled by enemy + if (Target != this && Target->IsAlive() && !IsHostileTo(Target)) + nearMembers.push_back(Target); + + // Push player's pet to vector + if (Unit* pet = Target->GetGuardianPet()) + if (pet != this && pet->IsAlive() && IsWithinDistInMap(pet, radius) && !IsHostileTo(pet)) + nearMembers.push_back(pet); + } + } + + if (!nearMembers.empty()) + { + nearMembers.sort(Acore::HealthPctOrderPred()); + if (Unit* target = nearMembers.front()) + { + CastSpell(target, 41637 /*Dummy visual effect triggered by main spell cast*/, true); + CastCustomSpell(target, spellProto->Id, &heal, nullptr, nullptr, true, nullptr, triggeredByAura, caster_guid); + if (Aura* aura = target->GetAura(spellProto->Id, caster->GetGUID())) + aura->SetCharges(jumps); + } + } + } + } + } + + // heal + CastCustomSpell(this, 33110, &heal, nullptr, nullptr, true, nullptr, nullptr, caster_guid); + return true; +} +bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura) +{ + // aura can be deleted at casts + SpellInfo const* spellProto = triggeredByAura->GetSpellInfo(); + + uint32 damageSpellId; + switch (spellProto->Id) + { + case 57949: // shiver + damageSpellId = 57952; + //animationSpellId = 57951; dummy effects for jump spell have unknown use (see also 41637) + break; + case 59978: // shiver + damageSpellId = 59979; + break; + case 43593: // Cold Stare + damageSpellId = 43594; + break; + default: + LOG_ERROR("entities.unit", "Unit::HandleAuraRaidProcFromCharge, received unhandled spell: {}", spellProto->Id); + return false; + } + + ObjectGuid caster_guid = triggeredByAura->GetCasterGUID(); + + // jumps + int32 jumps = triggeredByAura->GetBase()->GetCharges() - 1; + + // current aura expire + triggeredByAura->GetBase()->SetCharges(1); // will removed at next charges decrease + + // next target selection + if (jumps > 0) + { + if (Unit* caster = triggeredByAura->GetCaster()) + { + float radius = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcRadius(caster); + if (Unit* target = GetNextRandomRaidMemberOrPet(radius)) + { + CastSpell(target, spellProto, true, nullptr, triggeredByAura, caster_guid); + if (Aura* aura = target->GetAura(spellProto->Id, caster->GetGUID())) + aura->SetCharges(jumps); + } + } + } + + CastSpell(this, damageSpellId, true, nullptr, triggeredByAura, caster_guid); + + return true; +} + +void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackType attackType, SpellInfo const* spellProto, Spell const* spell /*= nullptr*/) { // Prevent killing unit twice (and giving reward from kill twice) if (!victim->GetHealth()) @@ -13363,22 +17442,17 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp // Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim if (killer && (killer->IsPet() || killer->IsTotem())) - { - // proc only once for victim if (Unit* owner = killer->GetOwner()) { - owner->ProcSkillsAndAuras(victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr); - sScriptMgr->OnCreatureKilledByPet(killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature()); + Unit::ProcDamageAndSpell(owner, victim, PROC_FLAG_KILL, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); + sScriptMgr->OnCreatureKilledByPet( killer->GetCharmerOrOwnerPlayerOrPlayerItself(), victim->ToCreature()); } - } if (killer != victim && !victim->IsCritter()) - { - killer->ProcSkillsAndAuras(victim, killer ? PROC_FLAG_KILL : PROC_FLAG_NONE, PROC_FLAG_KILLED, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr); - } + Unit::ProcDamageAndSpell(killer, victim, killer ? PROC_FLAG_KILL : 0, PROC_FLAG_KILLED, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); // Proc auras on death - must be before aura/combat remove - victim->ProcSkillsAndAuras(victim, PROC_FLAG_NONE, PROC_FLAG_DEATH, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr); + Unit::ProcDamageAndSpell(victim, nullptr, PROC_FLAG_DEATH, PROC_FLAG_NONE, PROC_EX_NONE, 0, attackType, spellProto, nullptr, -1, spell); // update get killing blow achievements, must be done before setDeathState to be able to require auras on target // and before Spirit of Redemption as it also removes auras @@ -14544,7 +18618,7 @@ float Unit::MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, i if (spellId) { if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RESIST_MISS_CHANCE>(spellId, hitChance); + modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, hitChance); } missChance += hitChance - 100.0f; @@ -15060,6 +19134,15 @@ void Unit::JumpTo(WorldObject* obj, float speedZ) bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) { + Creature* creature = ToCreature(); + if (creature && creature->IsAIEnabled) + { + if (!creature->AI()->BeforeSpellClick(clicker)) + { + return false; + } + } + bool result = false; uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry(); SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry); @@ -15128,7 +19211,6 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) result = true; } - Creature* creature = ToCreature(); if (creature && creature->IsAIEnabled) creature->AI()->OnSpellClick(clicker, result); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8e66a0a481..383b452475 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -702,13 +702,13 @@ struct DiminishingReturn : DRGroup(group), stack(0), hitTime(t), hitCount(count) {} - DiminishingGroup DRGroup; - uint16 stack; + DiminishingGroup DRGroup: 16; + uint16 stack: 16; uint32 hitTime; uint32 hitCount; }; -enum MeleeHitOutcome : uint8 +enum MeleeHitOutcome { MELEE_HIT_EVADE, MELEE_HIT_MISS, MELEE_HIT_DODGE, MELEE_HIT_BLOCK, MELEE_HIT_PARRY, MELEE_HIT_GLANCING, MELEE_HIT_CRIT, MELEE_HIT_CRUSHING, MELEE_HIT_NORMAL @@ -761,12 +761,11 @@ private: uint32 m_absorb; uint32 m_resist; uint32 m_block; - uint32 m_hitMask; uint32 m_cleanDamage; public: - DamageInfo(Unit* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, DamageEffectType damageType, WeaponAttackType attackType, uint32 cleanDamage = 0); + explicit DamageInfo(Unit* _attacker, Unit* _victim, uint32 _damage, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask, DamageEffectType _damageType, uint32 cleanDamage = 0); explicit DamageInfo(CalcDamageInfo& dmgInfo); - DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType, WeaponAttackType attackType, uint32 hitMask); + DamageInfo(SpellNonMeleeDamage const& spellNonMeleeDamage, DamageEffectType damageType); void ModifyDamage(int32 amount); void AbsorbDamage(uint32 amount); @@ -785,7 +784,6 @@ public: [[nodiscard]] uint32 GetBlock() const { return m_block; }; [[nodiscard]] uint32 GetUnmitigatedDamage() const; - [[nodiscard]] uint32 GetHitMask() const; }; class HealInfo @@ -794,33 +792,33 @@ private: Unit* const m_healer; Unit* const m_target; uint32 m_heal; - uint32 m_effectiveHeal; uint32 m_absorb; SpellInfo const* const m_spellInfo; SpellSchoolMask const m_schoolMask; - uint32 m_hitMask; public: - explicit HealInfo(Unit* healer, Unit* target, uint32 heal, SpellInfo const* spellInfo, SpellSchoolMask schoolMask); - void AbsorbHeal(uint32 amount); - - void SetHeal(uint32 amount) + explicit HealInfo(Unit* _healer, Unit* _target, uint32 _heal, SpellInfo const* _spellInfo, SpellSchoolMask _schoolMask) + : m_healer(_healer), m_target(_target), m_heal(_heal), m_spellInfo(_spellInfo), m_schoolMask(_schoolMask) { - m_heal = amount; + m_absorb = 0; + } + void AbsorbHeal(uint32 amount) + { + amount = std::min(amount, GetHeal()); + m_absorb += amount; + m_heal -= amount; } - void SetEffectiveHeal(uint32 amount) + void SetHeal(uint32 amount) { - m_effectiveHeal = amount; + m_heal = amount; } [[nodiscard]] Unit* GetHealer() const { return m_healer; } [[nodiscard]] Unit* GetTarget() const { return m_target; } [[nodiscard]] uint32 GetHeal() const { return m_heal; } - [[nodiscard]] uint32 GetEffectiveHeal() const { return m_effectiveHeal; } [[nodiscard]] uint32 GetAbsorb() const { return m_absorb; } [[nodiscard]] SpellInfo const* GetSpellInfo() const { return m_spellInfo; }; [[nodiscard]] SpellSchoolMask GetSchoolMask() const { return m_schoolMask; }; - [[nodiscard]] uint32 GetHitMask() const; }; class ProcEventInfo @@ -891,7 +889,7 @@ struct SpellNonMeleeDamage { SpellNonMeleeDamage(Unit* _attacker, Unit* _target, SpellInfo const* _spellInfo, uint32 _schoolMask) : target(_target), attacker(_attacker), spellInfo(_spellInfo), damage(0), overkill(0), schoolMask(_schoolMask), - absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0), fullBlock(false) + absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0) {} Unit* target; @@ -908,7 +906,6 @@ struct SpellNonMeleeDamage uint32 HitInfo; // Used for help uint32 cleanDamage; - bool fullBlock; }; struct SpellPeriodicAuraLogInfo @@ -926,7 +923,7 @@ struct SpellPeriodicAuraLogInfo }; void createProcFlags(SpellInfo const* spellInfo, WeaponAttackType attackType, bool positive, uint32& procAttacker, uint32& procVictim); -uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition); +uint32 createProcExtendMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition); struct RedirectThreatInfo { @@ -1291,7 +1288,6 @@ public: typedef std::list<Aura*> AuraList; typedef std::list<AuraApplication*> AuraApplicationList; typedef std::list<DiminishingReturn> Diminishing; - typedef std::vector<std::pair<uint8 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer; typedef GuidUnorderedSet ComboPointHolderSet; typedef std::map<uint8, AuraApplication*> VisibleAuraMap; @@ -1443,10 +1439,10 @@ public: void setPowerType(Powers power); [[nodiscard]] uint32 GetPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power); } [[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); } - void SetPower(Powers power, uint32 val); + void SetPower(Powers power, uint32 val, bool withPowerUpdate = true); void SetMaxPower(Powers power, uint32 val); // returns the change in power - int32 ModifyPower(Powers power, int32 val); + int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate = true); int32 ModifyPowerPct(Powers power, float pct, bool apply = true); [[nodiscard]] uint32 GetAttackTime(WeaponAttackType att) const @@ -1530,15 +1526,16 @@ public: uint16 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } static void DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb); static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false, Spell const* spell = nullptr); - static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr); - static void DealHeal(HealInfo& healInfo); + static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr, Spell const* spell = nullptr); + static int32 DealHeal(Unit* healer, Unit* victim, uint32 addhealth); - void ProcSkillsAndAuras(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); + static void ProcDamageAndSpell(Unit* actor, Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType = BASE_ATTACK, SpellInfo const* procSpellInfo = nullptr, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/); + void ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, SpellInfo const* procSpellInfo, uint32 damage, SpellInfo const* procAura = nullptr, int8 procAuraEffectIndex = -1, Spell const* procSpell = nullptr, DamageInfo* damageInfo = nullptr, HealInfo* healInfo = nullptr, uint32 procPhase = 2 /*PROC_SPELL_PHASE_HIT*/); - void GetProcAurasTriggeredOnEvent(AuraApplicationProcContainer& aurasTriggeringProc, AuraApplicationList* procAuras, ProcEventInfo& eventInfo); + void GetProcAurasTriggeredOnEvent(std::list<AuraApplication*>& aurasTriggeringProc, std::list<AuraApplication*>* procAuras, ProcEventInfo eventInfo); void TriggerAurasProcOnEvent(CalcDamageInfo& damageInfo); - void TriggerAurasProcOnEvent(Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); - void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, AuraApplicationProcContainer& procAuras); + void TriggerAurasProcOnEvent(std::list<AuraApplication*>* myProcAuras, std::list<AuraApplication*>* targetProcAuras, Unit* actionTarget, uint32 typeMaskActor, uint32 typeMaskActionTarget, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo); + void TriggerAurasProcOnEvent(ProcEventInfo& eventInfo, std::list<AuraApplication*>& procAuras); void HandleEmoteCommand(uint32 emoteId); void AttackerStateUpdate (Unit* victim, WeaponAttackType attType = BASE_ATTACK, bool extra = false, bool ignoreCasting = false); @@ -1546,7 +1543,12 @@ public: void CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* damageInfo, WeaponAttackType attackType = BASE_ATTACK, const bool sittingVictim = false); void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss); - void HandleProcExtraAttackFor(Unit* victim); + void HandleProcExtraAttackFor(Unit* victim, uint32 count); + void SetLastExtraAttackSpell(uint32 spellId) { _lastExtraAttackSpell = spellId; } + [[nodiscard]] uint32 GetLastExtraAttackSpell() const { return _lastExtraAttackSpell; } + void AddExtraAttacks(uint32 count); + void SetLastDamagedTargetGuid(ObjectGuid const& guid) { _lastDamagedTargetGuid = guid; } + [[nodiscard]] ObjectGuid const& GetLastDamagedTargetGuid() const { return _lastDamagedTargetGuid; } void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false); void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell = nullptr); @@ -1698,7 +1700,7 @@ public: [[nodiscard]] virtual bool IsUnderWater() const; bool isInAccessiblePlaceFor(Creature const* c) const; - void SendHealSpellLog(HealInfo& healInfo, bool critical = false); + void SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false); int32 HealBySpell(HealInfo& healInfo, bool critical = false); void SendEnergizeSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype); void EnergizeBySpell(Unit* victim, uint32 SpellID, uint32 Damage, Powers powertype); @@ -2513,6 +2515,14 @@ protected: bool _instantCast; private: + bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo); + bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, Spell const* spellProc = nullptr); + bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool* handled); + bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, uint32 procPhase, ProcEventInfo& eventInfo); + bool HandleOverrideClassScriptAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown); + bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura); + bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura); + void UpdateSplineMovement(uint32 t_diff); void UpdateSplinePosition(); @@ -2520,8 +2530,6 @@ private: [[nodiscard]] float GetCombatRatingReduction(CombatRating cr) const; [[nodiscard]] uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const; - void ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMask, uint32 hitMask, WeaponAttackType attType); - protected: void SetFeared(bool apply); void SetConfused(bool apply); @@ -2555,6 +2563,10 @@ private: bool _isWalkingBeforeCharm; ///< Are we walking before we were charmed? [[nodiscard]] float processDummyAuras(float TakenTotalMod) const; + + uint32 _lastExtraAttackSpell; + std::unordered_map<ObjectGuid /*guid*/, uint32 /*count*/> extraAttacksTargets; + ObjectGuid _lastDamagedTargetGuid; }; namespace Acore diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 9afe62860c..70eb6ef98c 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1186,7 +1186,7 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar) { int32 i = 0; flag96 _mask = 0; - SpellModContainer const& spellMods = pCurrChar->GetSpellModContainer(opType); + SpellModList const& spellMods = pCurrChar->GetSpellModList(opType); if (spellMods.empty()) continue; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 6b195ff72a..94a6d72b66 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -103,8 +103,8 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS] = &AuraEffect::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY &AuraEffect::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY &AuraEffect::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY - &AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in AuraEffect::HandleProc - &AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in AuraEffect::HandleProc + &AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell + &AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor &AuraEffect::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES &AuraEffect::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES &AuraEffect::HandleNULL, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a) @@ -323,7 +323,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS] = &AuraEffect::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus &AuraEffect::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code &AuraEffect::HandlePhase, //261 SPELL_AURA_PHASE - &AuraEffect::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in Spell::CheckCast + &AuraEffect::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast &AuraEffect::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask &AuraEffect::HandleUnused, //264 unused (3.2.0) &AuraEffect::HandleUnused, //265 unused (3.2.0) @@ -631,7 +631,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load) { // Apply periodic time mod if (modOwner) - modOwner->ApplySpellMod<SPELLMOD_ACTIVATION_TIME>(GetId(), m_amplitude); + modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude); if (caster) { @@ -689,6 +689,7 @@ void AuraEffect::CalculateSpellMod() m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types m_spellmod->spellId = GetId(); m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask; + m_spellmod->charges = GetBase()->GetCharges(); } m_spellmod->value = GetAmount(); break; @@ -1071,11 +1072,14 @@ bool AuraEffect::IsAffectedOnSpell(SpellInfo const* spell) const { if (!spell) return false; - // Check family name and EffectClassMask - if (!spell->IsAffected(m_spellInfo->SpellFamilyName, m_spellInfo->Effects[m_effIndex].SpellClassMask)) + // Check family name + if (spell->SpellFamilyName != m_spellInfo->SpellFamilyName) return false; - return true; + // Check EffectClassMask + if (m_spellInfo->Effects[m_effIndex].SpellClassMask & spell->SpellFamilyFlags) + return true; + return false; } bool AuraEffect::HasSpellClassMask() const @@ -1142,99 +1146,6 @@ void AuraEffect::PeriodicTick(AuraApplication* aurApp, Unit* caster) const } } -bool AuraEffect::CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) const -{ - bool result = GetBase()->CallScriptCheckEffectProcHandlers(this, aurApp, eventInfo); - if (!result) - return false; - - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - switch (GetAuraType()) - { - case SPELL_AURA_MOD_CONFUSE: - case SPELL_AURA_MOD_FEAR: - case SPELL_AURA_MOD_STUN: - case SPELL_AURA_MOD_ROOT: - case SPELL_AURA_TRANSFORM: - { - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - { - return false; - } - - // Spell own damage at apply won't break CC - if (spellInfo && spellInfo == eventInfo.GetSpellInfo()) - { - Aura* aura = GetBase(); - // called from spellcast, should not have ticked yet - if (aura->GetDuration() == aura->GetMaxDuration()) - { - return false; - } - } - break; - } - break; - case SPELL_AURA_MECHANIC_IMMUNITY: - case SPELL_AURA_MOD_MECHANIC_RESISTANCE: - // Compare mechanic - if (!spellInfo || static_cast<int32>(spellInfo->Mechanic) != GetMiscValue()) - { - return false; - } - break; - case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: - // Skip melee hits and instant cast spells - if (!spellInfo || !spellInfo->CalcCastTime()) - { - return false; - } - break; - case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: - // Compare casters - if (GetCasterGUID() != eventInfo.GetActor()->GetGUID()) - { - return false; - } - break; - case SPELL_AURA_MOD_POWER_COST_SCHOOL: - case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: - // Skip melee hits and spells with wrong school or zero cost - if (!spellInfo || (!spellInfo->ManaCost && !spellInfo->ManaCostPercentage) || // Cost Check - !(spellInfo->GetSchoolMask() & GetMiscValue())) // School Check - { - return false; - } - break; - case SPELL_AURA_REFLECT_SPELLS_SCHOOL: - // Skip melee hits and spells with wrong school - if (!spellInfo || !(spellInfo->GetSchoolMask() & GetMiscValue())) - { - return false; - } - break; - case SPELL_AURA_PROC_TRIGGER_SPELL: - case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: - { - // Don't proc extra attacks while already processing extra attack spell - uint32 triggerSpellId = GetSpellInfo()->Effects[GetEffIndex()].TriggerSpell; - if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId)) - { - if (aurApp->GetTarget()->m_extraAttacks && triggeredSpellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) - { - return false; - } - } - break; - } - default: - break; - } - - return result; -} - void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) { bool prevented = GetBase()->CallScriptEffectProcHandlers(this, aurApp, eventInfo); @@ -1243,16 +1154,6 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) switch (GetAuraType()) { - // CC Auras which use their amount to drop - // Are there anyu more auras which need this? - case SPELL_AURA_MOD_CONFUSE: - case SPELL_AURA_MOD_FEAR: - case SPELL_AURA_MOD_STUN: - case SPELL_AURA_MOD_ROOT: - case SPELL_AURA_TRANSFORM: - HandleBreakableCCAuraProc(aurApp, eventInfo); - break; - case SPELL_AURA_DUMMY: case SPELL_AURA_PROC_TRIGGER_SPELL: HandleProcTriggerSpellAuraProc(aurApp, eventInfo); break; @@ -2977,6 +2878,7 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo displayId = 0; } } + } target->Mount(displayId, vehicleId, GetMiscValue()); } @@ -5214,6 +5116,12 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (target->GetTypeId() == TYPEID_PLAYER) target->ToPlayer()->RemoveAmmo(); // not use ammo and not allow use break; + case 71563: + { + if (Aura* newAura = target->AddAura(71564, target)) + newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount); + return; + } } } // AT REMOVE @@ -6446,8 +6354,10 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const mitigatedDamage += resilienceReduction; } - DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK, cleanDamage.mitigated_damage); + damage = std::max(0, dmg); + cleanDamage.mitigated_damage = std::max(0, mitigatedDamage); + DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, cleanDamage.mitigated_damage); Unit::CalcAbsorbResist(dmgInfo); uint32 absorb = dmgInfo.GetAbsorb(); @@ -6461,15 +6371,12 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const // Set trigger flag uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 hitMask = dmgInfo.GetHitMask(); + uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_DOT; if (absorb > 0) - hitMask |= PROC_HIT_ABSORB; + procEx |= PROC_EX_ABSORB; if (damage) - { procVictim |= PROC_FLAG_TAKEN_DAMAGE; - hitMask |= crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; - } int32 overkill = damage - target->GetHealth(); if (overkill < 0) @@ -6480,8 +6387,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true); - // allow null caster to call this function - caster->ProcSkillsAndAuras(target, caster ? procAttacker : 0, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &dmgInfo, nullptr); + Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo); } void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const @@ -6534,8 +6440,10 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c cleanDamageAmount += resilienceReduction; } - DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK, cleanDamage.mitigated_damage); + damage = std::max(0, dmg); + cleanDamage.mitigated_damage = std::max(0, cleanDamageAmount); + DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, cleanDamage.mitigated_damage); Unit::CalcAbsorbResist(dmgInfo); uint32 absorb = dmgInfo.GetAbsorb(); @@ -6545,15 +6453,12 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c // Set trigger flag uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 hitMask = dmgInfo.GetHitMask(); + uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_DOT; if (absorb > 0) - hitMask |= PROC_HIT_ABSORB; + procEx |= PROC_EX_ABSORB; if (dmgInfo.GetDamage()) - { procVictim |= PROC_FLAG_TAKEN_DAMAGE; - hitMask |= crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; - } if (target->GetHealth() < dmgInfo.GetDamage()) { @@ -6571,8 +6476,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c new_damage = Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false); - // allow null caster to call this function - caster->ProcSkillsAndAuras(target, caster ? procAttacker : 0, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, hitMask, nullptr, &dmgInfo, nullptr); + Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo); if (!caster || !caster->IsAlive()) return; @@ -6585,7 +6489,6 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c HealInfo healInfo(caster, caster, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask()); int32 gain = caster->HealBySpell(healInfo); caster->getHostileRefMgr().threatAssist(caster, gain * 0.5f, GetSpellInfo()); - caster->ProcSkillsAndAuras(caster, PROC_FLAG_DONE_PERIODIC, PROC_FLAG_TAKEN_PERIODIC, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, hitMask, nullptr, nullptr, &healInfo); } void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster) const @@ -6719,13 +6622,13 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const HealInfo healInfo(caster, target, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask()); Unit::CalcHealAbsorb(healInfo); - Unit::DealHeal(healInfo); + int32 gain = Unit::DealHeal(caster, target, healInfo.GetHeal()); - SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - healInfo.GetEffectiveHeal(), healInfo.GetAbsorb(), 0, 0.0f, crit); + SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - gain, healInfo.GetAbsorb(), 0, 0.0f, crit); target->SendPeriodicAuraLog(&pInfo); if (caster) - target->getHostileRefMgr().threatAssist(caster, float(healInfo.GetEffectiveHeal()) * 0.5f, GetSpellInfo()); + target->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, GetSpellInfo()); bool haveCastItem = GetBase()->GetCastItemGUID(); @@ -6735,9 +6638,9 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const if (target != caster && GetSpellInfo()->HasAttribute(SPELL_ATTR2_NO_TARGET_PER_SECOND_COST)) { uint32 manaPerSecond = GetSpellInfo()->ManaPerSecond; - if (manaPerSecond > healInfo.GetEffectiveHeal() && healInfo.GetEffectiveHeal() > 0) + if ((int32)manaPerSecond > gain && gain > 0) { - manaPerSecond = healInfo.GetEffectiveHeal(); + manaPerSecond = gain; } uint32 absorb2 = 0; @@ -6749,15 +6652,13 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 hitMask = (crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL); + uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT; if (healInfo.GetAbsorb() > 0) - { - hitMask |= PROC_HIT_ABSORB; - } + procEx |= PROC_EX_ABSORB; // ignore item heals if (!haveCastItem && GetAuraType() != SPELL_AURA_OBS_MOD_HEALTH) // xinef: dont allow obs_mod_health to proc spells, this is passive regeneration and not hot - caster->ProcSkillsAndAuras(target, caster ? procAttacker : 0, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_NONE, hitMask, nullptr, nullptr, &healInfo); + Unit::ProcDamageAndSpell(caster, target, caster ? procAttacker : 0, procVictim, procEx, heal, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, nullptr, &healInfo); } void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const @@ -6938,32 +6839,14 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con // Set trigger flag uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 hitMask = createProcHitMask(&damageInfo, SPELL_MISS_NONE); - uint32 spellTypeMask = PROC_SPELL_TYPE_NO_DMG_HEAL; + uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE) | PROC_EX_INTERNAL_DOT; if (damageInfo.damage) - { procVictim |= PROC_FLAG_TAKEN_DAMAGE; - spellTypeMask |= PROC_SPELL_TYPE_DAMAGE; - } caster->DealSpellDamage(&damageInfo, true); - DamageInfo dmgInfo(damageInfo, DOT, BASE_ATTACK, hitMask); - caster->ProcSkillsAndAuras(target, procAttacker, procVictim, spellTypeMask, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &dmgInfo, nullptr); -} - -void AuraEffect::HandleBreakableCCAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) -{ - int32 const damageLeft = GetAmount() - static_cast<int32>(eventInfo.GetDamageInfo()->GetDamage()); - - if (damageLeft <= 0) - { - aurApp->GetTarget()->RemoveAura(aurApp); - } - else - { - SetAmount(damageLeft); - } + DamageInfo dmgInfo(damageInfo, DOT); + Unit::ProcDamageAndSpell(caster, damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo); } void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) @@ -6979,7 +6862,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve } else { - LOG_ERROR("spells.aura", "AuraEffect::HandleProcTriggerSpellAuraProc: Could not trigger spell {} from aura {} proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId()); + LOG_DEBUG("spells.aura", "AuraEffect::HandleProcTriggerSpellAuraProc: Could not trigger spell {} from aura {} proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId()); } } @@ -7000,7 +6883,7 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp } else { - LOG_ERROR("spells.aura", "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Could not trigger spell {} from aura {} proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId()); + LOG_DEBUG("spells.aura", "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Could not trigger spell {} from aura {} proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId()); } } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index b7ff1e15fd..b85984341a 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -49,6 +49,7 @@ public: Aura* GetBase() const { return m_base; } void GetTargetList(std::list<Unit*>& targetList) const; void GetApplicationList(std::list<AuraApplication*>& applicationList) const; + SpellModifier* GetSpellModifier() const { return m_spellmod; } SpellInfo const* GetSpellInfo() const { return m_spellInfo; } uint32 GetId() const; @@ -95,7 +96,6 @@ public: void SendTickImmune(Unit* target, Unit* caster) const; void PeriodicTick(AuraApplication* aurApp, Unit* caster) const; - bool CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventInfo) const; void HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void CleanupTriggeredSpells(Unit* target); @@ -333,7 +333,6 @@ public: void HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) const; // aura effect proc handlers - void HandleBreakableCCAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); void HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index db70f32077..8d2add5c3a 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -411,7 +411,7 @@ Aura::Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* m_castItemGuid(itemGUID ? itemGUID : castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_castItemEntry(castItem ? castItem->GetEntry() : 0), m_applyTime(GameTime::GetGameTime().count()), m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0), m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1), - m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_procCooldown(std::chrono::steady_clock::time_point::min()), m_triggeredByAuraSpellInfo(nullptr) + m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_triggeredByAuraSpellInfo(nullptr) { if ((m_spellInfo->ManaPerSecond || m_spellInfo->ManaPerSecondPerLevel) && !m_spellInfo->HasAttribute(SPELL_ATTR2_NO_TARGET_PER_SECOND_COST)) m_timeCla = 1 * IN_MILLISECONDS; @@ -875,7 +875,7 @@ int32 Aura::CalcMaxDuration(Unit* caster) const // IsPermanent() checks max duration (which we are supposed to calculate here) if (maxDuration != -1 && modOwner) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(GetId(), maxDuration); + modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, maxDuration); return maxDuration; } @@ -885,7 +885,7 @@ void Aura::SetDuration(int32 duration, bool withMods) { if (Unit* caster = GetCaster()) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(GetId(), duration); + modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration); } m_duration = duration; SetNeedClientUpdateForTargets(); @@ -976,11 +976,11 @@ uint8 Aura::CalcMaxCharges(Unit* caster) const { uint32 maxProcCharges = m_spellInfo->ProcCharges; if (SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId())) - maxProcCharges = procEntry->Charges; + maxProcCharges = procEntry->charges; if (caster) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CHARGES>(GetId(), maxProcCharges); + modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, maxProcCharges); return maxProcCharges; } @@ -1062,6 +1062,12 @@ bool Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode, bool periodicRes // reset charges SetCharges(CalcMaxCharges()); + // FIXME: not a best way to synchronize charges, but works + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (AuraEffect* aurEff = GetEffect(i)) + if (aurEff->GetAuraType() == SPELL_AURA_ADD_FLAT_MODIFIER || aurEff->GetAuraType() == SPELL_AURA_ADD_PCT_MODIFIER) + if (SpellModifier* mod = aurEff->GetSpellModifier()) + mod->charges = GetCharges(); } SetStackAmount(stackAmount); @@ -1196,7 +1202,7 @@ int32 Aura::CalcDispelChance(Unit* auraTarget, bool offensive) const // Apply dispel mod from aura caster if (Unit* caster = GetCaster()) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RESIST_DISPEL_CHANCE>(GetId(), resistChance); + modOwner->ApplySpellMod(GetId(), SPELLMOD_RESIST_DISPEL_CHANCE, resistChance); // Dispel resistance from target SPELL_AURA_MOD_DISPEL_RESIST // Only affects offensive dispels @@ -1254,7 +1260,7 @@ void Aura::HandleAllEffects(AuraApplication* aurApp, uint8 mode, bool apply) m_effects[i]->HandleEffect(aurApp, mode, apply); } -void Aura::GetApplicationList(Unit::AuraApplicationList& applicationList) const +void Aura::GetApplicationList(std::list<AuraApplication*>& applicationList) const { for (Aura::ApplicationMap::const_iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter) { @@ -1433,9 +1439,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b } break; case 44544: // Fingers of Frost - // Refresh or add visual aura - target->CastCustomSpell(74396, SPELLVALUE_AURA_STACK, sSpellMgr->AssertSpellInfo(74396)->StackAmount, (Unit*)nullptr, true); - break; { // See if we already have the indicator aura. If not, create one. if (Aura* aur = target->GetAura(74396)) @@ -1660,6 +1663,10 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b target->CastSpell(target, 32612, true, nullptr, GetEffect(1)); target->CombatStop(); break; + case 74396: // Fingers of Frost + // Remove the IGNORE_AURASTATE aura + target->RemoveAurasDueToSpell(44544); + break; case 44401: // Missile Barrage case 48108: // Hot Streak case 57761: // Fireball! @@ -2185,17 +2192,22 @@ bool Aura::CanStackWith(Aura const* existingAura, bool remove) const return true; } -bool Aura::IsProcOnCooldown(std::chrono::steady_clock::time_point now) const +bool Aura::IsProcOnCooldown() const { - return m_procCooldown > now; + /*if (m_procCooldown) + { + if (m_procCooldown > GameTime::GetGameTime().count()) + return true; + }*/ + return false; } -void Aura::AddProcCooldown(std::chrono::steady_clock::time_point cooldownEnd) +void Aura::AddProcCooldown(uint32 /*msec*/) { - m_procCooldown = cooldownEnd; + //m_procCooldown = GameTime::GetGameTime().count() + msec; } -void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now) +void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo) { bool prepare = CallScriptPrepareProcHandlers(aurApp, eventInfo); if (!prepare) @@ -2213,101 +2225,47 @@ void Aura::PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInf ASSERT(procEntry); // cooldowns should be added to the whole aura (see 51698 area aura) - AddProcCooldown(now + procEntry->Cooldown); + AddProcCooldown(procEntry->cooldown); } -uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now) const +bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const { SpellProcEntry const* procEntry = sSpellMgr->GetSpellProcEntry(GetId()); // only auras with spell proc entry can trigger proc if (!procEntry) - return 0; - - // check spell triggering us - if (Spell const* spell = eventInfo.GetProcSpell()) - { - // Do not allow auras to proc from effect triggered from itself - if (spell->IsTriggeredByAura(m_spellInfo)) - return 0; - - // check if aura can proc when spell is triggered (exception for hunter auto shot & wands) - if (spell->IsTriggered() && !(procEntry->AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) && !(eventInfo.GetTypeMask() & AUTO_ATTACK_PROC_FLAG_MASK)) - if (!GetSpellInfo()->HasAttribute(SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED)) - return 0; - } - - // check don't break stealth attr present - if (m_spellInfo->HasAura(SPELL_AURA_MOD_STEALTH)) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (spellInfo->HasAttribute(SPELL_ATTR0_CU_DONT_BREAK_STEALTH)) - return 0; - } + return false; // check if we have charges to proc with - if (IsUsingCharges()) - { - if (!GetCharges()) - return 0; - - if (procEntry->AttributesMask & PROC_ATTR_REQ_SPELLMOD) - { - if (Spell const* spell = eventInfo.GetProcSpell()) - { - if (!spell->m_appliedMods.count(const_cast<Aura*>(this))) - { - return 0; - } - } - } - } + if (IsUsingCharges() && !GetCharges()) + return false; // check proc cooldown - if (IsProcOnCooldown(now)) - return 0; + if (IsProcOnCooldown()) + return false; + + // TODO: + // something about triggered spells triggering, and add extra attack effect // do checks against db data - if (!SpellMgr::CanSpellTriggerProcOnEvent(*procEntry, eventInfo)) - return 0; + if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo)) + return false; // do checks using conditions table ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId()); ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget()); if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions)) - return 0; + return false; // AuraScript Hook bool check = const_cast<Aura*>(this)->CallScriptCheckProcHandlers(aurApp, eventInfo); if (!check) - return 0; - - // At least one effect has to pass checks to proc aura - uint8 procEffectMask = aurApp->GetEffectMask(); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (procEffectMask & (1 << i)) - if ((procEntry->AttributesMask & (PROC_ATTR_DISABLE_EFF_0 << i)) || !GetEffect(i)->CheckEffectProc(aurApp, eventInfo)) - procEffectMask &= ~(1 << i); - } - - if (!procEffectMask) - return 0; + return false; // TODO: // do allow additional requirements for procs // this is needed because this is the last moment in which you can prevent aura charge drop on proc // and possibly a way to prevent default checks (if there're going to be any) - // Aura added by spoell can't trigger from self (prevent drop charges/do triggers) - // But except periodic and kill triggers (can triggered from self) - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - { - if (spellInfo->Id == GetId() && !(eventInfo.GetTypeMask() & (PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_KILL))) - { - return 0; - } - } - // Check if current equipment meets aura requirements // do that only for passive spells // TODO: this needs to be unified for all kinds of auras @@ -2320,7 +2278,7 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, if (GetSpellInfo()->EquippedItemClass == ITEM_CLASS_WEAPON) { if (target->ToPlayer()->IsInFeralForm()) - return 0; + return false; if (DamageInfo const* damageInfo = eventInfo.GetDamageInfo()) { @@ -2351,50 +2309,39 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, } } - if (roll_chance_f(CalcProcChance(*procEntry, eventInfo))) - return procEffectMask; - - return 0; + return roll_chance_f(CalcProcChance(*procEntry, eventInfo)); } float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const { - float chance = procEntry.Chance; + float chance = procEntry.chance; // calculate chances depending on unit with caster's data // so talents modifying chances and judgements will have properly calculated proc chance if (Unit* caster = GetCaster()) { // calculate ppm chance if present and we're using weapon - if (eventInfo.GetDamageInfo() && procEntry.ProcsPerMinute != 0) + if (eventInfo.GetDamageInfo() && procEntry.ratePerMinute != 0) { uint32 WeaponSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); - chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ProcsPerMinute, GetSpellInfo()); + chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ratePerMinute, GetSpellInfo()); } // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(GetId(), chance); + modOwner->ApplySpellMod(GetId(), SPELLMOD_CHANCE_OF_SUCCESS, chance); } return chance; } -void Aura::TriggerProcOnEvent(uint8 procEffectMask, AuraApplication* aurApp, ProcEventInfo& eventInfo) +void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) { - bool prevented = CallScriptProcHandlers(aurApp, eventInfo); - - if (!prevented) - { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (!(procEffectMask & (1 << i))) - continue; + CallScriptProcHandlers(aurApp, eventInfo); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (aurApp->HasEffect(i)) // OnEffectProc / AfterEffectProc hooks handled in AuraEffect::HandleProc() - if (aurApp->HasEffect(i)) - GetEffect(i)->HandleProc(aurApp, eventInfo); - } + GetEffect(i)->HandleProc(aurApp, eventInfo); - CallScriptAfterProcHandlers(aurApp, eventInfo); - } + CallScriptAfterProcHandlers(aurApp, eventInfo); // Remove aura if we've used last charge to proc if (IsUsingCharges() && !GetCharges()) @@ -2690,14 +2637,30 @@ void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication con bool Aura::CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo) { bool result = true; - for (auto & m_loadedScript : m_loadedScripts) + for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) { - m_loadedScript->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_PROC, aurApp); - auto hookItrEnd = m_loadedScript->DoCheckProc.end(), hookItr = m_loadedScript->DoCheckProc.begin(); + (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_PROC, aurApp); + std::list<AuraScript::CheckProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckProc.end(), hookItr = (*scritr)->DoCheckProc.begin(); for (; hookItr != hookItrEnd; ++hookItr) - result &= hookItr->Call(m_loadedScript, eventInfo); + result &= hookItr->Call(*scritr, eventInfo); - m_loadedScript->_FinishScriptCall(); + (*scritr)->_FinishScriptCall(); + } + + return result; +} + +bool Aura::CallScriptCheckAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo) +{ + bool result = true; + for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_AFTER_PROC, aurApp); + std::list<AuraScript::CheckProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckAfterProc.end(), hookItr = (*scritr)->DoCheckAfterProc.begin(); + for (; hookItr != hookItrEnd; ++hookItr) + result &= hookItr->Call(*scritr, eventInfo); + + (*scritr)->_FinishScriptCall(); } return result; @@ -2752,26 +2715,6 @@ void Aura::CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventI } } -bool Aura::CallScriptCheckEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo) -{ - bool result = true; - - for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) - { - (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC, aurApp); - std::list<AuraScript::CheckEffectProcHandler>::iterator hookItrEnd = (*scritr)->DoCheckEffectProc.end(), hookItr = (*scritr)->DoCheckEffectProc.begin(); - for (; hookItr != hookItrEnd; ++hookItr) - { - if (hookItr->IsEffectAffected(m_spellInfo, aurEff->GetEffIndex())) - result &= hookItr->Call(*scritr, aurEff, eventInfo); - } - - (*scritr)->_FinishScriptCall(); - } - - return result; -} - bool Aura::CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo) { bool preventDefault = false; diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index c33ac114d6..d98f391dc6 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -191,14 +191,18 @@ public: bool CanStackWith(Aura const* checkAura, bool remove) const; bool IsAuraStronger(Aura const* newAura) const; - bool IsProcOnCooldown(std::chrono::steady_clock::time_point now) const; - void AddProcCooldown(std::chrono::steady_clock::time_point cooldownEnd); + // Proc system + // this subsystem is not yet in use - the core of it is functional, but still some research has to be done + // and some dependant problems fixed before it can replace old proc system (for example cooldown handling) + // currently proc system functionality is implemented in Unit::ProcDamageAndSpell + bool IsProcOnCooldown() const; + void AddProcCooldown(uint32 msec); bool IsUsingCharges() const { return m_isUsingCharges; } void SetUsingCharges(bool val) { m_isUsingCharges = val; } - void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now); - uint8 GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo, std::chrono::steady_clock::time_point now) const; + void PrepareProcToTrigger(AuraApplication* aurApp, ProcEventInfo& eventInfo); + bool IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) const; float CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const; - void TriggerProcOnEvent(uint8 procEffectMask, AuraApplication* aurApp, ProcEventInfo& eventInfo); + void TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo); // AuraScript void LoadScripts(); @@ -222,7 +226,7 @@ public: // Spell Proc Hooks bool CallScriptCheckProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); - bool CallScriptCheckEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo); + bool CallScriptCheckAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); bool CallScriptPrepareProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); bool CallScriptProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); void CallScriptAfterProcHandlers(AuraApplication const* aurApp, ProcEventInfo& eventInfo); @@ -265,8 +269,6 @@ protected: bool m_isSingleTarget: 1; // true if it's a single target spell and registered at caster - can change at spell steal for example bool m_isUsingCharges: 1; - std::chrono::steady_clock::time_point m_procCooldown; - private: Unit::AuraApplicationList m_removedApplications; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 20d8ad67c2..813ef0dbe4 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -640,7 +640,7 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, m_healing = 0; m_procAttacker = 0; m_procVictim = 0; - m_hitMask = 0; + m_procEx = 0; focusObject = nullptr; m_cast_count = 0; m_glyphIndex = 0; @@ -1811,7 +1811,7 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg { uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_JUMP_TARGETS>(m_spellInfo->Id, maxTargets, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this); if (maxTargets > 1) { @@ -2273,11 +2273,12 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar } } -void Spell::prepareDataForTriggerSystem() +void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) { //========================================================================================== // Now fill data for trigger system, need know: - // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_hitMask) + // can spell trigger another or not (m_canTrigger) + // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx) //========================================================================================== m_procVictim = m_procAttacker = 0; @@ -2316,6 +2317,7 @@ void Spell::prepareDataForTriggerSystem() // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget // Because spell positivity is dependant on target } + m_procEx = PROC_EX_NONE; // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection if (m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && @@ -2324,18 +2326,31 @@ void Spell::prepareDataForTriggerSystem() m_spellInfo->SpellFamilyFlags[2] & 0x00064000)) // Explosive and Immolation Trap { m_procAttacker |= PROC_FLAG_DONE_TRAP_ACTIVATION; - - // also fill up other flags (DoAllEffectOnTarget only fills up flag if both are not set) - m_procAttacker |= PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG; - m_procVictim |= PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG; } + /* Effects which are result of aura proc from triggered spell cannot proc + to prevent chain proc of these spells */ + // Hellfire Effect - trigger as DOT if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[0] & 0x00000040) { m_procAttacker = PROC_FLAG_DONE_PERIODIC; m_procVictim = PROC_FLAG_TAKEN_PERIODIC; } + + // Ranged autorepeat attack is set as triggered spell - ignore it + if (!(m_procAttacker & PROC_FLAG_DONE_RANGED_AUTO_ATTACK)) + { + if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS && + (m_spellInfo->HasAttribute(SPELL_ATTR2_ACTIVE_THREAT) || + m_spellInfo->HasAttribute(SPELL_ATTR3_NOT_A_PROC))) + m_procEx |= PROC_EX_INTERNAL_CANT_PROC; + else if (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) + m_procEx |= PROC_EX_INTERNAL_TRIGGERED; + } + // Totem casts require spellfamilymask defined in spell_proc_event to proc + if (m_originalCaster && m_caster != m_originalCaster && m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsTotem() && m_caster->IsControlledByPlayer()) + m_procEx |= PROC_EX_INTERNAL_REQ_FAMILY; } void Spell::CleanupTargetList() @@ -2347,32 +2362,6 @@ void Spell::CleanupTargetList() m_delayTrajectory = 0; } -class ProcReflectDelayed : public BasicEvent -{ -public: - ProcReflectDelayed(Unit* owner, ObjectGuid casterGuid) : _victim(owner), _casterGuid(casterGuid) { } - - bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override - { - Unit* caster = ObjectAccessor::GetUnit(*_victim, _casterGuid); - if (!caster) - return true; - - uint32 const typeMaskActor = PROC_FLAG_NONE; - uint32 const typeMaskActionTarget = PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG; - uint32 const spellTypeMask = PROC_SPELL_TYPE_DAMAGE | PROC_SPELL_TYPE_NO_DMG_HEAL; - uint32 const spellPhaseMask = PROC_SPELL_PHASE_NONE; - uint32 const hitMask = PROC_HIT_REFLECT; - - caster->ProcSkillsAndAuras(_victim, typeMaskActor, typeMaskActionTarget, spellTypeMask, spellPhaseMask, hitMask, nullptr, nullptr, nullptr); - return true; - } - -private: - Unit* _victim; - ObjectGuid _casterGuid; -}; - void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/) { for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) @@ -2384,8 +2373,11 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= return; if (checkIfValid) - if (m_spellInfo->CheckTarget(m_caster, target, implicit) != SPELL_CAST_OK) // skip stealth checks for AOE + { + SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit); + if (res != SPELL_CAST_OK) return; + } // Check for effect immune skip if immuned for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) @@ -2456,22 +2448,23 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= targetInfo.timeDelay = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f); // Calculate minimum incoming time - if (!m_delayMoment || m_delayMoment > targetInfo.timeDelay) + if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay) m_delayMoment = targetInfo.timeDelay; } else - targetInfo.timeDelay = 0ULL; + targetInfo.timeDelay = 0LL; // If target reflect spell back to caster if (targetInfo.missCondition == SPELL_MISS_REFLECT) { // Calculate reflected spell result on caster - targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, false); // can't reflect twice + targetInfo.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, m_canReflect); - // Proc spell reflect aura when missile hits the original target - target->m_Events.AddEvent(new ProcReflectDelayed(target, m_originalCasterGUID), target->m_Events.CalculateTime(targetInfo.timeDelay)); + if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell + targetInfo.reflectResult = SPELL_MISS_PARRY; // Increase time interval for reflected spells by 1.5 + m_caster->m_Events.AddEvent(new ReflectEvent(m_caster, targetInfo.targetGUID, m_spellInfo), m_caster->m_Events.CalculateTime(targetInfo.timeDelay)); targetInfo.timeDelay += targetInfo.timeDelay >> 1; m_spellFlags |= SPELL_FLAG_REFLECTED; @@ -2552,7 +2545,7 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask) if (dist < 5.0f) dist = 5.0f; target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f)); - if (!m_delayMoment || m_delayMoment > target.timeDelay) + if (m_delayMoment == 0 || m_delayMoment > target.timeDelay) m_delayMoment = target.timeDelay; } else @@ -2667,8 +2660,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) PrepareScriptHitHandlers(); CallScriptBeforeHitHandlers(missInfo); - // Spells with this flag cannot trigger if effect is casted on self - bool const canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_CASTER_PROCS) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE2); + //Spells with this flag cannot trigger if effect is casted on self + bool canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_SUPRESS_CASTER_PROCS) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE2); bool reflectedSpell = missInfo == SPELL_MISS_REFLECT; Unit* spellHitTarget = nullptr; @@ -2706,14 +2699,18 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID) { m_needComboPoints = false; + // Restore spell mods for a miss/dodge/parry Cold Blood + // TODO: check how broad this rule should be + if (m_caster->GetTypeId() == TYPEID_PLAYER && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY)) + m_caster->ToPlayer()->RestoreSpellMods(this, 14177); } // Fill base trigger info uint32 procAttacker = m_procAttacker; uint32 procVictim = m_procVictim; - uint32 hitMask = m_hitMask; + uint32 procEx = m_procEx; - // Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now + // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now if (canEffectTrigger && !procAttacker && !procVictim) { bool positive = true; @@ -2769,11 +2766,11 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (crit) { - hitMask |= PROC_HIT_CRITICAL; + procEx |= PROC_EX_CRITICAL_HIT; addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr); } else - hitMask |= PROC_HIT_NORMAL; + procEx |= PROC_EX_NORMAL_HIT; HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask()); @@ -2781,20 +2778,27 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (GetSpellValue()->ForcedCritResult) { crit = true; - hitMask |= PROC_HIT_CRITICAL; + procEx |= PROC_EX_CRITICAL_HIT; } int32 gain = caster->HealBySpell(healInfo, crit); unitTarget->getHostileRefMgr().threatAssist(caster, float(gain) * 0.5f, m_spellInfo); m_healing = gain; - // Do triggers for unit + // Xinef: if heal acutally healed something, add no overheal flag + if (m_healing) + procEx |= PROC_EX_NO_OVERHEAL; + + // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (canEffectTrigger) - caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, nullptr, &healInfo); + Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo); } // Do damage and triggers else if (m_damage > 0) { + caster->SetLastDamagedTargetGuid(unitTarget->GetGUID()); + // Fill base damage struct (unitTarget - is real spell target) SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo, m_spellSchoolMask); @@ -2854,7 +2858,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (reflectedSpell) effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit); - hitMask |= createProcHitMask(&damageInfo, missInfo); + procEx |= createProcExtendMask(&damageInfo, missInfo); procVictim |= PROC_FLAG_TAKEN_DAMAGE; caster->DealSpellDamage(&damageInfo, true, this); @@ -2862,15 +2866,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // do procs after damage, eg healing effects // no need to check if target is alive, done in procdamageandspell - // Do triggers for unit + // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (canEffectTrigger) { - DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, hitMask); - caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, hitMask, this, &dmgInfo, nullptr); + DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE); + Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + m_triggeredByAuraSpell.effectIndex, this, &dmgInfo); if (caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 && m_spellInfo->HasAttribute(SPELL_ATTR4_SUPRESS_WEAPON_PROCS) == 0 && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) - caster->ToPlayer()->CastItemCombatSpell(dmgInfo); + caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); } m_damage = damageInfo.damage; @@ -2880,16 +2885,19 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) { // Fill base damage struct (unitTarget - is real spell target) SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo, m_spellSchoolMask); - hitMask |= createProcHitMask(&damageInfo, missInfo); - // Do triggers for unit + procEx |= createProcExtendMask(&damageInfo, missInfo); + // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (canEffectTrigger) { - DamageInfo spellNoDamageInfo(damageInfo, NODAMAGE, m_attackType, hitMask); - caster->ProcSkillsAndAuras(unitTarget, procAttacker, procVictim, PROC_SPELL_TYPE_NO_DMG_HEAL, PROC_SPELL_PHASE_HIT, hitMask, this, &spellNoDamageInfo, nullptr); + DamageInfo dmgInfo(damageInfo, NODAMAGE); + Unit::ProcDamageAndSpell(caster, unitTarget, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + m_triggeredByAuraSpell.effectIndex, this, &dmgInfo); - if (caster->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) && - !m_spellInfo->HasAttribute(SPELL_ATTR4_SUPRESS_WEAPON_PROCS) && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) - caster->ToPlayer()->CastItemCombatSpell(spellNoDamageInfo); + // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also + // Xinef: ofc count only spells that HIT the target, little hack used to fool the system + if ((procEx & PROC_EX_NORMAL_HIT || procEx & PROC_EX_CRITICAL_HIT) && caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 && + m_spellInfo->HasAttribute(SPELL_ATTR4_SUPRESS_WEAPON_PROCS) == 0 && (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) + caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, procEx); } // Failed Pickpocket, reveal rogue @@ -3113,6 +3121,10 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic); + // xinef: if aura was not refreshed, add proc ex + if (!refresh) + m_procEx |= PROC_EX_NO_AURA_REFRESH; + if (m_spellAura) { // Set aura stack amount to desired value @@ -3241,8 +3253,8 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask) // info confirmed with retail sniffs of permafrost and shadow weaving if (!m_hitTriggerSpells.empty()) { - int32 _duration = 0; - for (auto i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i) + int _duration = 0; + for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i) { if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance)) { @@ -3358,7 +3370,7 @@ bool Spell::UpdateChanneledTargetList() } if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, range, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this); // xinef: add little tolerance level range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd @@ -3521,7 +3533,7 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const } // Prepare data for triggers - prepareDataForTriggerSystem(); + prepareDataForTriggerSystem(triggeredByAura); // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail) m_casttime = (_triggeredCastFlags & TRIGGERED_CAST_DIRECTLY) ? 0 : m_spellInfo->CalcCastTime(m_caster, this); @@ -3705,6 +3717,10 @@ void Spell::cancel(bool bySelf) if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->NeedSendSpectatorData()) ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999); + // spell is canceled-take mods and clear list + if (Player* player = m_caster->GetSpellModOwner()) + player->RemoveSpellMods(this); + m_appliedMods.clear(); break; default: @@ -3929,14 +3945,26 @@ void Spell::_cast(bool skipCheck) } } - uint32 hitMask = m_hitMask; + uint32 procEx = PROC_EX_NORMAL_HIT; - if (!(hitMask & PROC_HIT_CRITICAL)) + for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { - hitMask |= PROC_HIT_NORMAL; + if (ihit->missCondition != SPELL_MISS_NONE) + { + continue; + } + + if (!ihit->crit) + { + continue; + } + + procEx |= PROC_EX_CRITICAL_HIT; + break; } - m_originalCaster->ProcSkillsAndAuras(m_originalCaster, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_CAST, hitMask, this, nullptr, nullptr); + Unit::ProcDamageAndSpell(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, procEx, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_CAST); } if (modOwner) @@ -3957,6 +3985,11 @@ void Spell::_cast(bool skipCheck) if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true)) m_caster->ClearUnitState(UNIT_STATE_CASTING); + // remove all applied mods at this point + // dont allow user to use them twice in case spell did not reach current target + if (modOwner) + modOwner->RemoveSpellMods(this); + // Xinef: why do we keep focus after spell is sent to air? // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc // Xinef: we get focused to it out of nowhere... @@ -4049,7 +4082,7 @@ void Spell::handle_immediate() // First mod_duration then haste - see Missile Barrage // Apply duration mod if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); // Apply haste mods if (m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC)) @@ -4073,14 +4106,8 @@ void Spell::handle_immediate() // process immediate effects (items, ground, etc.) also initialize some variables _handle_immediate_phase(); - // consider spell hit for some spells without target, so they may proc on finish phase correctly - if (m_UniqueTargetInfo.empty()) - m_hitMask = PROC_HIT_NORMAL; - else - { - for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - DoAllEffectOnTarget(&(*ihit)); - } + for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + DoAllEffectOnTarget(&(*ihit)); for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit) DoAllEffectOnTarget(&(*ihit)); @@ -4227,8 +4254,10 @@ void Spell::_handle_finish_phase() m_caster->AddComboPoints(m_comboTarget, m_comboPointGain); } - if (m_caster->m_extraAttacks && GetSpellInfo()->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) - m_caster->HandleProcExtraAttackFor(m_caster->GetVictim()); + if (m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + { + m_caster->SetLastExtraAttackSpell(m_spellInfo->Id); + } if (!IsAutoRepeat() && !IsNextMeleeSwingSpell()) if (m_caster->GetCharmerOrOwnerPlayerOrPlayerItself()) @@ -4257,13 +4286,25 @@ void Spell::_handle_finish_phase() } } - uint32 hitMask = m_hitMask; - if (!(hitMask & PROC_HIT_CRITICAL)) + uint32 procEx = PROC_EX_NORMAL_HIT; + for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) { - hitMask |= PROC_HIT_NORMAL; + if (ihit->missCondition != SPELL_MISS_NONE) + { + continue; + } + + if (!ihit->crit) + { + continue; + } + + procEx |= PROC_EX_CRITICAL_HIT; + break; } - m_originalCaster->ProcSkillsAndAuras(m_originalCaster, procAttacker, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_FINISH, hitMask, this, nullptr, nullptr); + Unit::ProcDamageAndSpell(m_originalCaster, m_originalCaster, procAttacker, PROC_FLAG_NONE, procEx, 1, BASE_ATTACK, m_spellInfo, m_triggeredByAuraSpell.spellInfo, + m_triggeredByAuraSpell.effectIndex, this, nullptr, nullptr, PROC_SPELL_PHASE_FINISH); } } @@ -4453,6 +4494,11 @@ void Spell::finish(bool ok) if (m_caster->GetTypeId() == TYPEID_PLAYER && !m_triggeredByAuraSpell) m_caster->ToPlayer()->UpdatePotionCooldown(this); + // Take mods after trigger spell (needed for 14177 to affect 48664) + // mods are taken only on succesfull cast and independantly from targets of the spell + if (Player* player = m_caster->GetSpellModOwner()) + player->RemoveSpellMods(this); + // xinef: clear reactive auras states after spell cast if (m_spellInfo->CasterAuraState == AURA_STATE_DEFENSE || m_spellInfo->CasterAuraState == AURA_STATE_HUNTER_PARRY) m_caster->ModifyAuraState(AuraStateType(m_spellInfo->CasterAuraState), false); @@ -5237,7 +5283,7 @@ void Spell::TakePower() hit = false; //lower spell cost on fail (by talent aura) if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_SPELL_COST_REFUND_ON_FAIL>(m_spellInfo->Id, m_powerCost, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this); } break; } @@ -5338,7 +5384,7 @@ SpellCastResult Spell::CheckRuneCost(uint32 RuneCostID) { runeCost[i] = src->RuneCost[i]; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this); } runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later @@ -5378,7 +5424,7 @@ void Spell::TakeRunePower(bool didHit) { runeCost[i] = runeCostData->RuneCost[i]; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this); } runeCost[RUNE_DEATH] = 0; // calculated later @@ -5775,11 +5821,7 @@ SpellCastResult Spell::CheckCast(bool strict) // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy if (!m_triggeredByAuraSpell || m_targets.GetUnitTarget() != m_caster || !(m_spellInfo->GetExplicitTargetMask() & TARGET_FLAG_UNIT_ENEMY)) { - Unit* caster = m_caster; - if (m_originalCaster && m_caster->GetEntry() != WORLD_TRIGGER) // Do a simplified check for gameobject casts - caster = m_originalCaster; - - SpellCastResult castResult = m_spellInfo->CheckExplicitTarget(caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget()); + SpellCastResult castResult = m_spellInfo->CheckExplicitTarget((m_originalCaster && m_caster->GetEntry() != WORLD_TRIGGER) ? m_originalCaster : m_caster, m_targets.GetObjectTarget(), m_targets.GetItemTarget()); if (castResult != SPELL_CAST_OK) return castResult; } @@ -5787,7 +5829,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (Unit* target = m_targets.GetUnitTarget()) { - SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, m_caster->GetEntry() == WORLD_TRIGGER); // skip stealth checks for GO casts + SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false); if (castResult != SPELL_CAST_OK) return castResult; @@ -6983,7 +7025,7 @@ SpellCastResult Spell::CheckRange(bool strict) range_type = SPELL_RANGE_RANGED; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, max_range, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this); // xinef: dont check max_range to strictly after cast if (range_type != SPELL_RANGE_MELEE && !strict) @@ -7697,7 +7739,7 @@ void Spell::Delayed() // only called in DealDamage() //check pushback reduce int32 delaytime = 500; // spellcasting delay is normally 500ms int32 delayReduce = 100; // must be initialized to 100 for percent modifiers - m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this); + m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this); delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100; if (delayReduce >= 100) return; @@ -7735,7 +7777,7 @@ void Spell::DelayedChannel() int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit int32 delayReduce = 100; // must be initialized to 100 for percent modifiers - m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this); + m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this); delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100; if (delayReduce >= 100) return; @@ -8115,6 +8157,14 @@ bool SpellEvent::IsDeletable() const return m_Spell->IsDeletable(); } +bool ReflectEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) +{ + Unit* target = ObjectAccessor::GetUnit(*_caster, _targetGUID); + if (target && _caster->IsInMap(target)) + Unit::ProcDamageAndSpell(_caster, target, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_REFLECT, 1, BASE_ATTACK, _spellInfo); + return true; +} + bool Spell::IsValidDeadOrAliveTarget(Unit const* target) const { if (target->IsAlive()) @@ -8690,24 +8740,26 @@ void Spell::PrepareTriggersExecutedOnHit() // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster // and to correctly calculate proc chance when combopoints are present Unit::AuraEffectList const& targetTriggers = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER); - for (AuraEffect const* aurEff : targetTriggers) + for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i) { - if (!aurEff->IsAffectedOnSpell(m_spellInfo)) + if (!(*i)->IsAffectedOnSpell(m_spellInfo)) continue; - - SpellInfo const* auraSpellInfo = aurEff->GetSpellInfo(); - uint32 auraSpellIdx = aurEff->GetEffIndex(); + SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo(); + uint32 auraSpellIdx = (*i)->GetEffIndex(); if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell)) { // calculate the chance using spell base amount, because aura amount is not updated on combo-points change // this possibly needs fixing - int32 auraBaseAmount = aurEff->GetBaseAmount(); + int32 auraBaseAmount = (*i)->GetBaseAmount(); // proc chance is stored in effect amount int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount); - chance *= aurEff->GetBase()->GetStackAmount(); - // build trigger and add to the list - m_hitTriggerSpells.emplace_back(spellInfo, auraSpellInfo, chance); + HitTriggerSpell spellTriggerInfo; + spellTriggerInfo.triggeredSpell = spellInfo; + spellTriggerInfo.triggeredByAura = auraSpellInfo; + spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex(); + spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount(); + m_hitTriggerSpells.push_back(spellTriggerInfo); } } } @@ -8752,8 +8804,8 @@ void Spell::TriggerGlobalCooldown() if (m_spellInfo->StartRecoveryTime >= MIN_GCD && m_spellInfo->StartRecoveryTime <= MAX_GCD) { // gcd modifier auras are applied only to own spells and only players have such mods - if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_GLOBAL_COOLDOWN>(m_spellInfo->Id, gcd, this); + if (m_caster->GetTypeId() == TYPEID_PLAYER) + m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this); // Apply haste rating if (m_spellInfo->StartRecoveryCategory == 133 && m_spellInfo->StartRecoveryTime == 1500 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE && @@ -8762,7 +8814,10 @@ void Spell::TriggerGlobalCooldown() gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED)); } - RoundToInterval<int32>(gcd, MIN_GCD, MAX_GCD); + if (gcd < MIN_GCD) + gcd = MIN_GCD; + else if (gcd > MAX_GCD) + gcd = MAX_GCD; } // Only players or controlled units have global cooldown diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 642ceda362..f6e3e646f6 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -414,7 +414,7 @@ public: void EffectCastButtons(SpellEffIndex effIndex); void EffectRechargeManaGem(SpellEffIndex effIndex); - typedef std::unordered_set<Aura*> UsedSpellMods; + typedef std::set<Aura*> UsedSpellMods; void InitExplicitTargets(SpellCastTargets const& targets); void SelectExplicitTargets(); @@ -553,9 +553,6 @@ public: bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; } bool IsAutoActionResetSpell() const; bool IsIgnoringCooldowns() const; - bool IsProcDisabled() const { return (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) != 0; } - - bool IsTriggeredByAura(SpellInfo const* auraSpellInfo) const { return (auraSpellInfo == m_triggeredByAuraSpell.spellInfo); } bool IsDeletable() const { return !m_referencedFromCurrentSpell && !m_executedCurrently; } void SetReferencedFromCurrent(bool yes) { m_referencedFromCurrentSpell = yes; } @@ -673,8 +670,8 @@ public: // ****************************************** uint32 m_procAttacker; // Attacker trigger flags uint32 m_procVictim; // Victim trigger flags - uint32 m_hitMask; - void prepareDataForTriggerSystem(); + uint32 m_procEx; + void prepareDataForTriggerSystem(AuraEffect const* triggeredByAura); // ***************************************** // Spell target subsystem @@ -742,9 +739,6 @@ public: struct HitTriggerSpell { - HitTriggerSpell(SpellInfo const* spellInfo, SpellInfo const* auraSpellInfo, int32 procChance) : - triggeredSpell(spellInfo), triggeredByAura(auraSpellInfo), chance(procChance) { } - SpellInfo const* triggeredSpell; SpellInfo const* triggeredByAura; uint8 triggeredByEffIdx; @@ -753,7 +747,7 @@ public: bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura = nullptr) const; void PrepareTriggersExecutedOnHit(); - typedef std::vector<HitTriggerSpell> HitTriggerSpellList; + typedef std::list<HitTriggerSpell> HitTriggerSpellList; HitTriggerSpellList m_hitTriggerSpells; // effect helpers @@ -844,4 +838,17 @@ namespace Acore } typedef void(Spell::*pEffect)(SpellEffIndex effIndex); + +class ReflectEvent : public BasicEvent +{ + public: + ReflectEvent(Unit* caster, ObjectGuid targetGUID, SpellInfo const* spellInfo) : _caster(caster), _targetGUID(targetGUID), _spellInfo(spellInfo) { } + bool Execute(uint64 e_time, uint32 p_time) override; + + protected: + Unit* _caster; + ObjectGuid _targetGUID; + SpellInfo const* _spellInfo; +}; + #endif diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h index d3bd7d3db1..f3e08fc34d 100644 --- a/src/server/game/Spells/SpellDefines.h +++ b/src/server/game/Spells/SpellDefines.h @@ -72,38 +72,38 @@ enum SpellAuraInterruptFlags AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE), }; -enum SpellModOp : uint8 +enum SpellModOp { - SPELLMOD_DAMAGE = 0, - SPELLMOD_DURATION = 1, - SPELLMOD_THREAT = 2, - SPELLMOD_EFFECT1 = 3, - SPELLMOD_CHARGES = 4, - SPELLMOD_RANGE = 5, - SPELLMOD_RADIUS = 6, - SPELLMOD_CRITICAL_CHANCE = 7, - SPELLMOD_ALL_EFFECTS = 8, - SPELLMOD_NOT_LOSE_CASTING_TIME = 9, - SPELLMOD_CASTING_TIME = 10, - SPELLMOD_COOLDOWN = 11, - SPELLMOD_EFFECT2 = 12, - SPELLMOD_IGNORE_ARMOR = 13, - SPELLMOD_COST = 14, - SPELLMOD_CRIT_DAMAGE_BONUS = 15, - SPELLMOD_RESIST_MISS_CHANCE = 16, - SPELLMOD_JUMP_TARGETS = 17, - SPELLMOD_CHANCE_OF_SUCCESS = 18, - SPELLMOD_ACTIVATION_TIME = 19, - SPELLMOD_DAMAGE_MULTIPLIER = 20, - SPELLMOD_GLOBAL_COOLDOWN = 21, - SPELLMOD_DOT = 22, - SPELLMOD_EFFECT3 = 23, - SPELLMOD_BONUS_MULTIPLIER = 24, + SPELLMOD_DAMAGE = 0, + SPELLMOD_DURATION = 1, + SPELLMOD_THREAT = 2, + SPELLMOD_EFFECT1 = 3, + SPELLMOD_CHARGES = 4, + SPELLMOD_RANGE = 5, + SPELLMOD_RADIUS = 6, + SPELLMOD_CRITICAL_CHANCE = 7, + SPELLMOD_ALL_EFFECTS = 8, + SPELLMOD_NOT_LOSE_CASTING_TIME = 9, + SPELLMOD_CASTING_TIME = 10, + SPELLMOD_COOLDOWN = 11, + SPELLMOD_EFFECT2 = 12, + SPELLMOD_IGNORE_ARMOR = 13, + SPELLMOD_COST = 14, + SPELLMOD_CRIT_DAMAGE_BONUS = 15, + SPELLMOD_RESIST_MISS_CHANCE = 16, + SPELLMOD_JUMP_TARGETS = 17, + SPELLMOD_CHANCE_OF_SUCCESS = 18, + SPELLMOD_ACTIVATION_TIME = 19, + SPELLMOD_DAMAGE_MULTIPLIER = 20, + SPELLMOD_GLOBAL_COOLDOWN = 21, + SPELLMOD_DOT = 22, + SPELLMOD_EFFECT3 = 23, + SPELLMOD_BONUS_MULTIPLIER = 24, // spellmod 25 - SPELLMOD_PROC_PER_MINUTE = 26, - SPELLMOD_VALUE_MULTIPLIER = 27, - SPELLMOD_RESIST_DISPEL_CHANCE = 28, - SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell + SPELLMOD_PROC_PER_MINUTE = 26, + SPELLMOD_VALUE_MULTIPLIER = 27, + SPELLMOD_RESIST_DISPEL_CHANCE = 28, + SPELLMOD_CRIT_DAMAGE_BONUS_2 = 29, //one not used spell SPELLMOD_SPELL_COST_REFUND_ON_FAIL = 30 }; @@ -141,10 +141,9 @@ enum TriggerCastFlags TRIGGERED_IGNORE_SET_FACING = 0x00000200, //! Will not adjust facing to target (if any) TRIGGERED_IGNORE_SHAPESHIFT = 0x00000400, //! Will ignore shapeshift checks TRIGGERED_IGNORE_CASTER_AURASTATE = 0x00000800, //! Will ignore caster aura states including combat requirements and death state - TRIGGERED_DISALLOW_PROC_EVENTS = 0x00001000, //! Disallows proc events from triggered spell (default) TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE = 0x00002000, //! Will ignore mounted/on vehicle restrictions TRIGGERED_IGNORE_CASTER_AURAS = 0x00010000, //! Will ignore caster aura restrictions or requirements - // reuse 0x00020000 + TRIGGERED_DISALLOW_PROC_EVENTS = 0x00020000, //! Disallows proc events from triggered spell (default) TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions TRIGGERED_FULL_MASK = 0x0007FFFF, //! Used when doing CastSpell with triggered == true TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index b847c8f139..87dbb64a6a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -310,8 +310,7 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage); else { - DamageInfo dmgInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); - m_caster->CalcAbsorbResist(dmgInfo); + DamageInfo dmgInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE); uint32 absorb = dmgInfo.GetAbsorb(); uint32 resist = dmgInfo.GetResist(); @@ -2343,7 +2342,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) int32 duration = m_spellInfo->GetDuration(); if (Player* modOwner = m_originalCaster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); TempSummon* summon = nullptr; @@ -3149,7 +3148,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex) int32 duration = m_spellInfo->GetDuration(); if(Player* modOwner = m_originalCaster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); Player* owner = m_originalCaster->ToPlayer(); if (!owner && m_originalCaster->ToCreature()->IsTotem()) @@ -3723,7 +3722,6 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex) { int32 duration = m_originalCaster->ModSpellDuration(m_spellInfo, unitTarget, m_originalCaster->CalcSpellDuration(m_spellInfo), false, 1 << effIndex); unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/); - m_originalCaster->ProcSkillsAndAuras(unitTarget, PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_HIT, PROC_HIT_INTERRUPT, nullptr, nullptr, nullptr); } ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id); unitTarget->InterruptSpell(CurrentSpellTypes(i), false); @@ -4684,17 +4682,18 @@ void Spell::EffectResurrect(SpellEffIndex effIndex) void Spell::EffectAddExtraAttacks(SpellEffIndex effIndex) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + { return; + } - if (!unitTarget || !unitTarget->IsAlive() || !unitTarget->GetVictim()) - return; - - if (unitTarget->m_extraAttacks) + if (!unitTarget || !unitTarget->IsAlive()) + { return; + } - unitTarget->m_extraAttacks = damage; + unitTarget->AddExtraAttacks(damage); - ExecuteLogEffectExtraAttacks(effIndex, unitTarget->GetVictim(), damage); + ExecuteLogEffectExtraAttacks(effIndex, unitTarget, damage); } void Spell::EffectParry(SpellEffIndex /*effIndex*/) @@ -5817,8 +5816,19 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex) m_runesState = m_caster->ToPlayer()->GetRunesState(); uint32 count = damage; - if (count == 0) - count = 1; + if (count == 0) count = 1; + for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j) + { + if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue)) + { + if (m_spellInfo->Id == 45529) + if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) + continue; + player->SetRuneCooldown(j, 0); + player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period + --count; + } + } // Blood Tap if (m_spellInfo->Id == 45529 && count > 0) @@ -5826,10 +5836,10 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex) for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l) { // Check if both runes are on cd as that is the only time when this needs to come into effect - if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RUNE_BLOOD) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RUNE_BLOOD)) + if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB))) { // Should always update the rune with the lowest cd - if (l + 1 < MAX_RUNES && player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1)) + if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1)) l++; player->SetRuneCooldown(l, 0); player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period @@ -5840,15 +5850,6 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex) } } - for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j) - { - if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue)) - { - player->SetRuneCooldown(j, 0); - --count; - } - } - // Empower rune weapon if (m_spellInfo->Id == 47568) { @@ -5858,7 +5859,7 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex) for (uint32 i = 0; i < MAX_RUNES; ++i) { - if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST)) + if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH)) { player->SetRuneCooldown(i, 0); player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period @@ -6060,7 +6061,7 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* int32 duration = m_spellInfo->GetDuration(); if (Player* modOwner = m_originalCaster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; Map* map = caster->GetMap(); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 8d24dd6df3..a9a73f07c9 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -524,7 +524,7 @@ float SpellEffectInfo::CalcValueMultiplier(Unit* caster, Spell* spell) const { float multiplier = ValueMultiplier; if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr)) - modOwner->ApplySpellMod<SPELLMOD_VALUE_MULTIPLIER>(_spellInfo->Id, multiplier, spell); + modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_VALUE_MULTIPLIER, multiplier, spell); return multiplier; } @@ -532,7 +532,7 @@ float SpellEffectInfo::CalcDamageMultiplier(Unit* caster, Spell* spell) const { float multiplier = DamageMultiplier; if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr)) - modOwner->ApplySpellMod<SPELLMOD_DAMAGE_MULTIPLIER>(_spellInfo->Id, multiplier, spell); + modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_DAMAGE_MULTIPLIER, multiplier, spell); return multiplier; } @@ -552,7 +552,7 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const radius += RadiusEntry->RadiusPerLevel * caster->getLevel(); radius = std::min(radius, RadiusEntry->RadiusMax); if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RADIUS>(_spellInfo->Id, radius, spell); + modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_RADIUS, radius, spell); } return radius; @@ -831,7 +831,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) SpellVisual = spellEntry->SpellVisual; SpellIconID = spellEntry->SpellIconID; ActiveIconID = spellEntry->ActiveIconID; - Priority = spellEntry->SpellPriority; + SpellPriority = spellEntry->SpellPriority; SpellName = spellEntry->SpellName; Rank = spellEntry->Rank; MaxTargetLevel = spellEntry->MaxTargetLevel; @@ -1268,26 +1268,6 @@ bool SpellInfo::IsAutoRepeatRangedSpell() const return AttributesEx2 & SPELL_ATTR2_AUTO_REPEAT; } -bool SpellInfo::IsAffected(uint32 familyName, flag96 const& familyFlags) const -{ - if (!familyName) - { - return true; - } - - if (familyName != SpellFamilyName) - { - return false; - } - - if (familyFlags && !(familyFlags & SpellFamilyFlags)) - { - return false; - } - - return true; -} - bool SpellInfo::IsAffectedBySpellMods() const { return !(AttributesEx3 & SPELL_ATTR3_IGNORE_CASTER_MODIFIERS); @@ -1312,7 +1292,15 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const return true; } - return IsAffected(affectSpell->SpellFamilyName, mod->mask); + // False if affect_spell == nullptr or spellFamily not equal + if (affectSpell->SpellFamilyName != SpellFamilyName) + return false; + + // true + if (mod->mask & SpellFamilyFlags) + return true; + + return false; } bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const @@ -2323,7 +2311,7 @@ float SpellInfo::GetMaxRange(bool positive, Unit* caster, Spell* spell) const range = RangeEntry->RangeMax[0]; if (caster) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RANGE>(Id, range, spell); + modOwner->ApplySpellMod(Id, SPELLMOD_RANGE, range, spell); return range; } @@ -2458,7 +2446,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, S // Apply cost mod by spell if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_COST>(Id, powerCost, spell); + modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost, spell); if (!caster->IsControlledByPlayer()) { diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 5b8ad7a9bb..dc300600b2 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -377,7 +377,7 @@ public: std::array<uint32, 2> SpellVisual; uint32 SpellIconID; uint32 ActiveIconID; - uint32 Priority; + uint32 SpellPriority; std::array<char const*, 16> SpellName; std::array<char const*, 16> Rank; uint32 MaxTargetLevel; @@ -463,8 +463,6 @@ public: bool IsRangedWeaponSpell() const; bool IsAutoRepeatRangedSpell() const; - bool IsAffected(uint32 familyName, flag96 const& familyFlags) const; - bool IsAffectedBySpellMods() const; bool IsAffectedBySpellMod(SpellModifier const* mod) const; diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index c47169b9d8..e9f2479795 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -171,7 +171,7 @@ void SpellMgr::LoadSpellInfoCorrections() 53232, // Rapid Killing (Rank 2) }, [](SpellInfo* spellInfo) { - spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED; // Entries were not updated after spell effect change, we have to do that manually + spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_FROM_PROCS; // Entries were not updated after spell effect change, we have to do that manually }); ApplySpellFix({ @@ -257,7 +257,7 @@ void SpellMgr::LoadSpellInfoCorrections() ApplySpellFix({ 57761 }, [](SpellInfo* spellInfo) { spellInfo->ProcCharges = 1; - spellInfo->Priority = 50; + spellInfo->SpellPriority = 50; }); // Tidal Wave @@ -272,10 +272,10 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE; }); - // Death and Decay - ApplySpellFix({ 52212 }, [](SpellInfo* spellInfo) + // Ascendance (Talisman of Ascendance trinket) + ApplySpellFix({ 28200 }, [](SpellInfo* spellInfo) { - spellInfo->AttributesEx6 |= SPELL_ATTR6_IGNORE_PHASE_SHIFT; + spellInfo->ProcCharges = 6; }); // The Eye of Acherus (no spawn in phase 2 in db) @@ -4458,10 +4458,6 @@ void SpellMgr::LoadSpellInfoCorrections() } } - // disable proc for magnet auras, they're handled differently - if (spellInfo->HasAura(SPELL_AURA_SPELL_MAGNET)) - spellInfo->ProcFlags = 0; - if (spellInfo->ActiveIconID == 2158) // flight { spellInfo->Attributes |= SPELL_ATTR0_PASSIVE; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 866a1a7b1a..8d9524bf53 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -727,86 +727,222 @@ void SpellMgr::GetSetOfSpellsInSpellGroupWithFlag(uint32 group_id, SpellGroupSpe availableElixirs.insert(itr->first); // insert spell id } -SpellProcEntry const* SpellMgr::GetSpellProcEntry(uint32 spellId) const +SpellProcEventEntry const* SpellMgr::GetSpellProcEvent(uint32 spellId) const { - SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId); - if (itr != mSpellProcMap.end()) + SpellProcEventMap::const_iterator itr = mSpellProcEventMap.find(spellId); + if (itr != mSpellProcEventMap.end()) return &itr->second; return nullptr; } -bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) +bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, ProcEventInfo const& eventInfo, bool active) const { - // proc type doesn't match - if (!(eventInfo.GetTypeMask() & procEntry.ProcFlags)) + // No extra req need + uint32 procEvent_procEx = PROC_EX_NONE; + uint32 procEvent_procPhase = PROC_SPELL_PHASE_HIT; + + uint32 procFlags = eventInfo.GetTypeMask(); + uint32 procExtra = eventInfo.GetHitMask(); + uint32 procPhase = eventInfo.GetSpellPhaseMask(); + SpellInfo const* procSpellInfo = eventInfo.GetSpellInfo(); + + // check prockFlags for condition + if ((procFlags & EventProcFlag) == 0) return false; - // check XP or honor target requirement - if (procEntry.AttributesMask & PROC_ATTR_REQ_EXP_OR_HONOR) - if (Player* actor = eventInfo.GetActor()->ToPlayer()) - if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget())) + // Xinef: Always trigger for this, including TAKEN_DAMAGE + if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_DEATH | PROC_FLAG_TAKEN_DAMAGE)) + return true; + + bool hasFamilyMask = false; + + if (procFlags & PROC_FLAG_DONE_PERIODIC) + { + if (procExtra & PROC_EX_INTERNAL_HOT) + { + if (EventProcFlag == PROC_FLAG_DONE_PERIODIC) + { + /// no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT. + if (!spellProto->SpellFamilyName) + return false; + } + /// Aura must have positive procflags for a HOT to proc + else if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS))) return false; + } + /// Aura must have negative or neutral(PROC_FLAG_DONE_PERIODIC only) procflags for a DOT to proc + else if (EventProcFlag != PROC_FLAG_DONE_PERIODIC) + if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_DONE_TRAP_ACTIVATION))) + return false; + } - // check mana requirement - if (procEntry.AttributesMask & PROC_ATTR_REQ_MANA_COST) - if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo()) - if (!eventSpellInfo->ManaCost && !eventSpellInfo->ManaCostPercentage) + if (procFlags & PROC_FLAG_TAKEN_PERIODIC) + { + if (procExtra & PROC_EX_INTERNAL_HOT) + { + /// No aura that only has PROC_FLAG_TAKEN_PERIODIC can proc from a HOT. + if (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC) + return false; + /// Aura must have positive procflags for a HOT to proc + if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS))) return false; + } + /// Aura must have negative or neutral(PROC_FLAG_TAKEN_PERIODIC only) procflags for a DOT to proc + else if (EventProcFlag != PROC_FLAG_TAKEN_PERIODIC) + if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG))) + return false; + } - // always trigger for these types - if (eventInfo.GetTypeMask() & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_DEATH)) - return true; + // Trap casts are active by default + if (procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION) + active = true; - // do triggered cast checks - // Do not consider autoattacks as triggered spells - if (!(procEntry.AttributesMask & PROC_ATTR_TRIGGERED_CAN_PROC) && !(eventInfo.GetTypeMask() & AUTO_ATTACK_PROC_FLAG_MASK)) + if (spellProcEvent) // Exist event data { - if (Spell const* spell = eventInfo.GetProcSpell()) + // Store extra req + procEvent_procEx = spellProcEvent->procEx; + procEvent_procPhase = spellProcEvent->procPhase; + + // For melee triggers + if (!procSpellInfo) + { + // Check (if set) for school (melee attack have Normal school) + if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0) + return false; + } + else // For spells need check school/spell family/family mask { - if (spell->IsTriggered()) + // Check (if set) for school + if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpellInfo->SchoolMask) == 0) + return false; + + // Check (if set) for spellFamilyName + if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpellInfo->SpellFamilyName)) + return false; + + // spellFamilyName is Ok need check for spellFamilyMask if present + if (spellProcEvent->spellFamilyMask) { - SpellInfo const* spellInfo = spell->GetSpellInfo(); - if (!spellInfo->HasAttribute(SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2) && - !spellInfo->HasAttribute(SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC)) + if (!(spellProcEvent->spellFamilyMask & procSpellInfo->SpellFamilyFlags)) return false; + hasFamilyMask = true; + // Some spells are not considered as active even with have spellfamilyflags + if (!(procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL)) + active = true; + } + + // Check tick numbers + if (procEvent_procEx & PROC_EX_ONLY_FIRST_TICK) + { + if (Spell const* procSpell = eventInfo.GetProcSpell()) + { + if (procSpell->GetTriggeredByAuraTickNumber() > 1) + { + return false; + } + } } } } - // check school mask (if set) for other trigger types - if (procEntry.SchoolMask && !(eventInfo.GetSchoolMask() & procEntry.SchoolMask)) + if (procExtra & (PROC_EX_INTERNAL_REQ_FAMILY)) + { + if (!hasFamilyMask) + return false; + } + + if (!(procEvent_procPhase & procPhase)) + { return false; + } - // check spell family name/flags (if set) for spells - if (eventInfo.GetTypeMask() & (PERIODIC_PROC_FLAG_MASK | SPELL_PROC_FLAG_MASK)) + // Check for extra req (if none) and hit/crit + if (procEvent_procEx == PROC_EX_NONE) + { + // No extra req, so can trigger only for hit/crit - spell has to be active + if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && active) + return true; + } + else // Passive spells hits here only if resist/reflect/immune/evade { - if (SpellInfo const* eventSpellInfo = eventInfo.GetSpellInfo()) + if (procExtra & AURA_SPELL_PROC_EX_MASK) { - if (!eventSpellInfo->IsAffected(procEntry.SpellFamilyName, procEntry.SpellFamilyMask)) - { + // if spell marked as procing only from not active spells + if (active && procEvent_procEx & PROC_EX_NOT_ACTIVE_SPELL) return false; - } - } + // if spell marked as procing only from active spells + if (!active && procEvent_procEx & PROC_EX_ONLY_ACTIVE_SPELL) + return false; + // Exist req for PROC_EX_EX_TRIGGER_ALWAYS + if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS) + return true; + // PROC_EX_NOT_ACTIVE_SPELL and PROC_EX_ONLY_ACTIVE_SPELL flags handle: if passed checks before + if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK)) == 0)) + return true; + } + // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other) + if (procEvent_procEx & procExtra) + return true; + } + return false; +} + +SpellProcEntry const* SpellMgr::GetSpellProcEntry(uint32 spellId) const +{ + SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId); + if (itr != mSpellProcMap.end()) + return &itr->second; + return nullptr; +} + +bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const +{ + // proc type doesn't match + if (!(eventInfo.GetTypeMask() & procEntry.typeMask)) + return false; + + // check XP or honor target requirement + if (procEntry.attributesMask & PROC_ATTR_REQ_EXP_OR_HONOR) + if (Player* actor = eventInfo.GetActor()->ToPlayer()) + if (eventInfo.GetActionTarget() && !actor->isHonorOrXPTarget(eventInfo.GetActionTarget())) + return false; + + // always trigger for these types + if (eventInfo.GetTypeMask() & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_DEATH)) + return true; + + // check school mask (if set) for other trigger types + if (procEntry.schoolMask && !(eventInfo.GetSchoolMask() & procEntry.schoolMask)) + return false; + + // check spell family name/flags (if set) for spells + if (eventInfo.GetTypeMask() & (PERIODIC_PROC_FLAG_MASK | SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION)) + { + if (procEntry.spellFamilyName && (procEntry.spellFamilyName != eventInfo.GetSpellInfo()->SpellFamilyName)) + return false; + + if (procEntry.spellFamilyMask && !(procEntry.spellFamilyMask & eventInfo.GetSpellInfo()->SpellFamilyFlags)) + return false; } // check spell type mask (if set) if (eventInfo.GetTypeMask() & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)) { - if (procEntry.SpellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.SpellTypeMask)) + if (procEntry.spellTypeMask && !(eventInfo.GetSpellTypeMask() & procEntry.spellTypeMask)) return false; } // check spell phase mask if (eventInfo.GetTypeMask() & REQ_SPELL_PHASE_PROC_FLAG_MASK) { - if (!(eventInfo.GetSpellPhaseMask() & procEntry.SpellPhaseMask)) + if (!(eventInfo.GetSpellPhaseMask() & procEntry.spellPhaseMask)) return false; } // check hit mask (on taken hit or on done hit, but not on spell cast phase) if ((eventInfo.GetTypeMask() & TAKEN_HIT_PROC_FLAG_MASK) || ((eventInfo.GetTypeMask() & DONE_HIT_PROC_FLAG_MASK) && !(eventInfo.GetSpellPhaseMask() & PROC_SPELL_PHASE_CAST))) { - uint32 hitMask = procEntry.HitMask; + uint32 hitMask = procEntry.hitMask; // get default values if hit mask not set if (!hitMask) { @@ -1597,22 +1733,22 @@ void SpellMgr::LoadSpellGroupStackRules() LOG_INFO("server.loading", " "); } -void SpellMgr::LoadSpellProcs() +void SpellMgr::LoadSpellProcEvents() { uint32 oldMSTime = getMSTime(); - mSpellProcMap.clear(); // need for reload case + mSpellProcEventMap.clear(); // need for reload case - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - QueryResult result = WorldDatabase.Query("SELECT SpellId, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, ProcFlags, SpellTypeMask, SpellPhaseMask, HitMask, AttributesMask, ProcsPerMinute, Chance, Cooldown, Charges FROM spell_proc"); + // 0 1 2 3 4 5 6 7 8 9 10 11 + QueryResult result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, procPhase, ppmRate, CustomChance, Cooldown FROM spell_proc_event"); if (!result) { - LOG_INFO("server.loading", ">> Loaded 0 spell proc conditions and data. DB table `spell_proc` is empty."); - LOG_INFO("server.loading", " "); + LOG_WARN("server.loading", ">> Loaded 0 spell proc event conditions. DB table `spell_proc_event` is empty."); return; } uint32 count = 0; + do { Field* fields = result->Fetch(); @@ -1629,274 +1765,204 @@ void SpellMgr::LoadSpellProcs() SpellInfo const* spellInfo = GetSpellInfo(spellId); if (!spellInfo) { - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId); + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` does not exist", spellId); continue; } if (allRanks) { + if (!spellInfo->IsRanked()) + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` with all ranks, but spell has no ranks.", spellId); + if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId)) { - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>()); + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` is not first rank of spell.", spellId); continue; } } - SpellProcEntry baseProcEntry; + SpellProcEventEntry spellProcEvent; - baseProcEntry.SchoolMask = fields[1].Get<int8>(); - baseProcEntry.SpellFamilyName = fields[2].Get<uint16>(); - baseProcEntry.SpellFamilyMask[0] = fields[3].Get<uint32>(); - baseProcEntry.SpellFamilyMask[1] = fields[4].Get<uint32>(); - baseProcEntry.SpellFamilyMask[2] = fields[5].Get<uint32>(); - baseProcEntry.ProcFlags = fields[6].Get<uint32>(); - baseProcEntry.SpellTypeMask = fields[7].Get<uint32>(); - baseProcEntry.SpellPhaseMask = fields[8].Get<uint32>(); - baseProcEntry.HitMask = fields[9].Get<uint32>(); - baseProcEntry.AttributesMask = fields[10].Get<uint32>(); - baseProcEntry.ProcsPerMinute = fields[11].Get<float>(); - baseProcEntry.Chance = fields[12].Get<float>(); - baseProcEntry.Cooldown = Milliseconds(fields[13].Get<uint32>()); - baseProcEntry.Charges = fields[14].Get<uint8>(); + spellProcEvent.schoolMask = fields[1].Get<int8>(); + spellProcEvent.spellFamilyName = fields[2].Get<uint16>(); + spellProcEvent.spellFamilyMask[0] = fields[3].Get<uint32>(); + spellProcEvent.spellFamilyMask[1] = fields[4].Get<uint32>(); + spellProcEvent.spellFamilyMask[2] = fields[5].Get<uint32>(); + spellProcEvent.procFlags = fields[6].Get<uint32>(); + spellProcEvent.procEx = fields[7].Get<uint32>(); + spellProcEvent.procPhase = fields[8].Get<uint32>(); + spellProcEvent.ppmRate = fields[9].Get<float>(); + spellProcEvent.customChance = fields[10].Get<float>(); + spellProcEvent.cooldown = fields[11].Get<uint32>(); + + // PROC_SPELL_PHASE_NONE is by default PROC_SPELL_PHASE_HIT + if (spellProcEvent.procPhase == PROC_SPELL_PHASE_NONE) + { + spellProcEvent.procPhase = PROC_SPELL_PHASE_HIT; + } while (spellInfo) { - if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end()) + if (mSpellProcEventMap.find(spellInfo->Id) != mSpellProcEventMap.end()) { - LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId); + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` already has its first rank in table.", spellInfo->Id); break; } - SpellProcEntry procEntry = SpellProcEntry(baseProcEntry); - // take defaults from dbcs - if (!procEntry.ProcFlags) - procEntry.ProcFlags = spellInfo->ProcFlags; - if (!procEntry.Charges) - procEntry.Charges = spellInfo->ProcCharges; - if (!procEntry.Chance && !procEntry.ProcsPerMinute) - procEntry.Chance = float(spellInfo->ProcChance); + if (!spellInfo->ProcFlags && !spellProcEvent.procFlags) + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc_event` probally not triggered spell", spellInfo->Id); - // validate data - if (procEntry.SchoolMask & ~SPELL_SCHOOL_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SchoolMask` set: {}", spellId, procEntry.SchoolMask); - if (procEntry.SpellFamilyName && (procEntry.SpellFamilyName < 3 || procEntry.SpellFamilyName > 17 || procEntry.SpellFamilyName == 14 || procEntry.SpellFamilyName == 16)) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellFamilyName` set: {}", spellId, procEntry.SpellFamilyName); - if (procEntry.Chance < 0) - { - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `Chance` field", spellId); - procEntry.Chance = 0; - } - if (procEntry.ProcsPerMinute < 0) - { - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has negative value in `ProcsPerMinute` field", spellId); - procEntry.ProcsPerMinute = 0; - } - if (procEntry.Chance == 0 && procEntry.ProcsPerMinute == 0) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `Chance` and `ProcsPerMinute` values defined, proc will not be triggered", spellId); - if (procEntry.Charges > 99) - { - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has too big value in `Charges` field", spellId); - procEntry.Charges = 99; - } - if (!procEntry.ProcFlags) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `ProcFlags` value defined, proc will not be triggered", spellId); - if (procEntry.SpellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellTypeMask` set: {}", spellId, procEntry.SpellTypeMask); - if (procEntry.SpellTypeMask && !(procEntry.ProcFlags & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellTypeMask` value defined, but it won't be used for defined `ProcFlags` value", spellId); - if (!procEntry.SpellPhaseMask && procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} doesn't have `SpellPhaseMask` value defined, but it's required for defined `ProcFlags` value, proc will not be triggered", spellId); - if (procEntry.SpellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `SpellPhaseMask` set: {}", spellId, procEntry.SpellPhaseMask); - if (procEntry.SpellPhaseMask && !(procEntry.ProcFlags & REQ_SPELL_PHASE_PROC_FLAG_MASK)) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `SpellPhaseMask` value defined, but it won't be used for defined `ProcFlags` value", spellId); - if (procEntry.HitMask & ~PROC_HIT_MASK_ALL) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has wrong `HitMask` set: {}", spellId, procEntry.HitMask); - if (procEntry.HitMask && !(procEntry.ProcFlags & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.ProcFlags & DONE_HIT_PROC_FLAG_MASK && (!procEntry.SpellPhaseMask || procEntry.SpellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH))))) - LOG_ERROR("sql.sql", "`spell_proc` table entry for SpellId {} has `HitMask` value defined, but it won't be used for defined `ProcFlags` and `SpellPhaseMask` values", spellId); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if ((procEntry.AttributesMask & (PROC_ATTR_DISABLE_EFF_0 << i)) && !spellInfo->Effects[i].IsAura()) - LOG_ERROR("sql.sql", "The `spell_proc` table entry for spellId {} has Attribute PROC_ATTR_DISABLE_EFF_{}, but effect {} is not an aura effect", spellInfo->Id, static_cast<uint32>(i), static_cast<uint32>(i)); - - mSpellProcMap[spellInfo->Id] = procEntry; + mSpellProcEventMap[spellInfo->Id] = spellProcEvent; if (allRanks) spellInfo = spellInfo->GetNextRankSpell(); else break; } + ++count; } while (result->NextRow()); LOG_INFO("server.loading", ">> Loaded {} Extra Spell Proc Event Conditions in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); LOG_INFO("server.loading", " "); +} - // Define can trigger auras - bool isTriggerAura[TOTAL_AURAS]; - // Triggered always, even from triggered spells - bool isAlwaysTriggeredAura[TOTAL_AURAS]; - // SpellTypeMask to add to the proc - uint32 spellTypeMask[TOTAL_AURAS]; - - // List of auras that CAN trigger but may not exist in spell_proc - // in most cases needed to drop charges - - // some aura types need additional checks (eg SPELL_AURA_MECHANIC_IMMUNITY needs mechanic check) - // see AuraEffect::CheckEffectProc - for (uint16 i = 0; i < TOTAL_AURAS; ++i) - { - isTriggerAura[i] = false; - isAlwaysTriggeredAura[i] = false; - spellTypeMask[i] = PROC_SPELL_TYPE_MASK_ALL; - } - - isTriggerAura[SPELL_AURA_DUMMY] = true; // Most dummy auras should require scripting, but there are some exceptions (ie 12311) - isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true; // "Any direct damaging attack will revive targets" - isTriggerAura[SPELL_AURA_MOD_THREAT] = true; // Only one spell: 28762 part of Mage T3 8p bonus - isTriggerAura[SPELL_AURA_MOD_STUN] = true; // Aura does not have charges but needs to be removed on trigger - isTriggerAura[SPELL_AURA_MOD_DAMAGE_DONE] = true; - isTriggerAura[SPELL_AURA_MOD_DAMAGE_TAKEN] = true; - isTriggerAura[SPELL_AURA_MOD_RESISTANCE] = true; - isTriggerAura[SPELL_AURA_MOD_STEALTH] = true; - isTriggerAura[SPELL_AURA_MOD_FEAR] = true; // Aura does not have charges but needs to be removed on trigger - isTriggerAura[SPELL_AURA_MOD_ROOT] = true; - isTriggerAura[SPELL_AURA_TRANSFORM] = true; - isTriggerAura[SPELL_AURA_REFLECT_SPELLS] = true; - isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true; - isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true; - isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true; - isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true; - isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true; - isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true; - isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true; - isTriggerAura[SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN] = true; - isTriggerAura[SPELL_AURA_MOD_ATTACK_POWER] = true; - isTriggerAura[SPELL_AURA_ADD_CASTER_HIT_TRIGGER] = true; - isTriggerAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; - isTriggerAura[SPELL_AURA_MOD_MELEE_HASTE] = true; - isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE] = true; - isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE] = true; - isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE] = true; - isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; - isTriggerAura[SPELL_AURA_MOD_SPELL_CRIT_CHANCE] = true; - isTriggerAura[SPELL_AURA_ADD_FLAT_MODIFIER] = true; - isTriggerAura[SPELL_AURA_ADD_PCT_MODIFIER] = true; - isTriggerAura[SPELL_AURA_ABILITY_IGNORE_AURASTATE] = true; - - isAlwaysTriggeredAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_STEALTH] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_CONFUSE] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_FEAR] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_ROOT] = true; - isAlwaysTriggeredAura[SPELL_AURA_MOD_STUN] = true; - isAlwaysTriggeredAura[SPELL_AURA_TRANSFORM] = true; - - spellTypeMask[SPELL_AURA_MOD_STEALTH] = PROC_SPELL_TYPE_DAMAGE | PROC_SPELL_TYPE_NO_DMG_HEAL; - spellTypeMask[SPELL_AURA_MOD_CONFUSE] = PROC_SPELL_TYPE_DAMAGE; - spellTypeMask[SPELL_AURA_MOD_FEAR] = PROC_SPELL_TYPE_DAMAGE; - spellTypeMask[SPELL_AURA_MOD_ROOT] = PROC_SPELL_TYPE_DAMAGE; - spellTypeMask[SPELL_AURA_MOD_STUN] = PROC_SPELL_TYPE_DAMAGE; - spellTypeMask[SPELL_AURA_TRANSFORM] = PROC_SPELL_TYPE_DAMAGE; - - // This generates default procs to retain compatibility with previous proc system - LOG_INFO("server.loading", "Generating spell proc data from SpellMap..."); - count = 0; - oldMSTime = getMSTime(); +void SpellMgr::LoadSpellProcs() +{ + uint32 oldMSTime = getMSTime(); - for (SpellInfo const* spellInfo : mSpellInfoMap) + mSpellProcMap.clear(); // need for reload case + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + QueryResult result = WorldDatabase.Query("SELECT spellId, schoolMask, spellFamilyName, spellFamilyMask0, spellFamilyMask1, spellFamilyMask2, typeMask, spellTypeMask, spellPhaseMask, hitMask, attributesMask, ratePerMinute, chance, cooldown, charges FROM spell_proc"); + if (!result) { - if (!spellInfo) - continue; + LOG_WARN("server.loading", ">> Loaded 0 Spell Proc Conditions And Data. DB table `spell_proc` Is Empty."); + LOG_INFO("server.loading", " "); + return; + } - // Data already present in DB, overwrites default proc - if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end()) - continue; + uint32 count = 0; + do + { + Field* fields = result->Fetch(); - // Nothing to do if no flags set - if (!spellInfo->ProcFlags) - continue; + int32 spellId = fields[0].Get<int32>(); - bool addTriggerFlag = false; - uint32 procSpellTypeMask = PROC_SPELL_TYPE_NONE; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + bool allRanks = false; + if (spellId < 0) { - if (!spellInfo->Effects[i].IsEffect()) - continue; - - uint32 auraName = spellInfo->Effects[i].ApplyAuraName; - if (!auraName) - continue; - - if (!isTriggerAura[auraName]) - continue; - - procSpellTypeMask |= spellTypeMask[auraName]; + allRanks = true; + spellId = -spellId; + } - if (isAlwaysTriggeredAura[auraName]) - addTriggerFlag = true; + SpellInfo const* spellInfo = GetSpellInfo(spellId); + if (!spellInfo) + { + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` does not exist", spellId); + continue; + } - // many proc auras with taken procFlag mask don't have attribute "can proc with triggered" - // they should proc nevertheless (example mage armor spells with judgement) - if (!addTriggerFlag && (spellInfo->ProcFlags & TAKEN_HIT_PROC_FLAG_MASK) != 0) + if (allRanks) + { + if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId)) { - switch (auraName) - { - case SPELL_AURA_PROC_TRIGGER_SPELL: - case SPELL_AURA_PROC_TRIGGER_DAMAGE: - addTriggerFlag = true; - break; - default: - break; - } + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` is not first rank of spell.", fields[0].Get<int32>()); + continue; } - - break; } - if (!procSpellTypeMask) - continue; - - SpellProcEntry procEntry; - procEntry.SchoolMask = 0; - procEntry.ProcFlags = spellInfo->ProcFlags; - procEntry.SpellFamilyName = 0; - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (spellInfo->Effects[i].IsEffect() && isTriggerAura[spellInfo->Effects[i].ApplyAuraName]) - procEntry.SpellFamilyMask |= spellInfo->Effects[i].SpellClassMask; - - if (procEntry.SpellFamilyMask) - procEntry.SpellFamilyName = spellInfo->SpellFamilyName; + SpellProcEntry baseProcEntry; - procEntry.SpellTypeMask = procSpellTypeMask; - procEntry.SpellPhaseMask = PROC_SPELL_PHASE_HIT; - procEntry.HitMask = PROC_HIT_NONE; // uses default proc @see SpellMgr::CanSpellTriggerProcOnEvent + baseProcEntry.schoolMask = fields[1].Get<int8>(); + baseProcEntry.spellFamilyName = fields[2].Get<uint16>(); + baseProcEntry.spellFamilyMask[0] = fields[3].Get<uint32>(); + baseProcEntry.spellFamilyMask[1] = fields[4].Get<uint32>(); + baseProcEntry.spellFamilyMask[2] = fields[5].Get<uint32>(); + baseProcEntry.typeMask = fields[6].Get<uint32>(); + baseProcEntry.spellTypeMask = fields[7].Get<uint32>(); + baseProcEntry.spellPhaseMask = fields[8].Get<uint32>(); + baseProcEntry.hitMask = fields[9].Get<uint32>(); + baseProcEntry.attributesMask = fields[10].Get<uint32>(); + baseProcEntry.ratePerMinute = fields[11].Get<float>(); + baseProcEntry.chance = fields[12].Get<float>(); + float cooldown = fields[13].Get<float>(); + baseProcEntry.cooldown = uint32(cooldown); + baseProcEntry.charges = fields[14].Get<uint32>(); - // Reflect auras should only proc off reflects - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + while (spellInfo) { - if (spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS) || spellInfo->Effects[i].IsAura(SPELL_AURA_REFLECT_SPELLS_SCHOOL)) + if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end()) { - procEntry.HitMask = PROC_HIT_REFLECT; + LOG_ERROR("sql.sql", "Spell {} listed in `spell_proc` has duplicate entry in the table", spellId); break; } - } + SpellProcEntry procEntry = SpellProcEntry(baseProcEntry); + + // take defaults from dbcs + if (!procEntry.typeMask) + procEntry.typeMask = spellInfo->ProcFlags; + if (!procEntry.charges) + procEntry.charges = spellInfo->ProcCharges; + if (!procEntry.chance && !procEntry.ratePerMinute) + procEntry.chance = float(spellInfo->ProcChance); - procEntry.AttributesMask = 0; - if (spellInfo->ProcFlags & PROC_FLAG_KILL) - procEntry.AttributesMask |= PROC_ATTR_REQ_EXP_OR_HONOR; - if (addTriggerFlag) - procEntry.AttributesMask |= PROC_ATTR_TRIGGERED_CAN_PROC; + // validate data + if (procEntry.schoolMask & ~SPELL_SCHOOL_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `schoolMask` set: {}", spellId, procEntry.schoolMask); + if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16)) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `spellFamilyName` set: {}", spellId, procEntry.spellFamilyName); + if (procEntry.chance < 0) + { + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has negative value in `chance` field", spellId); + procEntry.chance = 0; + } + if (procEntry.ratePerMinute < 0) + { + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has negative value in `ratePerMinute` field", spellId); + procEntry.ratePerMinute = 0; + } + if (cooldown < 0) + { + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has negative value in `cooldown` field", spellId); + procEntry.cooldown = 0; + } + if (procEntry.chance == 0 && procEntry.ratePerMinute == 0) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellId); + if (procEntry.charges > 99) + { + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has too big value in `charges` field", spellId); + procEntry.charges = 99; + } + if (!procEntry.typeMask) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} doesn't have `typeMask` value defined, proc will not be triggered", spellId); + if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `spellTypeMask` set: {}", spellId, procEntry.spellTypeMask); + if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK))) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has `spellTypeMask` value defined, but it won't be used for defined `typeMask` value", spellId); + if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} doesn't have `spellPhaseMask` value defined, but it's required for defined `typeMask` value, proc will not be triggered", spellId); + if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `spellPhaseMask` set: {}", spellId, procEntry.spellPhaseMask); + if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellId); + if (procEntry.hitMask & ~PROC_HIT_MASK_ALL) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has wrong `hitMask` set: {}", spellId, procEntry.hitMask); + if (procEntry.hitMask && !(procEntry.typeMask & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.typeMask & DONE_HIT_PROC_FLAG_MASK && (!procEntry.spellPhaseMask || procEntry.spellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH))))) + LOG_ERROR("sql.sql", "`spell_proc` table entry for spellId {} has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellId); - procEntry.ProcsPerMinute = 0; - procEntry.Chance = spellInfo->ProcChance; - procEntry.Cooldown = Milliseconds::zero(); - procEntry.Charges = spellInfo->ProcCharges; + mSpellProcMap[spellInfo->Id] = procEntry; - mSpellProcMap[spellInfo->Id] = procEntry; + if (allRanks) + spellInfo = spellInfo->GetNextRankSpell(); + else + break; + } ++count; - } + } while (result->NextRow()); - LOG_INFO("server.loading", ">> Generated spell proc data for {} spells in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", ">> Loaded {} spell proc conditions and data in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); } void SpellMgr::LoadSpellBonuses() diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index c1bfb1d5f1..d02342f116 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -154,15 +154,13 @@ enum ProcFlags | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS, SPELL_PROC_FLAG_MASK = PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS - | PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS - | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG - | PROC_FLAG_DONE_TRAP_ACTIVATION, + | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, - SPELL_CAST_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION, + SPELL_CAST_PROC_FLAG_MASK = SPELL_PROC_FLAG_MASK | PROC_FLAG_DONE_TRAP_ACTIVATION | RANGED_PROC_FLAG_MASK, PERIODIC_PROC_FLAG_MASK = PROC_FLAG_DONE_PERIODIC | PROC_FLAG_TAKEN_PERIODIC, @@ -170,8 +168,7 @@ enum ProcFlags | PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG - | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_TRAP_ACTIVATION - | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, + | PROC_FLAG_DONE_PERIODIC | PROC_FLAG_DONE_MAINHAND_ATTACK | PROC_FLAG_DONE_OFFHAND_ATTACK, TAKEN_HIT_PROC_FLAG_MASK = PROC_FLAG_TAKEN_MELEE_AUTO_ATTACK | PROC_FLAG_TAKEN_RANGED_AUTO_ATTACK | PROC_FLAG_TAKEN_SPELL_MELEE_DMG_CLASS | PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS @@ -191,6 +188,46 @@ enum ProcFlags PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS | \ PROC_FLAG_TAKEN_SPELL_RANGED_DMG_CLASS) +enum ProcFlagsExLegacy +{ + PROC_EX_NONE = 0x0000000, // If none can tigger on Hit/Crit only (passive spells MUST defined by SpellFamily flag) + PROC_EX_NORMAL_HIT = 0x0000001, // If set only from normal hit (only damage spells) + PROC_EX_CRITICAL_HIT = 0x0000002, + PROC_EX_MISS = 0x0000004, + PROC_EX_RESIST = 0x0000008, + PROC_EX_DODGE = 0x0000010, + PROC_EX_PARRY = 0x0000020, + PROC_EX_BLOCK = 0x0000040, + PROC_EX_EVADE = 0x0000080, + PROC_EX_IMMUNE = 0x0000100, + PROC_EX_DEFLECT = 0x0000200, + PROC_EX_ABSORB = 0x0000400, + PROC_EX_REFLECT = 0x0000800, + PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used) + PROC_EX_FULL_BLOCK = 0x0002000, // block all attack damage + PROC_EX_RESERVED2 = 0x0004000, + PROC_EX_NOT_ACTIVE_SPELL = 0x0008000, // Spell mustn't do damage/heal to proc + PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always no matter of hit result + PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not implemented yet) + PROC_EX_ONLY_ACTIVE_SPELL = 0x0040000, // Spell has to do damage/heal to proc + PROC_EX_NO_OVERHEAL = 0x0080000, // Proc if heal did some work + PROC_EX_NO_AURA_REFRESH = 0x0100000, // Proc if aura was not refreshed + PROC_EX_ONLY_FIRST_TICK = 0x0200000, // Proc only on first tick (in case of periodic spells) + + // Flags for internal use - do not use these in db! + PROC_EX_INTERNAL_CANT_PROC = 0x0800000, + PROC_EX_INTERNAL_DOT = 0x1000000, + PROC_EX_INTERNAL_HOT = 0x2000000, + PROC_EX_INTERNAL_TRIGGERED = 0x4000000, + PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000 +}; + +#define AURA_SPELL_PROC_EX_MASK \ + (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT | PROC_EX_MISS | \ + PROC_EX_RESIST | PROC_EX_DODGE | PROC_EX_PARRY | PROC_EX_BLOCK | \ + PROC_EX_EVADE | PROC_EX_IMMUNE | PROC_EX_DEFLECT | \ + PROC_EX_ABSORB | PROC_EX_REFLECT | PROC_EX_INTERRUPT) + enum ProcFlagsSpellType { PROC_SPELL_TYPE_NONE = 0x0000000, @@ -224,37 +261,45 @@ enum ProcFlagsHit PROC_HIT_DEFLECT = 0x0000200, PROC_HIT_ABSORB = 0x0000400, // partial or full absorb PROC_HIT_REFLECT = 0x0000800, - PROC_HIT_INTERRUPT = 0x0001000, + PROC_HIT_INTERRUPT = 0x0001000, // (not used atm) PROC_HIT_FULL_BLOCK = 0x0002000, - PROC_HIT_MASK_ALL = 0x0002FFF, + PROC_HIT_MASK_ALL = 0x2FFF, }; enum ProcAttributes { - PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000001, // requires proc target to give exp or honor for aura proc - PROC_ATTR_TRIGGERED_CAN_PROC = 0x0000002, // aura can proc even with triggered spells - PROC_ATTR_REQ_MANA_COST = 0x0000004, // requires triggering spell to have a mana cost for aura proc - PROC_ATTR_REQ_SPELLMOD = 0x0000008, // requires triggering spell to be affected by proccing aura to drop charges - - PROC_ATTR_DISABLE_EFF_0 = 0x0000010, // explicitly disables aura proc from effects, USE ONLY IF 100% SURE AURA SHOULDN'T PROC - PROC_ATTR_DISABLE_EFF_1 = 0x0000020, // used to avoid a console error if the spell has invalid trigger spell and handled elsewhere - PROC_ATTR_DISABLE_EFF_2 = 0x0000040 // or handling not needed + PROC_ATTR_REQ_EXP_OR_HONOR = 0x0000010, }; +struct SpellProcEventEntry +{ + uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2 + uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value + flag96 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) + uint32 procFlags; // bitmask for matching proc event + uint32 procEx; // proc Extend info (see ProcFlagsEx) + uint32 procPhase; // proc phase (see ProcFlagsSpellPhase) + float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc + float customChance; // Owerride chance (in most cases for debug only) + uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_ +}; + +typedef std::unordered_map<uint32, SpellProcEventEntry> SpellProcEventMap; + struct SpellProcEntry { - uint32 SchoolMask; // if nonzero - bitmask for matching proc condition based on spell's school - uint32 SpellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName - flag96 SpellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags - uint32 ProcFlags; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags - uint32 SpellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType - uint32 SpellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase - uint32 HitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit - uint32 AttributesMask; // bitmask, see ProcAttributes - float ProcsPerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60 - float Chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if perMinuteRate set - Milliseconds Cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura - uint32 Charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite + uint32 schoolMask; // if nonzero - bitmask for matching proc condition based on spell's school + uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyName + flag96 spellFamilyMask; // if nonzero - bitmask for matching proc condition based on candidate spell's SpellFamilyFlags + uint32 typeMask; // if nonzero - owerwrite procFlags field for given Spell.dbc entry, bitmask for matching proc condition, see enum ProcFlags + uint32 spellTypeMask; // if nonzero - bitmask for matching proc condition based on candidate spell's damage/heal effects, see enum ProcFlagsSpellType + uint32 spellPhaseMask; // if nonzero - bitmask for matching phase of a spellcast on which proc occurs, see enum ProcFlagsSpellPhase + uint32 hitMask; // if nonzero - bitmask for matching proc condition based on hit result, see enum ProcFlagsHit + uint32 attributesMask; // bitmask, see ProcAttributes + float ratePerMinute; // if nonzero - chance to proc is equal to value * aura caster's weapon speed / 60 + float chance; // if nonzero - owerwrite procChance field for given Spell.dbc entry, defines chance of proc to occur, not used if perMinuteRate set + uint32 cooldown; // if nonzero - cooldown in secs for aura proc, applied to aura + uint32 charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite }; typedef std::unordered_map<uint32, SpellProcEntry> SpellProcMap; @@ -624,9 +669,13 @@ public: SpellGroupStackFlags CheckSpellGroupStackRules(SpellInfo const* spellInfo1, SpellInfo const* spellInfo2, bool remove, bool areaAura) const; void GetSetOfSpellsInSpellGroupWithFlag(uint32 group_id, SpellGroupSpecialFlags flag, std::set<uint32>& availableElixirs) const; + // Spell proc event table + [[nodiscard]] SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const; + bool IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, ProcEventInfo const& eventInfo, bool active) const; + // Spell proc table [[nodiscard]] SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const; - static bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo); + bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const; // Spell bonus data table [[nodiscard]] SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const; @@ -701,6 +750,7 @@ public: void LoadSpellTargetPositions(); void LoadSpellGroups(); void LoadSpellGroupStackRules(); + void LoadSpellProcEvents(); void LoadSpellProcs(); void LoadSpellBonuses(); void LoadSpellThreats(); @@ -729,6 +779,7 @@ private: SpellTargetPositionMap mSpellTargetPositions; SpellGroupMap mSpellGroupMap; SpellGroupStackMap mSpellGroupStackMap; + SpellProcEventMap mSpellProcEventMap; SpellProcMap mSpellProcMap; SpellBonusMap mSpellBonusMap; SpellThreatMap mSpellThreatMap; diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index c44c5460a9..4842cede7d 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -733,9 +733,6 @@ bool AuraScript::_Validate(SpellInfo const* entry) if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect()) LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str()); - for (std::list<CheckEffectProcHandler>::iterator itr = DoCheckEffectProc.begin(); itr != DoCheckEffectProc.end(); ++itr) - if (!itr->GetAffectedEffectsMask(entry)) - LOG_ERROR("spells.scripts", "Spell `{}` Effect `{}` of script `{}` did not match dbc effect data - handler bound to hook `DoCheckEffectProc` of AuraScript won't be executed", entry->Id, (*itr).ToString(), m_scriptName->c_str()); for (std::list<CheckProcHandler>::iterator itr = DoCheckAfterProc.begin(); itr != DoCheckAfterProc.end(); ++itr) if (!entry->HasEffect(SPELL_EFFECT_APPLY_AURA) && !entry->HasAreaAuraEffect()) LOG_ERROR("spells.scripts", "Spell `{}` of script `{}` does not have apply aura effect - handler bound to hook `DoCheckAfterProc` of AuraScript won't be executed", entry->Id, m_scriptName->c_str()); @@ -909,17 +906,6 @@ bool AuraScript::CheckProcHandler::Call(AuraScript* auraScript, ProcEventInfo& e return (auraScript->*_HandlerScript)(eventInfo); } -AuraScript::CheckEffectProcHandler::CheckEffectProcHandler(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName) - : AuraScript::EffectBase(effIndex, effName) -{ - _HandlerScript = handlerScript; -} - -bool AuraScript::CheckEffectProcHandler::Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo) -{ - return (auraScript->*_HandlerScript)(aurEff, eventInfo); -} - AuraScript::AuraProcHandler::AuraProcHandler(AuraProcFnType handlerScript) { _HandlerScript = handlerScript; @@ -1181,7 +1167,6 @@ Unit* AuraScript::GetTarget() const case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD: case AURA_SCRIPT_HOOK_EFFECT_SPLIT: case AURA_SCRIPT_HOOK_CHECK_PROC: - case AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC: case AURA_SCRIPT_HOOK_CHECK_AFTER_PROC: case AURA_SCRIPT_HOOK_PREPARE_PROC: case AURA_SCRIPT_HOOK_PROC: diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 54b8d009b4..b52d2215b5 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -499,7 +499,6 @@ enum AuraScriptHookType AURA_SCRIPT_HOOK_AFTER_DISPEL, // Spell Proc Hooks AURA_SCRIPT_HOOK_CHECK_PROC, - AURA_SCRIPT_HOOK_CHECK_EFFECT_PROC, AURA_SCRIPT_HOOK_CHECK_AFTER_PROC, AURA_SCRIPT_HOOK_PREPARE_PROC, AURA_SCRIPT_HOOK_PROC, @@ -530,8 +529,7 @@ public: typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const*, SpellModifier* &); \ typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \ typedef void(CLASSNAME::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \ - typedef bool(CLASSNAME::*AuraCheckProcFnType)(ProcEventInfo&); \ - typedef bool(CLASSNAME::*AuraCheckEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \ + typedef bool(CLASSNAME::*AuraCheckProcFnType)(ProcEventInfo&); \ typedef void(CLASSNAME::*AuraProcFnType)(ProcEventInfo&); \ typedef void(CLASSNAME::*AuraEffectProcFnType)(AuraEffect const*, ProcEventInfo&); \ @@ -641,14 +639,6 @@ public: private: AuraCheckProcFnType _HandlerScript; }; - class CheckEffectProcHandler : public EffectBase - { - public: - CheckEffectProcHandler(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName); - bool Call(AuraScript* auraScript, AuraEffect const* aurEff, ProcEventInfo& eventInfo); - private: - AuraCheckEffectProcFnType _HandlerScript; - }; class AuraProcHandler { public: @@ -678,9 +668,8 @@ public: class EffectAbsorbFunction : public AuraScript::EffectAbsorbHandler { public: EffectAbsorbFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectAbsorbHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ class EffectSplitFunction : public AuraScript::EffectSplitHandler { public: EffectSplitFunction(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectSplitHandler((AuraScript::AuraEffectSplitFnType)_pEffectHandlerScript, _effIndex) {} }; \ - class CheckProcHandlerFunction : public AuraScript::CheckProcHandler { public: CheckProcHandlerFunction(AuraCheckProcFnType handlerScript) : AuraScript::CheckProcHandler((AuraScript::AuraCheckProcFnType)handlerScript) {} }; \ - class CheckEffectProcHandlerFunction : public AuraScript::CheckEffectProcHandler { public: CheckEffectProcHandlerFunction(AuraCheckEffectProcFnType handlerScript, uint8 effIndex, uint16 effName) : AuraScript::CheckEffectProcHandler((AuraScript::AuraCheckEffectProcFnType)handlerScript, effIndex, effName) { } }; \ - class AuraProcHandlerFunction : public AuraScript::AuraProcHandler { public: AuraProcHandlerFunction(AuraProcFnType handlerScript) : AuraScript::AuraProcHandler((AuraScript::AuraProcFnType)handlerScript) {} }; \ + class CheckProcHandlerFunction : public AuraScript::CheckProcHandler { public: CheckProcHandlerFunction(AuraCheckProcFnType handlerScript) : AuraScript::CheckProcHandler((AuraScript::AuraCheckProcFnType)handlerScript) {} }; \ + class AuraProcHandlerFunction : public AuraScript::AuraProcHandler { public: AuraProcHandlerFunction(AuraProcFnType handlerScript) : AuraScript::AuraProcHandler((AuraScript::AuraProcFnType)handlerScript) {} }; \ class EffectProcHandlerFunction : public AuraScript::EffectProcHandler { public: EffectProcHandlerFunction(AuraEffectProcFnType effectHandlerScript, uint8 effIndex, uint16 effName) : AuraScript::EffectProcHandler((AuraScript::AuraEffectProcFnType)effectHandlerScript, effIndex, effName) {} }; \ #define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) @@ -822,12 +811,6 @@ public: HookList<CheckProcHandler> DoCheckAfterProc; #define AuraCheckProcFn(F) CheckProcHandlerFunction(&F) - // executed when aura effect checks if it can proc the aura - // example: DoCheckEffectProc += AuraCheckEffectProcFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier); - // where function is bool function (AuraEffect const* aurEff, ProcEventInfo& eventInfo); - HookList<CheckEffectProcHandler> DoCheckEffectProc; -#define AuraCheckEffectProcFn(F, I, N) CheckEffectProcHandlerFunction(&F, I, N) - // executed before aura procs (possibility to prevent charge drop/cooldown) // example: DoPrepareProc += AuraProcFn(class::function); // where function is: void function (ProcEventInfo& eventInfo); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index abfc1078f9..a178af4051 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1663,7 +1663,10 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading Spell Learn Skills..."); sSpellMgr->LoadSpellLearnSkills(); // must be after LoadSpellRanks - LOG_INFO("server.loading", "Loading Spell Proc conditions and data..."); + LOG_INFO("server.loading", "Loading Spell Proc Event Conditions..."); + sSpellMgr->LoadSpellProcEvents(); + + LOG_INFO("server.loading", "Loading Spell Proc Conditions and Data..."); sSpellMgr->LoadSpellProcs(); LOG_INFO("server.loading", "Loading Spell Bonus Data..."); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 948e189560..2fee7b3b6d 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -154,6 +154,7 @@ public: { "spell_loot_template", HandleReloadLootTemplatesSpellCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_linked_spell", HandleReloadSpellLinkedSpellCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_pet_auras", HandleReloadSpellPetAurasCommand, SEC_ADMINISTRATOR, Console::Yes }, + { "spell_proc_event", HandleReloadSpellProcEventCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_proc", HandleReloadSpellProcsCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_scripts", HandleReloadSpellScriptsCommand, SEC_ADMINISTRATOR, Console::Yes }, { "spell_target_position", HandleReloadSpellTargetPositionCommand, SEC_ADMINISTRATOR, Console::Yes }, @@ -295,6 +296,7 @@ public: HandleReloadSpellAreaCommand(handler); HandleReloadSpellGroupsCommand(handler); HandleReloadSpellLinkedSpellCommand(handler); + HandleReloadSpellProcEventCommand(handler); HandleReloadSpellProcsCommand(handler); HandleReloadSpellBonusesCommand(handler); HandleReloadSpellTargetPositionCommand(handler); @@ -851,6 +853,14 @@ public: return true; } + static bool HandleReloadSpellProcEventCommand(ChatHandler* handler) + { + LOG_INFO("server.loading", "Re-Loading Spell Proc Event conditions..."); + sSpellMgr->LoadSpellProcEvents(); + handler->SendGlobalGMSysMessage("DB table `spell_proc_event` (spell proc trigger requirements) reloaded."); + return true; + } + static bool HandleReloadSpellProcsCommand(ChatHandler* handler) { LOG_INFO("server.loading", "Re-Loading Spell Proc conditions and data..."); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp index 55088fa48a..a874525987 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp @@ -17,19 +17,17 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "SpellScript.h" #include "hyjal.h" #include "hyjal_trash.h" enum Spells { - SPELL_CARRION_SWARM = 31306, - SPELL_SLEEP = 31298, - SPELL_VAMPIRIC_AURA = 38196, - SPELL_VAMPIRIC_AURA_HEAL = 31285, - SPELL_INFERNO = 31299, - SPELL_IMMOLATION = 31303, - SPELL_INFERNO_EFFECT = 31302 + SPELL_CARRION_SWARM = 31306, + SPELL_SLEEP = 31298, + SPELL_VAMPIRIC_AURA = 38196, + SPELL_INFERNO = 31299, + SPELL_IMMOLATION = 31303, + SPELL_INFERNO_EFFECT = 31302, }; enum Texts @@ -267,48 +265,8 @@ public: }; }; -class spell_anetheron_vampiric_aura : public SpellScriptLoader -{ -public: - spell_anetheron_vampiric_aura() : SpellScriptLoader("spell_anetheron_vampiric_aura") { } - - class spell_anetheron_vampiric_aura_AuraScript : public AuraScript - { - PrepareAuraScript(spell_anetheron_vampiric_aura_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_VAMPIRIC_AURA_HEAL)) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 bp = damageInfo->GetDamage() * 3; - eventInfo.GetActor()->CastCustomSpell(SPELL_VAMPIRIC_AURA_HEAL, SPELLVALUE_BASE_POINT0, bp, eventInfo.GetActor(), true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_anetheron_vampiric_aura_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_anetheron_vampiric_aura_AuraScript(); - } -}; - void AddSC_boss_anetheron() { new boss_anetheron(); new npc_towering_infernal(); - new spell_anetheron_vampiric_aura(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index 0aaf508bd8..ec53af7ecd 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -857,7 +857,7 @@ public: resilienceReduction = damage - resilienceReduction; damage -= resilienceReduction; uint32 mitigated_damage = resilienceReduction; - DamageInfo dmgInfo(caster, plr, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK, mitigated_damage); + DamageInfo dmgInfo(caster, plr, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, mitigated_damage); Unit::CalcAbsorbResist(dmgInfo); Unit::DealDamageMods(plr, damage, &absorb); int32 overkill = damage - plr->GetHealth(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index d7f428db7a..508653c07d 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -1589,26 +1589,6 @@ public: { return new spell_taldaram_ball_of_inferno_flame_SpellScript(); } - - class spell_taldaram_ball_of_inferno_flame_AuraScript : public AuraScript - { - PrepareAuraScript(spell_taldaram_ball_of_inferno_flame_AuraScript); - - void HandleStackDrop(ProcEventInfo& /*eventInfo*/) - { - ModStackAmount(-1); - } - - void Register() override - { - OnProc += AuraProcFn(spell_taldaram_ball_of_inferno_flame_AuraScript::HandleStackDrop); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_taldaram_ball_of_inferno_flame_AuraScript(); - } }; class spell_valanar_kinetic_bomb : public SpellScriptLoader diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp index 24bb933812..86bc01d41c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp @@ -1061,7 +1061,7 @@ public: { DamageInfo* damageInfo = eventInfo.GetDamageInfo(); SpellInfo const* procSpell = eventInfo.GetSpellInfo(); - return eventInfo.GetActor() && eventInfo.GetActionTarget() && ((damageInfo && damageInfo->GetDamage()) || eventInfo.GetHitMask() & PROC_HIT_ABSORB) && procSpell && procSpell->SpellIconID != 2731; // Xinef: Mark of the Fallen Champion + return eventInfo.GetActor() && eventInfo.GetActionTarget() && ((damageInfo && damageInfo->GetDamage()) || eventInfo.GetHitMask() & PROC_EX_ABSORB) && procSpell && procSpell->SpellIconID != 2731; // Xinef: Mark of the Fallen Champion } void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) @@ -1115,7 +1115,7 @@ public: { DamageInfo* damageInfo = eventInfo.GetDamageInfo(); SpellInfo const* procSpell = eventInfo.GetSpellInfo(); - return eventInfo.GetActor() && eventInfo.GetActionTarget() && ((damageInfo && damageInfo->GetDamage()) || eventInfo.GetHitMask() & PROC_HIT_ABSORB) && (!procSpell || procSpell->SpellIconID != 2731); // Xinef: Mark of the Fallen Champion + return eventInfo.GetActor() && eventInfo.GetActionTarget() && ((damageInfo && damageInfo->GetDamage()) || eventInfo.GetHitMask() & PROC_EX_ABSORB) && (!procSpell || procSpell->SpellIconID != 2731); // Xinef: Mark of the Fallen Champion } void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) @@ -1404,41 +1404,6 @@ public: } }; -// 72176 - Blood Beast's Blood Link -class spell_deathbringer_blood_beast_blood_link : public SpellScriptLoader -{ -public: - spell_deathbringer_blood_beast_blood_link() : SpellScriptLoader("spell_deathbringer_blood_beast_blood_link") { } - - class spell_deathbringer_blood_beast_blood_link_AuraScript : public AuraScript - { - PrepareAuraScript(spell_deathbringer_blood_beast_blood_link_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_BLOOD_LINK_DUMMY)) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetProcTarget()->CastCustomSpell(SPELL_BLOOD_LINK_DUMMY, SPELLVALUE_BASE_POINT0, 3, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_deathbringer_blood_beast_blood_link_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_deathbringer_blood_beast_blood_link_AuraScript(); - } -}; - void AddSC_boss_deathbringer_saurfang() { new boss_deathbringer_saurfang(); @@ -1453,5 +1418,4 @@ void AddSC_boss_deathbringer_saurfang() new spell_deathbringer_boiling_blood(); new achievement_ive_gone_and_made_a_mess(); new npc_icc_blood_beast(); - new spell_deathbringer_blood_beast_blood_link(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 6f8165d53d..7e31e85505 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -1076,23 +1076,9 @@ public: caster->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, caster, false);*/ } - void HandleProc(ProcEventInfo& eventInfo) - { - uint32 stack = GetStackAmount(); - Unit* caster = eventInfo.GetActor(); - - int32 const mod = caster->GetMap()->Is25ManRaid() ? 1500 : 1250; - int32 dmg = 0; - for (uint8 i = 1; i <= stack; ++i) - dmg += mod * i; - - caster->CastCustomSpell(SPELL_EXPUNGED_GAS, SPELLVALUE_BASE_POINT0, dmg); - } - void Register() override { OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_gaseous_bloat_AuraScript::HandleExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); - OnProc += AuraProcFn(spell_putricide_gaseous_bloat_AuraScript::HandleProc); } }; @@ -1721,45 +1707,6 @@ public: } }; -// 71770 - Ooze Spell Tank Protection -class spell_putricide_ooze_tank_protection : public SpellScriptLoader -{ -public: - spell_putricide_ooze_tank_protection() : SpellScriptLoader("spell_putricide_ooze_tank_protection") { } - - class spell_putricide_ooze_tank_protection_AuraScript : public AuraScript - { - PrepareAuraScript(spell_putricide_ooze_tank_protection_AuraScript); - - bool Validate(SpellInfo const* spellInfo) override - { - if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell) || - !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].TriggerSpell)) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* actionTarget = eventInfo.GetActionTarget(); - actionTarget->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - OnEffectProc += AuraEffectProcFn(spell_putricide_ooze_tank_protection_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_putricide_ooze_tank_protection_AuraScript(); - } -}; - void AddSC_boss_professor_putricide() { new boss_professor_putricide(); @@ -1784,5 +1731,4 @@ void AddSC_boss_professor_putricide() new spell_putricide_mutated_transformation_dmg(); new spell_putricide_eat_ooze(); new spell_putricide_regurgitated_ooze(); - new spell_putricide_ooze_tank_protection(); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 625a96eea5..b581decfcf 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -952,7 +952,7 @@ public: } else { - me->ModifyHealth(me->CountPctFromMaxHealth(5)); + Unit::DealHeal(me, me, me->CountPctFromMaxHealth(3)); _events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000); } break; diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp index d2c74139b6..21d21e3d71 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp @@ -2987,8 +2987,6 @@ public: void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); if (!damageInfo || !damageInfo->GetDamage()) diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp index 3f17f3048a..0664944a80 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp @@ -89,57 +89,6 @@ public: }; }; -enum SecondWind -{ - SPELL_SECOND_WIND_TRIGGER = 42771 -}; - -// 42770 - Second Wind -class spell_uk_second_wind : public SpellScriptLoader -{ -public: - spell_uk_second_wind() : SpellScriptLoader("spell_uk_second_wind") { } - - class spell_uk_second_wind_AuraScript : public AuraScript - { - PrepareAuraScript(spell_uk_second_wind_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_SECOND_WIND_TRIGGER)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - return (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN))) != 0; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActionTarget(); - caster->CastSpell(caster, SPELL_SECOND_WIND_TRIGGER, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_uk_second_wind_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_uk_second_wind_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_uk_second_wind_AuraScript(); - } -}; - enum EnslavedProtoDrake { TYPE_PROTODRAKE_AT = 28, @@ -298,5 +247,4 @@ void AddSC_utgarde_keep() new npc_enslaved_proto_drake(); new spell_ticking_time_bomb(); - new spell_uk_second_wind(); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.cpp deleted file mode 100644 index 32fbe4d55a..0000000000 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "ScriptMgr.h" -#include "SpellMgr.h" -#include "SpellScript.h" -#include "SpellAuraEffects.h" -#include "Unit.h" - -enum Spells -{ - SPELL_MARK_OF_MALICE_TRIGGERED = 33494 -}; - -// 33493 - Mark of Malice -class spell_mark_of_malice : public AuraScript -{ - PrepareAuraScript(spell_mark_of_malice); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MARK_OF_MALICE_TRIGGERED }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - // just drop charges - if (aurEff->GetBase()->GetCharges() > 1) - return; - - GetTarget()->CastSpell(GetTarget(), SPELL_MARK_OF_MALICE_TRIGGERED, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mark_of_malice::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -void AddSC_shadow_labyrinth() -{ - RegisterSpellScript(spell_mark_of_malice); -} diff --git a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp index 0046dc91d6..24145c39bd 100644 --- a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp +++ b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp @@ -33,17 +33,16 @@ enum Texts enum Spells { - SPELL_SHADOW_VOLLEY = 32963, - SPELL_CLEAVE = 31779, - SPELL_THUNDERCLAP = 36706, - SPELL_VOID_BOLT = 39329, - SPELL_MARK_OF_KAZZAK = 32960, - SPELL_MARK_OF_KAZZAK_DAMAGE = 32961, - SPELL_ENRAGE = 32964, - SPELL_CAPTURE_SOUL = 32966, - SPELL_TWISTED_REFLECTION = 21063, - SPELL_TWISTED_REFLECTION_HEAL = 21064, - SPELL_BERSERK = 32965, + SPELL_SHADOW_VOLLEY = 32963, + SPELL_CLEAVE = 31779, + SPELL_THUNDERCLAP = 36706, + SPELL_VOID_BOLT = 39329, + SPELL_MARK_OF_KAZZAK = 32960, + SPELL_MARK_OF_KAZZAK_DAMAGE = 32961, + SPELL_ENRAGE = 32964, + SPELL_CAPTURE_SOUL = 32966, + SPELL_TWISTED_REFLECTION = 21063, + SPELL_BERSERK = 32965, }; enum Events @@ -220,47 +219,8 @@ public: } }; -class spell_twisted_reflection : public SpellScriptLoader -{ -public: - spell_twisted_reflection() : SpellScriptLoader("spell_twisted_reflection") { } - - class spell_twisted_reflection_AuraScript : public AuraScript - { - PrepareAuraScript(spell_twisted_reflection_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_TWISTED_REFLECTION_HEAL)) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActor(), SPELL_TWISTED_REFLECTION_HEAL, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_twisted_reflection_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_twisted_reflection_AuraScript(); - } -}; - void AddSC_boss_doomlordkazzak() { new boss_doomlord_kazzak(); new spell_mark_of_kazzak(); - new spell_twisted_reflection(); } diff --git a/src/server/scripts/Outland/outland_script_loader.cpp b/src/server/scripts/Outland/outland_script_loader.cpp index 2552525858..df02e86d36 100644 --- a/src/server/scripts/Outland/outland_script_loader.cpp +++ b/src/server/scripts/Outland/outland_script_loader.cpp @@ -29,7 +29,6 @@ void AddSC_boss_ambassador_hellmaw(); void AddSC_boss_blackheart_the_inciter(); void AddSC_boss_grandmaster_vorpil(); void AddSC_boss_murmur(); -void AddSC_shadow_labyrinth(); void AddSC_boss_illidan(); //Black Temple void AddSC_boss_shade_of_akama(); void AddSC_boss_supremus(); @@ -123,7 +122,6 @@ void AddOutlandScripts() AddSC_boss_blackheart_the_inciter(); AddSC_boss_grandmaster_vorpil(); AddSC_boss_murmur(); - AddSC_shadow_labyrinth(); AddSC_boss_illidan(); //Black Temple AddSC_boss_shade_of_akama(); AddSC_boss_supremus(); diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index bd380476e3..2533462a50 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -21,11 +21,7 @@ */ #include "ScriptMgr.h" -#include "CreatureAIImpl.h" #include "ScriptedCreature.h" -#include "SpellScript.h" -#include "SpellAuraEffects.h" -#include "TemporarySummon.h" enum HunterSpells { @@ -36,26 +32,6 @@ enum HunterSpells SPELL_HUNTER_PET_SCALING = 62915 }; -enum HunterCreatures -{ - NPC_HUNTER_VIPER = 19921 -}; - -enum PetSpellsMisc -{ - SPELL_PET_GUARD_DOG_HAPPINESS = 54445, - SPELL_PET_SILVERBACK_RANK_1 = 62800, - SPELL_PET_SILVERBACK_RANK_2 = 62801, - - SPELL_PET_SWOOP = 52825, - SPELL_PET_CHARGE = 61685, - - PET_ICON_ID_GROWL = 201, - PET_ICON_ID_CLAW = 262, - PET_ICON_ID_BITE = 1680, - PET_ICON_ID_SMACK = 473 -}; - struct npc_pet_hunter_snake_trap : public ScriptedAI { npc_pet_hunter_snake_trap(Creature* creature) : ScriptedAI(creature) { _init = false; } @@ -162,156 +138,7 @@ private: uint32 _spellTimer; }; -// 57627 - Charge -class spell_pet_charge : public AuraScript -{ - PrepareAuraScript(spell_pet_charge); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PET_SWOOP, - SPELL_PET_CHARGE - }); - } - - void HandleDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // Remove +% AP aura - Unit* pet = eventInfo.GetActor(); - Aura* aura = pet->GetAura(SPELL_PET_SWOOP, pet->GetGUID()); - if (!aura) - aura = pet->GetAura(SPELL_PET_CHARGE, pet->GetGUID()); - - if (!aura) - return; - - aura->DropCharge(AURA_REMOVE_BY_EXPIRE); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pet_charge::HandleDummy, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -53178 - Guard Dog -class spell_pet_guard_dog : public AuraScript -{ - PrepareAuraScript(spell_pet_guard_dog); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Growl shares family flags with other spells - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - caster->CastSpell((Unit*)nullptr, SPELL_PET_GUARD_DOG_HAPPINESS, true, nullptr, aurEff); - - float addThreat = CalculatePct(eventInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount()); - eventInfo.GetProcTarget()->AddThreat(caster, addThreat); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pet_guard_dog::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pet_guard_dog::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -62764 - Silverback -class spell_pet_silverback : public AuraScript -{ - PrepareAuraScript(spell_pet_silverback); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PET_GUARD_DOG_HAPPINESS }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Growl shares family flags with other spells - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != PET_ICON_ID_GROWL) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static uint32 const triggerSpell[2] = { SPELL_PET_SILVERBACK_RANK_1, SPELL_PET_SILVERBACK_RANK_2 }; - - PreventDefaultAction(); - - uint32 spellId = triggerSpell[GetSpellInfo()->GetRank() - 1]; - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pet_silverback::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pet_silverback::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -61680 - Culling the Herd -class spell_pet_culling_the_herd : public AuraScript -{ - PrepareAuraScript(spell_pet_culling_the_herd); - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Claw, Bite and Smack share FamilyFlags with other spells - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - switch (spellInfo->SpellIconID) - { - case PET_ICON_ID_CLAW: - case PET_ICON_ID_BITE: - case PET_ICON_ID_SMACK: - break; - default: - return false; - } - - return true; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pet_culling_the_herd::CheckProc); - } -}; - void AddSC_hunter_pet_scripts() { RegisterCreatureAI(npc_pet_hunter_snake_trap); - RegisterSpellScript(spell_pet_charge); - RegisterSpellScript(spell_pet_guard_dog); - RegisterSpellScript(spell_pet_silverback); - RegisterSpellScript(spell_pet_culling_the_herd); } diff --git a/src/server/scripts/Pet/pet_priest.cpp b/src/server/scripts/Pet/pet_priest.cpp index 732943444f..1f6b2f9647 100644 --- a/src/server/scripts/Pet/pet_priest.cpp +++ b/src/server/scripts/Pet/pet_priest.cpp @@ -29,7 +29,7 @@ enum PriestSpells { SPELL_PRIEST_GLYPH_OF_SHADOWFIEND = 58228, - SPELL_PRIEST_SHADOWFIEND_DEATH = 57989, + SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA = 58227, SPELL_PRIEST_SHADOWFIEND_DODGE = 8273, SPELL_PRIEST_LIGHTWELL_CHARGES = 59907 }; @@ -67,10 +67,12 @@ struct npc_pet_pri_shadowfiend : public PetAI AttackStart(target); } - void IsSummonedBy(Unit* summoner) override + void JustDied(Unit* /*killer*/) override { - if (summoner->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOWFIEND)) - DoCastAOE(SPELL_PRIEST_SHADOWFIEND_DEATH); + if (me->IsSummon()) + if (Unit* owner = me->ToTempSummon()->GetSummonerUnit()) + if (owner->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOWFIEND)) + owner->CastSpell(owner, SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA, true); } }; diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 07aee4a416..88ed7bec24 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -33,13 +33,6 @@ enum DeathKnightSpells { - SPELL_DK_ACCLIMATION_HOLY = 50490, - SPELL_DK_ACCLIMATION_FIRE = 50362, - SPELL_DK_ACCLIMATION_FROST = 50485, - SPELL_DK_ACCLIMATION_ARCANE = 50486, - SPELL_DK_ACCLIMATION_SHADOW = 50489, - SPELL_DK_ACCLIMATION_NATURE = 50488, - SPELL_DK_ADVANTAGE_T10_4P_MELEE = 70657, SPELL_DK_DEATH_AND_DECAY_TRIGGER = 52212, SPELL_DK_GLYPH_OF_SCOURGE_STRIKE = 58642, SPELL_DK_WANDERING_PLAGUE_TRIGGER = 50526, @@ -66,7 +59,6 @@ enum DeathKnightSpells SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1 = 50365, SPELL_DK_IMPROVED_FROST_PRESENCE_R1 = 50384, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1 = 50391, - SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL = 50475, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622, SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962, @@ -80,23 +72,7 @@ enum DeathKnightSpells SPELL_DK_UNHOLY_PRESENCE = 48265, SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772, SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, - SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284, - SPELL_DK_GLYPH_OF_SCOURGE_STRIKE_SCRIPT = 69961, - SPELL_DK_BUTCHERY_RUNIC_POWER = 50163, - SPELL_DK_MARK_OF_BLOOD_HEAL = 61607, - SPELL_DK_UNHOLY_BLIGHT_DAMAGE = 50536, - SPELL_DK_GLYPH_OF_UNHOLY_BLIGHT = 63332, - SPELL_DK_VENDETTA_HEAL = 50181, - SPELL_DK_NECROSIS_DAMAGE = 51460, - SPELL_DK_OBLITERATE_OFF_HAND_R1 = 66198, - SPELL_DK_FROST_STRIKE_OFF_HAND_R1 = 66196, - SPELL_DK_PLAGUE_STRIKE_OFF_HAND_R1 = 66216, - SPELL_DK_DEATH_STRIKE_OFF_HAND_R1 = 66188, - SPELL_DK_RUNE_STRIKE_OFF_HAND_R1 = 66217, - SPELL_DK_BLOOD_STRIKE_OFF_HAND_R1 = 66215, - SPELL_DK_RUNIC_RETURN = 61258, - SPELL_DK_WANDERING_PLAGUE_DAMAGE = 50526, - SPELL_DK_DEATH_COIL_R1 = 47541, + SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284 }; enum DeathKnightSpellIcons @@ -106,130 +82,7 @@ enum DeathKnightSpellIcons enum Misc { - NPC_DK_GHOUL = 26125, - NPC_DK_DANCING_RUNE_WEAPON = 27893, - SPELL_CATEGORY_HOWLING_BLAST = 1248 -}; - -// -49200 - Acclimation -class spell_dk_acclimation : public AuraScript -{ - PrepareAuraScript(spell_dk_acclimation); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_HOLY) || - !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_FIRE) || - !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_FROST) || - !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_NATURE) || - !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_SHADOW) || - !sSpellMgr->GetSpellInfo(SPELL_DK_ACCLIMATION_ARCANE)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetDamageInfo()) - { - switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) - { - case SPELL_SCHOOL_HOLY: - case SPELL_SCHOOL_FIRE: - case SPELL_SCHOOL_NATURE: - case SPELL_SCHOOL_FROST: - case SPELL_SCHOOL_SHADOW: - case SPELL_SCHOOL_ARCANE: - return true; - default: - break; - } - } - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - uint32 triggerspell = 0; - - switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) - { - case SPELL_SCHOOL_HOLY: - triggerspell = SPELL_DK_ACCLIMATION_HOLY; - break; - case SPELL_SCHOOL_FIRE: - triggerspell = SPELL_DK_ACCLIMATION_FIRE; - break; - case SPELL_SCHOOL_NATURE: - triggerspell = SPELL_DK_ACCLIMATION_NATURE; - break; - case SPELL_SCHOOL_FROST: - triggerspell = SPELL_DK_ACCLIMATION_FROST; - break; - case SPELL_SCHOOL_SHADOW: - triggerspell = SPELL_DK_ACCLIMATION_SHADOW; - break; - case SPELL_SCHOOL_ARCANE: - triggerspell = SPELL_DK_ACCLIMATION_ARCANE; - break; - default: - return; - } - - if (Unit* target = eventInfo.GetActionTarget()) - { - target->CastSpell(target, triggerspell, true, nullptr, aurEff); - } - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dk_acclimation::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dk_acclimation::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 70656 - Advantage (T10 4P Melee Bonus) -class spell_dk_advantage_t10_4p : public AuraScript -{ - PrepareAuraScript(spell_dk_advantage_t10_4p); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_ADVANTAGE_T10_4P_MELEE)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (Unit* caster = eventInfo.GetActor()) - { - if (caster->GetTypeId() != TYPEID_PLAYER || caster->getClass() != CLASS_DEATH_KNIGHT) - { - return false; - } - - for (uint8 i = 0; i < MAX_RUNES; ++i) - { - if (caster->ToPlayer()->GetRuneCooldown(i) == 0) - { - return false; - } - } - - return true; - } - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dk_advantage_t10_4p::CheckProc); - } + NPC_DK_GHOUL = 26125 }; // 50526 - Wandering Plague @@ -585,38 +438,19 @@ class spell_dk_summon_gargoyle : public SpellScript } }; -// 63611 - Improved Blood Presence Triggered +// 63611 - Improved Blood Presence class spell_dk_improved_blood_presence_proc : public AuraScript { PrepareAuraScript(spell_dk_improved_blood_presence_proc); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL)) - return false; - return true; - } - bool CheckProc(ProcEventInfo& eventInfo) { - if (eventInfo.GetActor()->GetTypeId() == TYPEID_PLAYER) - return true; - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) - eventInfo.GetActor()->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_HEAL, SPELLVALUE_BASE_POINT0, CalculatePct(int32(dmgInfo->GetDamage()), aurEff->GetAmount()), - eventInfo.GetActor(), true, nullptr, aurEff); + return eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetDamage(); } void Register() override { DoCheckProc += AuraCheckProcFn(spell_dk_improved_blood_presence_proc::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dk_improved_blood_presence_proc::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -643,7 +477,7 @@ class spell_dk_wandering_plague_aura : public AuraScript PreventDefaultAction(); eventInfo.GetActor()->AddSpellCooldown(SPELL_DK_WANDERING_PLAGUE_TRIGGER, 0, 1000); - eventInfo.GetActor()->CastCustomSpell(SPELL_DK_WANDERING_PLAGUE_TRIGGER, SPELLVALUE_BASE_POINT0, CalculatePct<int32, int32>(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()), eventInfo.GetActionTarget(), TRIGGERED_FULL_MASK, nullptr, aurEff); + eventInfo.GetActor()->CastCustomSpell(SPELL_DK_WANDERING_PLAGUE_TRIGGER, SPELLVALUE_BASE_POINT0, CalculatePct<int32, int32>(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()), eventInfo.GetActionTarget(), TRIGGERED_FULL_MASK); } void Register() override @@ -859,7 +693,7 @@ class spell_dk_scent_of_blood_trigger : public AuraScript bool CheckProc(ProcEventInfo& eventInfo) { - return (eventInfo.GetHitMask() & (PROC_HIT_DODGE | PROC_HIT_PARRY)) || (eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetDamage()); + return (eventInfo.GetHitMask() & (PROC_EX_DODGE | PROC_EX_PARRY)) || (eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetDamage()); } void Register() override @@ -2301,287 +2135,8 @@ class spell_dk_will_of_the_necropolis : public AuraScript } }; -// -49182 - Blade Barrier -class spell_dk_blade_barrier : public AuraScript -{ - PrepareAuraScript(spell_dk_blade_barrier); - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetSpellInfo() != nullptr) - if (Player* player = eventInfo.GetActor()->ToPlayer()) - if (player->getClass() == CLASS_DEATH_KNIGHT && player->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) - return true; - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dk_blade_barrier::CheckProc); - } -}; - -// -48979 - Butchery -class spell_dk_butchery : public AuraScript -{ - PrepareAuraScript(spell_dk_butchery); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_BUTCHERY_RUNIC_POWER }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastCustomSpell(SPELL_DK_BUTCHERY_RUNIC_POWER, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_butchery::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 58642 - Glyph of Scourge Strike -class spell_dk_glyph_of_scourge_strike : public AuraScript -{ - PrepareAuraScript(spell_dk_glyph_of_scourge_strike); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_GLYPH_OF_SCOURGE_STRIKE_SCRIPT }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_DK_GLYPH_OF_SCOURGE_STRIKE_SCRIPT, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_glyph_of_scourge_strike::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 61257 - Runic Power Back on Snare/Root -class spell_dk_pvp_4p_bonus : public AuraScript -{ - PrepareAuraScript(spell_dk_pvp_4p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_RUNIC_RETURN }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - return (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_SNARE))) != 0; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActionTarget()->CastSpell((Unit*)nullptr, SPELL_DK_RUNIC_RETURN, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dk_pvp_4p_bonus::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dk_pvp_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 49005 - Mark of Blood -class spell_dk_mark_of_blood : public AuraScript -{ - PrepareAuraScript(spell_dk_mark_of_blood); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_MARK_OF_BLOOD_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_DK_MARK_OF_BLOOD_HEAL, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_mark_of_blood::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -51459 - Necrosis -class spell_dk_necrosis : public AuraScript -{ - PrepareAuraScript(spell_dk_necrosis); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_NECROSIS_DAMAGE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - eventInfo.GetActor()->CastCustomSpell(SPELL_DK_NECROSIS_DAMAGE, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_necrosis::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -49018 - Sudden Doom -class spell_dk_sudden_doom : public AuraScript -{ - PrepareAuraScript(spell_dk_sudden_doom); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_DEATH_COIL_R1 }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DK_DEATH_COIL_R1); - uint32 spellId = 0; - - while (spellInfo) - { - if (!caster->HasSpell(spellInfo->Id)) - break; - - spellId = spellInfo->Id; - spellInfo = spellInfo->GetNextRankSpell(); - } - - if (!spellId) - return; - - caster->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_sudden_doom::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -65661 Threat of Thassarian -class spell_dk_threat_of_thassarian : public AuraScript -{ - PrepareAuraScript(spell_dk_threat_of_thassarian); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DK_OBLITERATE_OFF_HAND_R1, - SPELL_DK_FROST_STRIKE_OFF_HAND_R1, - SPELL_DK_PLAGUE_STRIKE_OFF_HAND_R1, - SPELL_DK_DEATH_STRIKE_OFF_HAND_R1, - SPELL_DK_RUNE_STRIKE_OFF_HAND_R1, - SPELL_DK_BLOOD_STRIKE_OFF_HAND_R1 - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - if (!roll_chance_i(aurEff->GetAmount())) - return; - - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - // Must dual wield - Unit* caster = eventInfo.GetActor(); - if (!caster->haveOffhandWeapon()) - return; - - uint32 spellId = 0; - // Plague Strike - if (spellInfo->SpellFamilyFlags[0] & 0x00000001) - spellId = SPELL_DK_PLAGUE_STRIKE_OFF_HAND_R1; - // Death Strike - else if (spellInfo->SpellFamilyFlags[0] & 0x00000010) - spellId = SPELL_DK_DEATH_STRIKE_OFF_HAND_R1; - // Blood Strike - else if (spellInfo->SpellFamilyFlags[0] & 0x00400000) - spellId = SPELL_DK_BLOOD_STRIKE_OFF_HAND_R1; - // Frost Strike - else if (spellInfo->SpellFamilyFlags[1] & 0x00000004) - spellId = SPELL_DK_FROST_STRIKE_OFF_HAND_R1; - // Obliterate - else if (spellInfo->SpellFamilyFlags[1] & 0x00020000) - spellId = SPELL_DK_OBLITERATE_OFF_HAND_R1; - // Rune Strike - else if (spellInfo->SpellFamilyFlags[1] & 0x20000000) - spellId = SPELL_DK_RUNE_STRIKE_OFF_HAND_R1; - - if (!spellId) - return; - - spellId = sSpellMgr->GetSpellWithRank(spellId, spellInfo->GetRank()); - caster->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_threat_of_thassarian::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -49015 - Vendetta -class spell_dk_vendetta : public AuraScript -{ - PrepareAuraScript(spell_dk_vendetta); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DK_VENDETTA_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - int32 amount = caster->CountPctFromMaxHealth(aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_DK_VENDETTA_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dk_vendetta::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - void AddSC_deathknight_spell_scripts() { - RegisterSpellScript(spell_dk_acclimation); - RegisterSpellScript(spell_dk_advantage_t10_4p); RegisterSpellScript(spell_dk_wandering_plague); RegisterSpellScript(spell_dk_raise_ally); RegisterSpellScript(spell_dk_raise_ally_trigger); @@ -2626,13 +2181,4 @@ void AddSC_deathknight_spell_scripts() RegisterSpellScript(spell_dk_spell_deflection); RegisterSpellScript(spell_dk_vampiric_blood); RegisterSpellScript(spell_dk_will_of_the_necropolis); - RegisterSpellScript(spell_dk_blade_barrier); - RegisterSpellScript(spell_dk_butchery); - RegisterSpellScript(spell_dk_glyph_of_scourge_strike); - RegisterSpellScript(spell_dk_pvp_4p_bonus); - RegisterSpellScript(spell_dk_mark_of_blood); - RegisterSpellScript(spell_dk_necrosis); - RegisterSpellScript(spell_dk_sudden_doom); - RegisterSpellScript(spell_dk_threat_of_thassarian); - RegisterSpellScript(spell_dk_vendetta); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 0811fa9e50..d7f697a33f 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -55,45 +55,12 @@ enum DruidSpells SPELL_DRUID_SURVIVAL_INSTINCTS = 50322, SPELL_DRUID_SAVAGE_ROAR = 62071, SPELL_DRUID_TIGER_S_FURY_ENERGIZE = 51178, - SPELL_DRUID_T9_FERAL_RELIC_BEAR = 67354, - SPELL_DRUID_T9_FERAL_RELIC_CAT = 67355, SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950, SPELL_DRUID_BEAR_FORM_PASSIVE = 1178, SPELL_DRUID_DIRE_BEAR_FORM_PASSIVE = 9635, - SPELL_DRUID_FORMS_TRINKET_BEAR = 37340, - SPELL_DRUID_FORMS_TRINKET_CAT = 37341, - SPELL_DRUID_FORMS_TRINKET_MOONKIN = 37343, - SPELL_DRUID_FORMS_TRINKET_NONE = 37344, - SPELL_DRUID_FORMS_TRINKET_TREE = 37342, SPELL_DRUID_ENRAGE = 5229, SPELL_DRUID_ENRAGED_DEFENSE = 70725, SPELL_DRUID_ITEM_T10_FERAL_4P_BONUS = 70726, - SPELL_DRUID_T3_PROC_ENERGIZE_MANA = 28722, - SPELL_DRUID_T3_PROC_ENERGIZE_RAGE = 28723, - SPELL_DRUID_T3_PROC_ENERGIZE_ENERGY = 28724, - SPELL_DRUID_BLESSING_OF_THE_CLAW = 28750, - SPELL_DRUID_REVITALIZE_ENERGIZE_MANA = 48542, - SPELL_DRUID_REVITALIZE_ENERGIZE_RAGE = 48541, - SPELL_DRUID_REVITALIZE_ENERGIZE_ENERGY = 48540, - SPELL_DRUID_REVITALIZE_ENERGIZE_RP = 48543, - SPELL_DRUID_GLYPH_OF_INNERVATE_REGEN = 54833, - SPELL_DRUID_GLYPH_OF_STARFIRE_SCRIPT = 54846, - SPELL_DRUID_GLYPH_OF_RIP = 54818, - SPELL_DRUID_RIP_DURATION_LACERATE_DMG = 60141, - SPELL_DRUID_GLYPH_OF_RAKE_TRIGGERED = 54820, - SPELL_DRUID_IMP_LEADER_OF_THE_PACK_R1 = 34297, - SPELL_DRUID_IMP_LEADER_OF_THE_PACK_HEAL = 34299, - SPELL_DRUID_IMP_LEADER_OF_THE_PACK_MANA = 68285, - SPELL_DRUID_EXHILARATE = 28742, - SPELL_DRUID_GLYPH_OF_REJUVENATION_HEAL = 54755, - SPELL_DRUID_INFUSION = 37238, - SPELL_DRUID_BLESSING_OF_REMULOS = 40445, - SPELL_DRUID_BLESSING_OF_ELUNE = 40446, - SPELL_DRUID_BLESSING_OF_CENARIUS = 40452, - SPELL_DRUID_LANGUISH = 71023, - SPELL_DRUID_REJUVENATION_T10_PROC = 70691, - SPELL_DRUID_BALANCE_T10_BONUS = 70718, - SPELL_DRUID_BALANCE_T10_BONUS_PROC = 70721 }; // 1178 - Bear Form (Passive) @@ -272,7 +239,7 @@ class spell_dru_brambles_treant : public AuraScript { int32 amount = 0; if (player->HasAura(SPELL_DRUID_BARKSKIN, player->GetGUID())) - player->ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(SPELL_DRUID_BARKSKIN, amount); + player->ApplySpellMod(SPELL_DRUID_BARKSKIN, SPELLMOD_CHANCE_OF_SUCCESS, amount); return roll_chance_i(amount); } @@ -287,7 +254,7 @@ class spell_dru_brambles_treant : public AuraScript if (GetUnitOwner()->IsSummon()) if (Unit* owner = GetUnitOwner()->ToTempSummon()->GetSummonerUnit()) if (Player* player = owner->GetSpellModOwner()) - player->ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(SPELL_DRUID_BARKSKIN, amount); + player->ApplySpellMod(SPELL_DRUID_BARKSKIN, SPELLMOD_CHANCE_OF_SUCCESS, amount); } void Register() override @@ -478,80 +445,6 @@ class spell_dru_enrage : public AuraScript } }; -// 37336 - Druid Forms Trinket -class spell_dru_forms_trinket : public AuraScript -{ - PrepareAuraScript(spell_dru_forms_trinket); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_BEAR) || - !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_CAT) || - !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_MOONKIN) || - !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_NONE) || - !sSpellMgr->GetSpellInfo(SPELL_DRUID_FORMS_TRINKET_TREE)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - Unit* target = eventInfo.GetActor(); - - switch (target->GetShapeshiftForm()) - { - case FORM_BEAR: - case FORM_DIREBEAR: - case FORM_CAT: - case FORM_MOONKIN: - case FORM_NONE: - case FORM_TREE: - return true; - default: - break; - } - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* target = eventInfo.GetActor(); - uint32 triggerspell = 0; - - switch (target->GetShapeshiftForm()) - { - case FORM_BEAR: - case FORM_DIREBEAR: - triggerspell = SPELL_DRUID_FORMS_TRINKET_BEAR; - break; - case FORM_CAT: - triggerspell = SPELL_DRUID_FORMS_TRINKET_CAT; - break; - case FORM_MOONKIN: - triggerspell = SPELL_DRUID_FORMS_TRINKET_MOONKIN; - break; - case FORM_NONE: - triggerspell = SPELL_DRUID_FORMS_TRINKET_NONE; - break; - case FORM_TREE: - triggerspell = SPELL_DRUID_FORMS_TRINKET_TREE; - break; - default: - return; - } - - target->CastSpell(target, triggerspell, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dru_forms_trinket::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dru_forms_trinket::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 54846 - Glyph of Starfire class spell_dru_glyph_of_starfire : public SpellScript { @@ -904,27 +797,35 @@ class spell_dru_rip : public AuraScript } }; -// 62600 - Savage Defense +// 62606 - Savage Defense class spell_dru_savage_defense : public AuraScript { PrepareAuraScript(spell_dru_savage_defense); - bool Validate(SpellInfo const* spellInfo) override + uint32 absorbPct; + + bool Load() override { - return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell }); + absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster()); + return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - int32 amount = static_cast<int32>(CalculatePct(caster->GetTotalAttackPowerValue(BASE_ATTACK), aurEff->GetAmount())); - caster->CastCustomSpell(GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect* aurEff, DamageInfo& /*dmgInfo*/, uint32& absorbAmount) + { + absorbAmount = uint32(CalculatePct(GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK), absorbPct)); + aurEff->SetAmount(0); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_dru_savage_defense::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_savage_defense::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_savage_defense::Absorb, EFFECT_0); } }; @@ -1059,7 +960,7 @@ class spell_dru_survival_instincts_aura : public AuraScript { Unit* target = GetTarget(); int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount()); - target->CastCustomSpell(target, SPELL_DRUID_SURVIVAL_INSTINCTS, &bp0, nullptr, nullptr, true, nullptr, aurEff); + target->CastCustomSpell(target, SPELL_DRUID_SURVIVAL_INSTINCTS, &bp0, nullptr, nullptr, true); } void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) @@ -1132,66 +1033,6 @@ class spell_dru_typhoon : public SpellScript } }; -// 67353 - T9 Feral Relic (Idol of Mutilation) -class spell_dru_t9_feral_relic : public AuraScript -{ - PrepareAuraScript(spell_dru_t9_feral_relic); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_T9_FERAL_RELIC_BEAR) || - !sSpellMgr->GetSpellInfo(SPELL_DRUID_T9_FERAL_RELIC_CAT)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - Unit* target = eventInfo.GetActor(); - - switch (target->GetShapeshiftForm()) - { - case FORM_BEAR: - case FORM_DIREBEAR: - case FORM_CAT: - return true; - default: - break; - } - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - uint32 triggerspell = 0; - - Unit* target = eventInfo.GetActor(); - - switch (target->GetShapeshiftForm()) - { - case FORM_BEAR: - case FORM_DIREBEAR: - triggerspell = SPELL_DRUID_T9_FERAL_RELIC_BEAR; - break; - case FORM_CAT: - triggerspell = SPELL_DRUID_T9_FERAL_RELIC_CAT; - break; - default: - return; - } - - target->CastSpell(target, triggerspell, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dru_t9_feral_relic::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dru_t9_feral_relic::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 70691 - Rejuvenation class spell_dru_t10_restoration_4p_bonus : public SpellScript { @@ -1309,441 +1150,6 @@ class spell_dru_berserk : public SpellScript } }; -// 54832 - Glyph of Innervate -class spell_dru_glyph_of_innervate : public AuraScript -{ - PrepareAuraScript(spell_dru_glyph_of_innervate); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_INNERVATE_REGEN }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DRUID_GLYPH_OF_INNERVATE_REGEN); - int32 amount = CalculatePct(static_cast<int32>(caster->GetCreatePowers(POWER_MANA)), aurEff->GetAmount()); - amount /= spellInfo->GetMaxTicks(); - - caster->CastCustomSpell(SPELL_DRUID_GLYPH_OF_INNERVATE_REGEN, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_innervate::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 54821 - Glyph of Rake -class spell_dru_glyph_of_rake : public AuraScript -{ - PrepareAuraScript(spell_dru_glyph_of_rake); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_RAKE_TRIGGERED }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget()->GetTypeId() == TYPEID_UNIT; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_DRUID_GLYPH_OF_RAKE_TRIGGERED, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_rake::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_rake::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 54754 - Glyph of Rejuvenation -class spell_dru_glyph_of_rejuvenation : public AuraScript -{ - PrepareAuraScript(spell_dru_glyph_of_rejuvenation); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_REJUVENATION_HEAL }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget()->HealthBelowPct(50); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount()); - eventInfo.GetActor()->CastCustomSpell(SPELL_DRUID_GLYPH_OF_REJUVENATION_HEAL, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_rejuvenation::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_rejuvenation::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 54815 - Glyph of Shred -class spell_dru_glyph_of_shred : public AuraScript -{ - PrepareAuraScript(spell_dru_glyph_of_shred); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DRUID_GLYPH_OF_RIP, - SPELL_DRUID_RIP_DURATION_LACERATE_DMG - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - // try to find spell Rip on the target - if (AuraEffect const* rip = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00800000, 0x0, 0x0, caster->GetGUID())) - { - // Rip's max duration, note: spells which modifies Rip's duration also counted like Glyph of Rip - uint32 countMin = rip->GetBase()->GetMaxDuration(); - - // just Rip's max duration without other spells - uint32 countMax = rip->GetSpellInfo()->GetMaxDuration(); - - // add possible auras' and Glyph of Shred's max duration - countMax += 3 * aurEff->GetAmount() * IN_MILLISECONDS; // Glyph of Shred -> +6 seconds - countMax += caster->HasAura(SPELL_DRUID_GLYPH_OF_RIP) ? 4 * IN_MILLISECONDS : 0; // Glyph of Rip -> +4 seconds - countMax += caster->HasAura(SPELL_DRUID_RIP_DURATION_LACERATE_DMG) ? 4 * IN_MILLISECONDS : 0; // T7 set bonus -> +4 seconds - - // if min < max -> that means caster didn't cast 3 shred yet - // so set Rip's duration and max duration - if (countMin < countMax) - { - rip->GetBase()->SetDuration(rip->GetBase()->GetDuration() + aurEff->GetAmount() * IN_MILLISECONDS); - rip->GetBase()->SetMaxDuration(countMin + aurEff->GetAmount() * IN_MILLISECONDS); - } - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_shred::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 54845 - Glyph of Starfire -class spell_dru_glyph_of_starfire_dummy : public AuraScript -{ - PrepareAuraScript(spell_dru_glyph_of_starfire_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_GLYPH_OF_STARFIRE_SCRIPT }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_DRUID_GLYPH_OF_STARFIRE_SCRIPT, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_starfire_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -48539 - Revitalize -class spell_dru_revitalize : public AuraScript -{ - PrepareAuraScript(spell_dru_revitalize); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DRUID_REVITALIZE_ENERGIZE_MANA, - SPELL_DRUID_REVITALIZE_ENERGIZE_RAGE, - SPELL_DRUID_REVITALIZE_ENERGIZE_ENERGY, - SPELL_DRUID_REVITALIZE_ENERGIZE_RP - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (!roll_chance_i(aurEff->GetAmount())) - return; - - Unit* target = eventInfo.GetProcTarget(); - uint32 spellId; - - switch (target->getPowerType()) - { - case POWER_MANA: - spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_MANA; - break; - case POWER_RAGE: - spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_RAGE; - break; - case POWER_ENERGY: - spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_ENERGY; - break; - case POWER_RUNIC_POWER: - spellId = SPELL_DRUID_REVITALIZE_ENERGIZE_RP; - break; - default: - return; - } - - eventInfo.GetActor()->CastSpell(target, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_revitalize::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - } -}; - -// 28716 - Rejuvenation -class spell_dru_t3_2p_bonus : public AuraScript -{ - PrepareAuraScript(spell_dru_t3_2p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DRUID_T3_PROC_ENERGIZE_MANA, - SPELL_DRUID_T3_PROC_ENERGIZE_RAGE, - SPELL_DRUID_T3_PROC_ENERGIZE_ENERGY - }); - } - - bool CheckProc(ProcEventInfo& /*eventInfo*/) - { - if (!roll_chance_i(50)) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* target = eventInfo.GetProcTarget(); - uint32 spellId; - - switch (target->getPowerType()) - { - case POWER_MANA: - spellId = SPELL_DRUID_T3_PROC_ENERGIZE_MANA; - break; - case POWER_RAGE: - spellId = SPELL_DRUID_T3_PROC_ENERGIZE_RAGE; - break; - case POWER_ENERGY: - spellId = SPELL_DRUID_T3_PROC_ENERGIZE_ENERGY; - break; - default: - return; - } - - eventInfo.GetActor()->CastSpell(target, spellId, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dru_t3_2p_bonus::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dru_t3_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - } -}; - -// 28744 - Regrowth -class spell_dru_t3_6p_bonus : public AuraScript -{ - PrepareAuraScript(spell_dru_t3_6p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_BLESSING_OF_THE_CLAW }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_DRUID_BLESSING_OF_THE_CLAW, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_t3_6p_bonus::HandleProc, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - } -}; - -// 28719 - Healing Touch -class spell_dru_t3_8p_bonus : public AuraScript -{ - PrepareAuraScript(spell_dru_t3_8p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_EXHILARATE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - Unit* caster = eventInfo.GetActor(); - int32 amount = CalculatePct(spellInfo->CalcPowerCost(caster, spellInfo->GetSchoolMask()), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_DRUID_EXHILARATE, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_t3_8p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 37288 - Mana Restore -// 37295 - Mana Restore -class spell_dru_t4_2p_bonus : public AuraScript -{ - PrepareAuraScript(spell_dru_t4_2p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_INFUSION }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_DRUID_INFUSION, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_t4_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 40442 - Druid Tier 6 Trinket -class spell_dru_item_t6_trinket : public AuraScript -{ - PrepareAuraScript(spell_dru_item_t6_trinket); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DRUID_BLESSING_OF_REMULOS, - SPELL_DRUID_BLESSING_OF_ELUNE, - SPELL_DRUID_BLESSING_OF_CENARIUS - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - uint32 spellId; - int32 chance; - - // Starfire - if (spellInfo->SpellFamilyFlags[0] & 0x00000004) - { - spellId = SPELL_DRUID_BLESSING_OF_REMULOS; - chance = 25; - } - // Rejuvenation - else if (spellInfo->SpellFamilyFlags[0] & 0x00000010) - { - spellId = SPELL_DRUID_BLESSING_OF_ELUNE; - chance = 25; - } - // Mangle (Bear) and Mangle (Cat) - else if (spellInfo->SpellFamilyFlags[1] & 0x00000440) - { - spellId = SPELL_DRUID_BLESSING_OF_CENARIUS; - chance = 40; - } else - return; - - if (roll_chance_i(chance)) - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_dru_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 70664 - Druid T10 Restoration 4P Bonus (Rejuvenation) -class spell_dru_t10_restoration_4p_bonus_dummy : public AuraScript -{ - PrepareAuraScript(spell_dru_t10_restoration_4p_bonus_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRUID_REJUVENATION_T10_PROC }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->Id == SPELL_DRUID_REJUVENATION_T10_PROC) - return false; - - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return false; - - Player* caster = eventInfo.GetActor()->ToPlayer(); - if (!caster) - return false; - - return caster->GetGroup() || caster != eventInfo.GetProcTarget(); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - int32 amount = static_cast<int32>(eventInfo.GetHealInfo()->GetHeal()); - eventInfo.GetActor()->CastCustomSpell(SPELL_DRUID_REJUVENATION_T10_PROC, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_dru_t10_restoration_4p_bonus_dummy::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_dru_t10_restoration_4p_bonus_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 24905 - Moonkin Form (Passive) class spell_dru_moonkin_form_passive_proc : public AuraScript { @@ -1778,7 +1184,6 @@ void AddSC_druid_spell_scripts() RegisterSpellScript(spell_dru_berserk); RegisterSpellScript(spell_dru_dash); RegisterSpellScript(spell_dru_enrage); - RegisterSpellScript(spell_dru_forms_trinket); RegisterSpellScript(spell_dru_glyph_of_starfire); RegisterSpellScript(spell_dru_idol_lifebloom); RegisterSpellScript(spell_dru_innervate); @@ -1799,20 +1204,7 @@ void AddSC_druid_spell_scripts() RegisterSpellScript(spell_dru_swift_flight_passive); RegisterSpellScript(spell_dru_tiger_s_fury); RegisterSpellScript(spell_dru_typhoon); - RegisterSpellScript(spell_dru_t9_feral_relic); RegisterSpellScript(spell_dru_t10_restoration_4p_bonus); RegisterSpellScript(spell_dru_wild_growth); - RegisterSpellScript(spell_dru_glyph_of_innervate); - RegisterSpellScript(spell_dru_glyph_of_rake); - RegisterSpellScript(spell_dru_glyph_of_rejuvenation); - RegisterSpellScript(spell_dru_glyph_of_shred); - RegisterSpellScript(spell_dru_glyph_of_starfire_dummy); - RegisterSpellScript(spell_dru_revitalize); - RegisterSpellScript(spell_dru_t3_2p_bonus); - RegisterSpellScript(spell_dru_t3_6p_bonus); - RegisterSpellScript(spell_dru_t3_8p_bonus); - RegisterSpellScript(spell_dru_t4_2p_bonus); - RegisterSpellScript(spell_dru_item_t6_trinket); - RegisterSpellScript(spell_dru_t10_restoration_4p_bonus_dummy); RegisterSpellScript(spell_dru_moonkin_form_passive_proc); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 019ecf37bb..7e16ae4f60 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -848,7 +848,8 @@ class spell_gen_fixate_aura : public AuraScript } }; -// 64440 - Blade Warding +/* 64440 - Blade Warding + 64568 - Blood Reserve */ class spell_gen_proc_above_75 : public AuraScript { PrepareAuraScript(spell_gen_proc_above_75); @@ -3633,53 +3634,6 @@ class spell_gen_bandage : public SpellScript } }; -// Blood Reserve - 64568 -enum BloodReserve -{ - SPELL_GEN_BLOOD_RESERVE_AURA = 64568, - SPELL_GEN_BLOOD_RESERVE_HEAL = 64569 -}; - -class spell_gen_blood_reserve : public AuraScript -{ - PrepareAuraScript(spell_gen_blood_reserve); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_GEN_BLOOD_RESERVE_HEAL)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (Unit* caster = eventInfo.GetActionTarget()) - { - if (caster->HealthBelowPct(35)) - { - return true; - } - } - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActionTarget(); - caster->CastCustomSpell(SPELL_GEN_BLOOD_RESERVE_HEAL, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), caster, TRIGGERED_FULL_MASK, nullptr, aurEff); - caster->RemoveAura(SPELL_GEN_BLOOD_RESERVE_AURA); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_gen_blood_reserve::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_gen_blood_reserve::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - enum ParalyticPoison { SPELL_PARALYSIS = 35202 @@ -4540,7 +4494,7 @@ public: return ValidateSpellInfo({ _spellId1, _spellId2 }); } - void HandleProc(AuraEffect* aurEff) + void HandleProc(AuraEffect* /*aurEff*/) { if (Unit* caster = GetCaster()) { @@ -4550,7 +4504,7 @@ public: return; } - caster->CastSpell(GetUnitOwner(), _spellId1, true, nullptr, aurEff); + caster->CastSpell(GetUnitOwner(), _spellId1, true); } } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index ec0279f8c1..bead129960 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -61,25 +61,15 @@ enum HunterSpells SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114, SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711, SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED = 54045, - SPELL_HUNTER_PIERCING_SHOTS = 63468, SPELL_HUNTER_READINESS = 23989, SPELL_HUNTER_SNIPER_TRAINING_R1 = 53302, SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 = 64418, - SPELL_HUNTER_T9_4P_GREATNESS = 68130, SPELL_HUNTER_VICIOUS_VIPER = 61609, SPELL_HUNTER_VIPER_ATTACK_SPEED = 60144, SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543, SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT = 61389, SPELL_LOCK_AND_LOAD_TRIGGER = 56453, - SPELL_LOCK_AND_LOAD_MARKER = 67544, - SPELL_HUNTER_LOCK_AND_LOAD_TRIGGER = 56453, - SPELL_HUNTER_LOCK_AND_LOAD_MARKER = 67544, - SPELL_HUNTER_KILL_COMMAND_HUNTER = 34027, - SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA = 34720, - SPELL_REPLENISHMENT = 57669, - SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1 = 56654, - SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 = 58882, - SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS = 57894 + SPELL_LOCK_AND_LOAD_MARKER = 67544 }; class spell_hun_check_pet_los : public SpellScript @@ -426,7 +416,7 @@ class spell_hun_ascpect_of_the_viper : public AuraScript } }; -// 53209 - Chimera Shot +// 53209 Chimera Shot class spell_hun_chimera_shot : public SpellScript { PrepareSpellScript(spell_hun_chimera_shot); @@ -443,8 +433,8 @@ class spell_hun_chimera_shot : public SpellScript { uint32 spellId = 0; int32 basePoint = 0; - Unit::AuraApplicationMap const& auras = unitTarget->GetAppliedAuras(); - for (Unit::AuraApplicationMap::const_iterator i = auras.begin(); i != auras.end(); ++i) + Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); + for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { Aura* aura = i->second->GetBase(); if (aura->GetCasterGUID() != caster->GetGUID()) @@ -454,47 +444,53 @@ class spell_hun_chimera_shot : public SpellScript flag96 familyFlag = aura->GetSpellInfo()->SpellFamilyFlags; if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000)) continue; - if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_0)) + if (AuraEffect* aurEff = aura->GetEffect(0)) { // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. if (familyFlag[0] & 0x4000) { + int32 TickCount = aurEff->GetTotalTicks(); spellId = SPELL_HUNTER_CHIMERA_SHOT_SERPENT; - - // calculate damage of basic tick (bonuses are already factored in AuraEffect) - basePoint = aurEff->GetAmount() * aurEff->GetTotalTicks(); - ApplyPct(basePoint, 40); + basePoint = aurEff->GetAmount(); + ApplyPct(basePoint, TickCount * 40); + basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount()); } - // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. + // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. else if (familyFlag[1] & 0x00000080) { + int32 TickCount = aura->GetEffect(0)->GetTotalTicks(); spellId = SPELL_HUNTER_CHIMERA_SHOT_VIPER; - // % of mana drained in max duration - basePoint = aurEff->GetAmount() * aurEff->GetTotalTicks(); - - // max value - int32 maxManaReturn = CalculatePct(static_cast<int32>(caster->GetMaxPower(POWER_MANA)), basePoint * 2); - ApplyPct(basePoint, unitTarget->GetMaxPower(POWER_MANA)); - if (basePoint > maxManaReturn) - basePoint = maxManaReturn; - - ApplyPct(basePoint, 60); + // Amount of one aura tick + basePoint = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), aurEff->GetAmount())); + int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50; // TODO: Caster uses unitTarget? + if (basePoint > casterBasePoint) + basePoint = casterBasePoint; + ApplyPct(basePoint, TickCount * 60); } - // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. + // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. else if (familyFlag[0] & 0x00008000) + { + if (caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown + { + if (caster->ToPlayer()->HasSpellCooldown(SPELL_HUNTER_CHIMERA_SHOT_SCORPID)) + break; + + caster->ToPlayer()->AddSpellCooldown(SPELL_HUNTER_CHIMERA_SHOT_SCORPID, 0, 60000); + } + spellId = SPELL_HUNTER_CHIMERA_SHOT_SCORPID; + } // Refresh aura duration aura->RefreshDuration(); + aurEff->ChangeAmount(aurEff->CalculateAmount(caster), false); } break; } if (spellId) - { caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true); - } } } @@ -812,49 +808,6 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScript } }; -// -53234 - Piercing Shots -class spell_hun_piercing_shots : public AuraScript -{ - PrepareAuraScript(spell_hun_piercing_shots); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_PIERCING_SHOTS)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetActionTarget()) - return true; - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetActionTarget(); - - if (DamageInfo* dmgInfo = eventInfo.GetDamageInfo()) - { - SpellInfo const* piercingShots = sSpellMgr->AssertSpellInfo(SPELL_HUNTER_PIERCING_SHOTS); - uint32 dmg = dmgInfo->GetDamage(); - - uint32 bp = CalculatePct(int32(dmg), aurEff->GetAmount()) / static_cast<int32>(piercingShots->GetMaxTicks()); - - caster->CastCustomSpell(SPELL_HUNTER_PIERCING_SHOTS, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); - } - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_hun_piercing_shots::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_hun_piercing_shots::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 54044 - Pet Carrion Feeder class spell_hun_pet_carrion_feeder : public SpellScript { @@ -1055,43 +1008,6 @@ class spell_hun_tame_beast : public SpellScript } }; -// 67151 - T9 4P Bonus -class spell_hun_t9_4p_bonus : public AuraScript -{ - PrepareAuraScript(spell_hun_t9_4p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_T9_4P_GREATNESS)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetActor()->GetTypeId() == TYPEID_PLAYER && eventInfo.GetActor()->ToPlayer()->GetPet()) - { - return true; - } - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - - caster->CastSpell(caster->ToPlayer()->GetPet(), SPELL_HUNTER_T9_4P_GREATNESS, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_hun_t9_4p_bonus::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_hun_t9_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 60144 - Viper Attack Speed class spell_hun_viper_attack_speed : public AuraScript { @@ -1165,7 +1081,7 @@ class spell_hun_glyph_of_arcane_shot : public AuraScript int32 mana = procSpell->CalcPowerCost(GetTarget(), procSpell->GetSchoolMask()); ApplyPct(mana, aurEff->GetAmount()); - GetTarget()->CastCustomSpell(SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT, SPELLVALUE_BASE_POINT0, mana, GetTarget(), TRIGGERED_NONE, nullptr, aurEff); + GetTarget()->CastCustomSpell(SPELL_HUNTER_GLYPH_OF_ARCANE_SHOT, SPELLVALUE_BASE_POINT0, mana, GetTarget()); } void Register() override @@ -1314,7 +1230,7 @@ class spell_hun_lock_and_load : public AuraScript } Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, SPELL_LOCK_AND_LOAD_TRIGGER, true, nullptr, aurEff); + caster->CastSpell(caster, SPELL_LOCK_AND_LOAD_TRIGGER, true); } void ApplyMarker(ProcEventInfo& eventInfo) @@ -1392,172 +1308,6 @@ class spell_hun_bestial_wrath : public SpellScript } }; -// 57870 - Glyph of Mend Pet -class spell_hun_glyph_of_mend_pet : public AuraScript -{ - PrepareAuraScript(spell_hun_glyph_of_mend_pet); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_HUNTER_GLYPH_OF_MEND_PET_HAPPINESS, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_hun_glyph_of_mend_pet::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -53290 - Hunting Party -class spell_hun_hunting_party : public AuraScript -{ - PrepareAuraScript(spell_hun_hunting_party); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_REPLENISHMENT }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_hun_hunting_party::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 58914 - Kill Command -class spell_hun_kill_command_pet : public AuraScript -{ - PrepareAuraScript(spell_hun_kill_command_pet); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HUNTER_KILL_COMMAND_HUNTER }); - } - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - // prevent charge drop (aura has both proc charge and stacks) - PreventDefaultAction(); - - if (Unit* owner = eventInfo.GetActor()->GetOwner()) - owner->RemoveAuraFromStack(SPELL_HUNTER_KILL_COMMAND_HUNTER); - - ModStackAmount(-1); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_hun_kill_command_pet::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -53228 - Rapid Recuperation (talent aura) -class spell_hun_rapid_recuperation_trigger : public AuraScript -{ - PrepareAuraScript(spell_hun_rapid_recuperation_trigger); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1, - SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 - }); - } - - void HandleRapidFireProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - // Proc only from Rapid Fire - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || !(spellInfo->SpellFamilyFlags[0] & 0x00000020)) - { - PreventDefaultAction(); - return; - } - } - - void HandleRapidKillingProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static uint32 const triggerSpells[2] = { SPELL_HUNTER_RAPID_RECUPERATION_MANA_R1, SPELL_HUNTER_RAPID_RECUPERATION_MANA_R2 }; - - PreventDefaultAction(); - - // Proc only from Rapid Killing - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || !(spellInfo->SpellFamilyFlags[1] & 0x01000000)) - return; - - uint8 rank = GetSpellInfo()->GetRank(); - uint32 spellId = triggerSpells[rank - 1]; - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_trigger::HandleRapidFireProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_trigger::HandleRapidKillingProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - -// -34497 - Thrill of the Hunt -class spell_hun_thrill_of_the_hunt : public AuraScript -{ - PrepareAuraScript(spell_hun_thrill_of_the_hunt); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - Unit* caster = eventInfo.GetActor(); - int32 amount = 0; - - // Explosive Shot - if (spellInfo->SpellFamilyFlags[2] & 0x200) - { - if (AuraEffect const* explosiveShot = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x00000000, 0x80000000, 0x00000000, caster->GetGUID())) - { - // due to Lock and Load SpellInfo::CalcPowerCost might return 0, so just calculate it manually - amount = CalculatePct(static_cast<int32>(CalculatePct(caster->GetCreateMana(), explosiveShot->GetSpellInfo()->ManaCostPercentage)), aurEff->GetAmount()); - - ASSERT(explosiveShot->GetSpellInfo()->GetMaxTicks() > 0); - amount /= explosiveShot->GetSpellInfo()->GetMaxTicks(); - } - } - else - amount = CalculatePct(static_cast<int32>(spellInfo->CalcPowerCost(caster, spellInfo->GetSchoolMask())), aurEff->GetAmount()); - - if (!amount) - return; - - caster->CastCustomSpell(SPELL_HUNTER_THRILL_OF_THE_HUNT_MANA, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_hun_thrill_of_the_hunt::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - void AddSC_hunter_spell_scripts() { RegisterSpellScript(spell_hun_check_pet_los); @@ -1579,20 +1329,13 @@ void AddSC_hunter_spell_scripts() RegisterSpellScript(spell_hun_misdirection_proc); RegisterSpellScript(spell_hun_pet_carrion_feeder); RegisterSpellScript(spell_hun_pet_heart_of_the_phoenix); - RegisterSpellScript(spell_hun_piercing_shots); RegisterSpellScript(spell_hun_readiness); RegisterSpellScript(spell_hun_scatter_shot); RegisterSpellScript(spell_hun_sniper_training); RegisterSpellScript(spell_hun_tame_beast); - RegisterSpellScript(spell_hun_t9_4p_bonus); RegisterSpellScript(spell_hun_viper_attack_speed); RegisterSpellScript(spell_hun_volley_trigger); RegisterSpellScript(spell_hun_lock_and_load); RegisterSpellScript(spell_hun_intimidation); RegisterSpellScript(spell_hun_bestial_wrath); - RegisterSpellScript(spell_hun_glyph_of_mend_pet); - RegisterSpellScript(spell_hun_hunting_party); - RegisterSpellScript(spell_hun_kill_command_pet); - RegisterSpellScript(spell_hun_rapid_recuperation_trigger); - RegisterSpellScript(spell_hun_thrill_of_the_hunt); } diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 769d96e77f..3476fb1e36 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -403,12 +403,12 @@ class spell_item_lil_phylactery : public AuraScript return eventInfo.GetActionTarget() && (eventInfo.GetActionTarget()->GetTypeId() != TYPEID_UNIT || eventInfo.GetActionTarget()->ToCreature()->isWorldBoss()); } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); if (Unit* critter = ObjectAccessor::GetUnit(*GetUnitOwner(), GetUnitOwner()->GetCritterGUID())) - GetUnitOwner()->CastSpell(critter, 69731 /*SPELL_LICH_PET_AURA_ON_KILL*/, true, nullptr, aurEff); + GetUnitOwner()->CastSpell(critter, 69731 /*SPELL_LICH_PET_AURA_ON_KILL*/, true); } void Register() override @@ -536,13 +536,13 @@ class spell_item_essence_of_life : public AuraScript }; const uint32 crazyAlchemistTable[5] = - { - 53909, // Wild Magic - 53908, // Potion of Speed - 53762, // Indestructible Potion - 43185, // Runic Healing Potion - 43186 // Runic Mana Potion - }; +{ + 53909, // Wild Magic + 53908, // Potion of Speed + 53762, // Indestructible Potion + 43185, // Runic Healing Potion + 43186 // Runic Mana Potion +}; class spell_item_crazy_alchemists_potion : public SpellScript { @@ -883,7 +883,7 @@ class spell_item_fetch_ball : public SpellScript if (Creature* creature = (*itr)->ToCreature()) { if (creature->GetOwnerGUID() == GetCaster()->GetOwnerGUID() && !creature->IsNonMeleeSpellCast(false) && - creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) + creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) { target = creature; break; @@ -923,11 +923,11 @@ class spell_item_oracle_ablutions : public SpellScript caster->CastSpell(caster, SPELL_ABLUTION_RUNIC, true); break; case POWER_MANA: - { - int32 mana = CalculatePct(caster->GetMaxPower(POWER_MANA), 5.0f); - caster->CastCustomSpell(SPELL_ABLUTION_MANA, SPELLVALUE_BASE_POINT0, mana, caster, true); - break; - } + { + int32 mana = CalculatePct(caster->GetMaxPower(POWER_MANA), 5.0f); + caster->CastCustomSpell(SPELL_ABLUTION_MANA, SPELLVALUE_BASE_POINT0, mana, caster, true); + break; + } case POWER_RAGE: caster->CastSpell(caster, SPELL_ABLUTION_RAGE, true); break; @@ -954,10 +954,10 @@ class spell_item_trauma : public AuraScript return eventInfo.GetActionTarget(); } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); - GetUnitOwner()->CastSpell(eventInfo.GetActionTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff); + GetUnitOwner()->CastSpell(eventInfo.GetActionTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true); } void Register() override @@ -971,7 +971,7 @@ class spell_item_blade_ward_enchant : public AuraScript { PrepareAuraScript(spell_item_blade_ward_enchant); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); if (!eventInfo.GetActionTarget()) @@ -982,7 +982,7 @@ class spell_item_blade_ward_enchant : public AuraScript if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(64442 /*SPELL_BLADE_WARDING*/)) { int32 basepoints = spellInfo->Effects[EFFECT_0].CalcValue() * this->GetStackAmount(); - eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActor(), true, nullptr, aurEff); + eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActor(), true); } } @@ -992,6 +992,37 @@ class spell_item_blade_ward_enchant : public AuraScript } }; +class spell_item_blood_draining_enchant : public AuraScript +{ + PrepareAuraScript(spell_item_blood_draining_enchant); + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (!eventInfo.GetActionTarget() || !eventInfo.GetDamageInfo() || (eventInfo.GetActionTarget()->GetHealth() - eventInfo.GetDamageInfo()->GetDamage()) >= eventInfo.GetActionTarget()->CountPctFromMaxHealth(35)) + { + return; + } + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(64569 /*SPELL_BLOOD_RESERVE*/)) + { + int32 basepoints = spellInfo->Effects[EFFECT_0].CalcValue() * this->GetStackAmount(); + eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActionTarget(), true); + eventInfo.GetActionTarget()->RemoveAurasDueToSpell(GetSpellInfo()->Id); // Remove rest auras + } + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(64569 /*SPELL_BLOOD_RESERVE*/); + int32 basepoints = spellInfo->Effects[EFFECT_0].CalcValue() * this->GetStackAmount(); + eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActionTarget(), true); + eventInfo.GetActionTarget()->RemoveAurasDueToSpell(GetSpellInfo()->Id); // Remove rest auras + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_item_blood_draining_enchant::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + class spell_item_dragon_kite_summon_lightning_bunny : public SpellScript { PrepareSpellScript(spell_item_dragon_kite_summon_lightning_bunny); @@ -1160,12 +1191,12 @@ class spell_item_eye_of_gruul_healing_discount : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_DRUID_ITEM_HEALING_TRANCE, - SPELL_PALADIN_ITEM_HEALING_TRANCE, - SPELL_PRIEST_ITEM_HEALING_TRANCE, - SPELL_SHAMAN_ITEM_HEALING_TRANCE - }); + { + SPELL_DRUID_ITEM_HEALING_TRANCE, + SPELL_PALADIN_ITEM_HEALING_TRANCE, + SPELL_PRIEST_ITEM_HEALING_TRANCE, + SPELL_SHAMAN_ITEM_HEALING_TRANCE + }); } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) @@ -1628,9 +1659,9 @@ class spell_item_fate_rune_of_unsurpassed_vigor : public AuraScript return ValidateSpellInfo({ SPELL_UNSURPASSED_VIGOR }); } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) { - GetTarget()->CastSpell(GetTarget(), SPELL_UNSURPASSED_VIGOR, true, nullptr, aurEff); + GetTarget()->CastSpell(GetTarget(), SPELL_UNSURPASSED_VIGOR, true); } void Register() override @@ -1752,13 +1783,13 @@ class spell_item_make_a_wish : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_MR_PINCHYS_BLESSING, - SPELL_SUMMON_MIGHTY_MR_PINCHY, - SPELL_SUMMON_FURIOUS_MR_PINCHY, - SPELL_TINY_MAGICAL_CRAWDAD, - SPELL_MR_PINCHYS_GIFT - }); + { + SPELL_MR_PINCHYS_BLESSING, + SPELL_SUMMON_MIGHTY_MR_PINCHY, + SPELL_SUMMON_FURIOUS_MR_PINCHY, + SPELL_TINY_MAGICAL_CRAWDAD, + SPELL_MR_PINCHYS_GIFT + }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -1814,12 +1845,12 @@ enum MingoFortune }; std::array<uint32, 20> const CreateFortuneSpells = - { - SPELL_CREATE_FORTUNE_1, SPELL_CREATE_FORTUNE_2, SPELL_CREATE_FORTUNE_3, SPELL_CREATE_FORTUNE_4, SPELL_CREATE_FORTUNE_5, - SPELL_CREATE_FORTUNE_6, SPELL_CREATE_FORTUNE_7, SPELL_CREATE_FORTUNE_8, SPELL_CREATE_FORTUNE_9, SPELL_CREATE_FORTUNE_10, - SPELL_CREATE_FORTUNE_11, SPELL_CREATE_FORTUNE_12, SPELL_CREATE_FORTUNE_13, SPELL_CREATE_FORTUNE_14, SPELL_CREATE_FORTUNE_15, - SPELL_CREATE_FORTUNE_16, SPELL_CREATE_FORTUNE_17, SPELL_CREATE_FORTUNE_18, SPELL_CREATE_FORTUNE_19, SPELL_CREATE_FORTUNE_20 - }; +{ + SPELL_CREATE_FORTUNE_1, SPELL_CREATE_FORTUNE_2, SPELL_CREATE_FORTUNE_3, SPELL_CREATE_FORTUNE_4, SPELL_CREATE_FORTUNE_5, + SPELL_CREATE_FORTUNE_6, SPELL_CREATE_FORTUNE_7, SPELL_CREATE_FORTUNE_8, SPELL_CREATE_FORTUNE_9, SPELL_CREATE_FORTUNE_10, + SPELL_CREATE_FORTUNE_11, SPELL_CREATE_FORTUNE_12, SPELL_CREATE_FORTUNE_13, SPELL_CREATE_FORTUNE_14, SPELL_CREATE_FORTUNE_15, + SPELL_CREATE_FORTUNE_16, SPELL_CREATE_FORTUNE_17, SPELL_CREATE_FORTUNE_18, SPELL_CREATE_FORTUNE_19, SPELL_CREATE_FORTUNE_20 +}; // 26465 - Mercurial Shield enum MercurialShield @@ -1922,11 +1953,11 @@ class spell_item_net_o_matic : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_NET_O_MATIC_TRIGGERED1, - SPELL_NET_O_MATIC_TRIGGERED2, - SPELL_NET_O_MATIC_TRIGGERED3 - }); + { + SPELL_NET_O_MATIC_TRIGGERED1, + SPELL_NET_O_MATIC_TRIGGERED2, + SPELL_NET_O_MATIC_TRIGGERED3 + }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -1971,11 +2002,11 @@ class spell_item_noggenfogger_elixir : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1, - SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2, - SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3 - }); + { + SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED1, + SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED2, + SPELL_NOGGENFOGGER_ELIXIR_TRIGGERED3 + }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -2056,7 +2087,7 @@ class spell_item_savory_deviate_delight : public SpellScript case 1: spellId = (caster->getGender() == GENDER_MALE ? SPELL_FLIP_OUT_MALE : SPELL_FLIP_OUT_FEMALE); break; - // Yaaarrrr - pirate + // Yaaarrrr - pirate case 2: spellId = (caster->getGender() == GENDER_MALE ? SPELL_YAAARRRR_MALE : SPELL_YAAARRRR_FEMALE); break; @@ -2247,7 +2278,7 @@ class spell_item_unsated_craving : public AuraScript void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, TRIGGERED_FULL_MASK, nullptr, aurEff); + eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, TRIGGERED_FULL_MASK); } void Register() override @@ -2261,7 +2292,7 @@ class spell_item_shadows_fate : public AuraScript { PrepareAuraScript(spell_item_shadows_fate); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) { PreventDefaultAction(); @@ -2270,7 +2301,7 @@ class spell_item_shadows_fate : public AuraScript if (!caster || !target) return; - caster->CastSpell(target, SPELL_SOUL_FEAST, TRIGGERED_FULL_MASK, nullptr, aurEff); + caster->CastSpell(target, SPELL_SOUL_FEAST, TRIGGERED_FULL_MASK); } void Register() override @@ -2297,11 +2328,11 @@ class spell_item_shadowmourne : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, - SPELL_SHADOWMOURNE_SOUL_FRAGMENT, - SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF - }); + { + SPELL_SHADOWMOURNE_CHAOS_BANE_DAMAGE, + SPELL_SHADOWMOURNE_SOUL_FRAGMENT, + SPELL_SHADOWMOURNE_CHAOS_BANE_BUFF + }); } bool CheckProc(ProcEventInfo& eventInfo) @@ -2423,14 +2454,14 @@ class spell_item_six_demon_bag : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_FROSTBOLT, - SPELL_POLYMORPH, - SPELL_SUMMON_FELHOUND_MINION, - SPELL_FIREBALL, - SPELL_CHAIN_LIGHTNING, - SPELL_ENVELOPING_WINDS - }); + { + SPELL_FROSTBOLT, + SPELL_POLYMORPH, + SPELL_SUMMON_FELHOUND_MINION, + SPELL_FIREBALL, + SPELL_CHAIN_LIGHTNING, + SPELL_ENVELOPING_WINDS + }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -2509,11 +2540,11 @@ class spell_item_underbelly_elixir : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_UNDERBELLY_ELIXIR_TRIGGERED1, - SPELL_UNDERBELLY_ELIXIR_TRIGGERED2, - SPELL_UNDERBELLY_ELIXIR_TRIGGERED3 - }); + { + SPELL_UNDERBELLY_ELIXIR_TRIGGERED1, + SPELL_UNDERBELLY_ELIXIR_TRIGGERED2, + SPELL_UNDERBELLY_ELIXIR_TRIGGERED3 + }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -2598,8 +2629,8 @@ class spell_item_map_of_the_geyser_fields : public SpellScript { Unit* caster = GetCaster(); if (caster->FindNearestCreature(NPC_SOUTH_SINKHOLE, 30.0f, true) || - caster->FindNearestCreature(NPC_NORTHEAST_SINKHOLE, 30.0f, true) || - caster->FindNearestCreature(NPC_NORTHWEST_SINKHOLE, 30.0f, true)) + caster->FindNearestCreature(NPC_NORTHEAST_SINKHOLE, 30.0f, true) || + caster->FindNearestCreature(NPC_NORTHWEST_SINKHOLE, 30.0f, true)) return SPELL_CAST_OK; SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_BE_CLOSE_TO_SINKHOLE); @@ -2626,11 +2657,11 @@ class spell_item_vanquished_clutches : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo( - { - SPELL_CRUSHER, - SPELL_CONSTRICTOR, - SPELL_CORRUPTOR - }); + { + SPELL_CRUSHER, + SPELL_CONSTRICTOR, + SPELL_CORRUPTOR + }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -2835,13 +2866,13 @@ class spell_item_reindeer_transformation : public SpellScript bool Validate(SpellInfo const* /*spell*/) override { return ValidateSpellInfo( - { - SPELL_FLYING_REINDEER_310, - SPELL_FLYING_REINDEER_280, - SPELL_FLYING_REINDEER_60, - SPELL_REINDEER_100, - SPELL_REINDEER_60 - }); + { + SPELL_FLYING_REINDEER_310, + SPELL_FLYING_REINDEER_280, + SPELL_FLYING_REINDEER_60, + SPELL_REINDEER_100, + SPELL_REINDEER_60 + }); } void HandleDummy(SpellEffIndex /* effIndex */) @@ -3111,12 +3142,12 @@ class spell_item_brewfest_mount_transformation : public SpellScript bool Validate(SpellInfo const* /*spell*/) override { return ValidateSpellInfo( - { - SPELL_MOUNT_RAM_100, - SPELL_MOUNT_RAM_60, - SPELL_MOUNT_KODO_100, - SPELL_MOUNT_KODO_60 - }); + { + SPELL_MOUNT_RAM_100, + SPELL_MOUNT_RAM_60, + SPELL_MOUNT_KODO_100, + SPELL_MOUNT_KODO_60 + }); } void HandleDummy(SpellEffIndex /* effIndex */) @@ -3135,20 +3166,20 @@ class spell_item_brewfest_mount_transformation : public SpellScript switch (GetSpellInfo()->Id) { - case SPELL_BREWFEST_MOUNT_TRANSFORM: - if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) - spell_id = caster->GetTeamId() == TEAM_ALLIANCE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; - else - spell_id = caster->GetTeamId() == TEAM_ALLIANCE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; - break; - case SPELL_BREWFEST_MOUNT_TRANSFORM_REVERSE: - if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) - spell_id = caster->GetTeamId() == TEAM_HORDE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; - else - spell_id = caster->GetTeamId() == TEAM_HORDE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; - break; - default: - return; + case SPELL_BREWFEST_MOUNT_TRANSFORM: + if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) + spell_id = caster->GetTeamId() == TEAM_ALLIANCE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; + else + spell_id = caster->GetTeamId() == TEAM_ALLIANCE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; + break; + case SPELL_BREWFEST_MOUNT_TRANSFORM_REVERSE: + if (caster->GetSpeedRate(MOVE_RUN) >= 2.0f) + spell_id = caster->GetTeamId() == TEAM_HORDE ? SPELL_MOUNT_RAM_100 : SPELL_MOUNT_KODO_100; + else + spell_id = caster->GetTeamId() == TEAM_HORDE ? SPELL_MOUNT_RAM_60 : SPELL_MOUNT_KODO_60; + break; + default: + return; } caster->CastSpell(caster, spell_id, true); } @@ -3658,1323 +3689,6 @@ class spell_item_mirrens_drinking_hat : public SpellScript } }; -enum SoulPreserver -{ - SPELL_SOUL_PRESERVER_DRUID = 60512, - SPELL_SOUL_PRESERVER_PALADIN = 60513, - SPELL_SOUL_PRESERVER_PRIEST = 60514, - SPELL_SOUL_PRESERVER_SHAMAN = 60515, -}; - -class spell_item_soul_preserver : public AuraScript -{ - PrepareAuraScript(spell_item_soul_preserver); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SOUL_PRESERVER_DRUID, SPELL_SOUL_PRESERVER_PALADIN, SPELL_SOUL_PRESERVER_PRIEST, SPELL_SOUL_PRESERVER_SHAMAN }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - - switch (caster->getClass()) - { - case CLASS_DRUID: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_DRUID, true, nullptr, aurEff); - break; - case CLASS_PALADIN: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PALADIN, true, nullptr, aurEff); - break; - case CLASS_PRIEST: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_PRIEST, true, nullptr, aurEff); - break; - case CLASS_SHAMAN: - caster->CastSpell(caster, SPELL_SOUL_PRESERVER_SHAMAN, true, nullptr, aurEff); - break; - default: - break; - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_soul_preserver::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum DeathChoiceSpells -{ - SPELL_DEATH_CHOICE_NORMAL_AURA = 67702, - SPELL_DEATH_CHOICE_NORMAL_AGILITY = 67703, - SPELL_DEATH_CHOICE_NORMAL_STRENGTH = 67708, - SPELL_DEATH_CHOICE_HEROIC_AURA = 67771, - SPELL_DEATH_CHOICE_HEROIC_AGILITY = 67772, - SPELL_DEATH_CHOICE_HEROIC_STRENGTH = 67773 -}; - -class spell_item_death_choice : public AuraScript -{ - PrepareAuraScript(spell_item_death_choice); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEATH_CHOICE_NORMAL_STRENGTH, SPELL_DEATH_CHOICE_NORMAL_AGILITY, SPELL_DEATH_CHOICE_HEROIC_STRENGTH, SPELL_DEATH_CHOICE_HEROIC_AGILITY }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - float str = caster->GetStat(STAT_STRENGTH); - float agi = caster->GetStat(STAT_AGILITY); - - switch (aurEff->GetId()) - { - case SPELL_DEATH_CHOICE_NORMAL_AURA: - { - if (str > agi) - { - caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_STRENGTH, true, nullptr, aurEff); - } - else - { - caster->CastSpell(caster, SPELL_DEATH_CHOICE_NORMAL_AGILITY, true, nullptr, aurEff); - } - break; - } - case SPELL_DEATH_CHOICE_HEROIC_AURA: - { - if (str > agi) - { - caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_STRENGTH, true, nullptr, aurEff); - } - else - { - caster->CastSpell(caster, SPELL_DEATH_CHOICE_HEROIC_AGILITY, true, nullptr, aurEff); - } - break; - } - default: - break; - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_death_choice::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum TrinketStackSpells -{ - SPELL_LIGHTNING_CAPACITOR_AURA = 37657, // Lightning Capacitor - SPELL_LIGHTNING_CAPACITOR_STACK = 37658, - SPELL_LIGHTNING_CAPACITOR_TRIGGER = 37661, - SPELL_THUNDER_CAPACITOR_AURA = 54841, // Thunder Capacitor - SPELL_THUNDER_CAPACITOR_STACK = 54842, - SPELL_THUNDER_CAPACITOR_TRIGGER = 54843, - SPELL_TOC25_CASTER_TRINKET_NORMAL_AURA = 67712, // Item - Coliseum 25 Normal Caster Trinket - SPELL_TOC25_CASTER_TRINKET_NORMAL_STACK = 67713, - SPELL_TOC25_CASTER_TRINKET_NORMAL_TRIGGER = 67714, - SPELL_TOC25_CASTER_TRINKET_HEROIC_AURA = 67758, // Item - Coliseum 25 Heroic Caster Trinket - SPELL_TOC25_CASTER_TRINKET_HEROIC_STACK = 67759, - SPELL_TOC25_CASTER_TRINKET_HEROIC_TRIGGER = 67760, -}; - -class spell_item_trinket_stack : public SpellScriptLoader -{ -public: - spell_item_trinket_stack(char const* scriptName, uint32 stackSpell, uint32 triggerSpell) : SpellScriptLoader(scriptName), - _stackSpell(stackSpell), _triggerSpell(triggerSpell) - { - } - - class spell_item_trinket_stack_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_trinket_stack_AuraScript); - - public: - spell_item_trinket_stack_AuraScript(uint32 stackSpell, uint32 triggerSpell) : _stackSpell(stackSpell), _triggerSpell(triggerSpell) - { - } - - private: - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ _stackSpell, _triggerSpell }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - - caster->CastSpell(caster, _stackSpell, true, nullptr, aurEff); // cast the stack - - Aura* dummy = caster->GetAura(_stackSpell); // retrieve aura - - //dont do anything if it's not the right amount of stacks; - if (!dummy || dummy->GetStackAmount() < aurEff->GetAmount()) - return; - - // if right amount, remove the aura and cast real trigger - caster->RemoveAurasDueToSpell(_stackSpell); - if (Unit* target = eventInfo.GetActionTarget()) - { - caster->CastSpell(target, _triggerSpell, true, nullptr, aurEff); - } - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAurasDueToSpell(_stackSpell); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_trinket_stack_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - AfterEffectRemove += AuraEffectRemoveFn(spell_item_trinket_stack_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); - } - - private: - uint32 _stackSpell; - uint32 _triggerSpell; - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_trinket_stack_AuraScript(_stackSpell, _triggerSpell); - } - -private: - uint32 _stackSpell; - uint32 _triggerSpell; -}; - -// 57345 - Darkmoon Card: Greatness -enum DarkmoonCardSpells -{ - SPELL_DARKMOON_CARD_STRENGHT = 60229, - SPELL_DARKMOON_CARD_AGILITY = 60233, - SPELL_DARKMOON_CARD_INTELLECT = 60234, - SPELL_DARKMOON_CARD_SPIRIT = 60235, -}; - -class spell_item_darkmoon_card_greatness : public AuraScript -{ - PrepareAuraScript(spell_item_darkmoon_card_greatness); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DARKMOON_CARD_AGILITY, SPELL_DARKMOON_CARD_STRENGHT, SPELL_DARKMOON_CARD_INTELLECT, SPELL_DARKMOON_CARD_SPIRIT }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - float str = caster->GetStat(STAT_STRENGTH); - float agi = caster->GetStat(STAT_AGILITY); - float intl = caster->GetStat(STAT_INTELLECT); - float spi = caster->GetStat(STAT_SPIRIT); - float stat = 0.0f; - - uint32 spellTrigger = SPELL_DARKMOON_CARD_STRENGHT; - - if (str > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_STRENGHT; - stat = str; - } - - if (agi > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_AGILITY; - stat = agi; - } - - if (intl > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_INTELLECT; - stat = intl; - } - - if (spi > stat) - { - spellTrigger = SPELL_DARKMOON_CARD_SPIRIT; - stat = spi; - } - - caster->CastSpell(caster, spellTrigger, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_darkmoon_card_greatness::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 43820 - Amani Charm of the Witch Doctor -enum CharmWitchDoctor -{ - SPELL_CHARM_WITCH_DOCTOR_PROC = 43821 -}; - -class spell_item_charm_witch_doctor : public AuraScript -{ - PrepareAuraScript(spell_item_charm_witch_doctor); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CHARM_WITCH_DOCTOR_PROC }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetActionTarget(); - - if (target) - { - int32 bp = CalculatePct(target->GetCreateHealth(), aurEff->GetSpellInfo()->Effects[1].CalcValue()); - caster->CastCustomSpell(target, SPELL_CHARM_WITCH_DOCTOR_PROC, &bp, nullptr, nullptr, true, nullptr, aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_charm_witch_doctor::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum ManaDrainSpells -{ - SPELL_MANA_DRAIN_ENERGIZE = 29471, - SPELL_MANA_DRAIN_LEECH = 27526 -}; - -// 27522, 40336 - Mana Drain -class spell_item_mana_drain : public AuraScript -{ - PrepareAuraScript(spell_item_mana_drain); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MANA_DRAIN_ENERGIZE, SPELL_MANA_DRAIN_LEECH }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetActionTarget(); - - if (caster->IsAlive()) - { - caster->CastSpell(caster, SPELL_MANA_DRAIN_ENERGIZE, true, nullptr, aurEff); - } - - if (target && target->IsAlive()) - { - caster->CastSpell(target, SPELL_MANA_DRAIN_LEECH, true, nullptr, aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_mana_drain::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// Item - 12846: Argent Dawn Commission -// Item - 13209: Seal of the Dawn -// Item - 19812: Rune of the Dawn - -enum AlchemistStone -{ - SPELL_ALCHEMISTS_STONE_EXTRA_HEAL = 21399, - SPELL_ALCHEMISTS_STONE_EXTRA_MANA = 21400 -}; - -// Item - 13503: Alchemist's Stone -// Item - 35748: Guardian's Alchemist Stone -// Item - 35749: Sorcerer's Alchemist Stone -// Item - 35750: Redeemer's Alchemist Stone -// Item - 35751: Assassin's Alchemist Stone -// Item - 44322: Mercurial Alchemist Stone -// Item - 44323: Indestructible Alchemist's Stone -// Item - 44324: Mighty Alchemist's Stone - -// 17619 - Alchemist's Stone -class spell_item_alchemists_stone : public AuraScript -{ - PrepareAuraScript(spell_item_alchemists_stone); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_ALCHEMISTS_STONE_EXTRA_HEAL, - SPELL_ALCHEMISTS_STONE_EXTRA_MANA - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - Unit* caster = eventInfo.GetActionTarget(); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - uint32 spellId; - switch (spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_HEAL: - spellId = SPELL_ALCHEMISTS_STONE_EXTRA_HEAL; - break; - case SPELL_EFFECT_ENERGIZE: - spellId = SPELL_ALCHEMISTS_STONE_EXTRA_MANA; - break; - default: - continue; - } - - int32 amount = CalculatePct(spellInfo->Effects[i].CalcValue(caster), 40); - caster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_alchemists_stone::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -enum AngerCapacitor -{ - SPELL_MOTE_OF_ANGER = 71432, - SPELL_MANIFEST_ANGER_MAIN_HAND = 71433, - SPELL_MANIFEST_ANGER_OFF_HAND = 71434 -}; - -// Item - 50351: Tiny Abomination in a Jar -// 71406 - Anger Capacitor - -// Item - 50706: Tiny Abomination in a Jar (Heroic) -// 71545 - Anger Capacitor -template <uint8 StackAmount> -class spell_item_anger_capacitor : public SpellScriptLoader -{ -public: - spell_item_anger_capacitor(char const* ScriptName) : SpellScriptLoader(ScriptName) { } - - template <uint8 Stacks> - class spell_item_anger_capacitor_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_anger_capacitor_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MOTE_OF_ANGER, - SPELL_MANIFEST_ANGER_MAIN_HAND, - SPELL_MANIFEST_ANGER_OFF_HAND - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - - caster->CastSpell((Unit*)nullptr, SPELL_MOTE_OF_ANGER, true); - Aura const* motes = caster->GetAura(SPELL_MOTE_OF_ANGER); - if (!motes || motes->GetStackAmount() < Stacks) - return; - - caster->RemoveAurasDueToSpell(SPELL_MOTE_OF_ANGER); - uint32 spellId = SPELL_MANIFEST_ANGER_MAIN_HAND; - if (Player* player = caster->ToPlayer()) - if (player->GetWeaponForAttack(OFF_ATTACK, true) && urand(0, 1)) - spellId = SPELL_MANIFEST_ANGER_OFF_HAND; - - caster->CastSpell(target, spellId, true, nullptr, aurEff); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAurasDueToSpell(SPELL_MOTE_OF_ANGER); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_anger_capacitor_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - AfterEffectRemove += AuraEffectRemoveFn(spell_item_anger_capacitor_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_anger_capacitor_AuraScript<StackAmount>(); - } -}; - -enum AuraOfMadness -{ - SPELL_SOCIOPATH = 39511, // Sociopath: +35 strength(Paladin, Rogue, Druid, Warrior) - SPELL_DELUSIONAL = 40997, // Delusional: +70 attack power(Rogue, Hunter, Paladin, Warrior, Druid) - SPELL_KLEPTOMANIA = 40998, // Kleptomania: +35 agility(Warrior, Rogue, Paladin, Hunter, Druid) - SPELL_MEGALOMANIA = 40999, // Megalomania: +41 damage / healing(Druid, Shaman, Priest, Warlock, Mage, Paladin) - SPELL_PARANOIA = 41002, // Paranoia: +35 spell / melee / ranged crit strike rating(All classes) - SPELL_MANIC = 41005, // Manic: +35 haste(spell, melee and ranged) (All classes) - SPELL_NARCISSISM = 41009, // Narcissism: +35 intellect(Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter) - SPELL_MARTYR_COMPLEX = 41011, // Martyr Complex: +35 stamina(All classes) - SPELL_DEMENTIA = 41404, // Dementia: Every 5 seconds either gives you +5/-5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) - - SPELL_DEMENTIA_POS = 41406, - SPELL_DEMENTIA_NEG = 41409, - - SAY_MADNESS = 21954 -}; - -// Item - 31859: Darkmoon Card: Madness -// 39446 - Aura of Madness -class spell_item_aura_of_madness : public AuraScript -{ - PrepareAuraScript(spell_item_aura_of_madness); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SOCIOPATH, - SPELL_DELUSIONAL, - SPELL_KLEPTOMANIA, - SPELL_MEGALOMANIA, - SPELL_PARANOIA, - SPELL_MANIC, - SPELL_NARCISSISM, - SPELL_MARTYR_COMPLEX, - SPELL_DEMENTIA - }) && sObjectMgr->GetBroadcastText(SAY_MADNESS); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static std::vector<uint32> const triggeredSpells[MAX_CLASSES] = - { - //CLASS_NONE - { }, - //CLASS_WARRIOR - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, - //CLASS_PALADIN - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_HUNTER - { SPELL_DELUSIONAL, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_ROGUE - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, - //CLASS_PRIEST - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_DEATH_KNIGHT - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_MARTYR_COMPLEX }, - //CLASS_SHAMAN - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_MAGE - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_WARLOCK - { SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA }, - //CLASS_UNK - { }, - //CLASS_DRUID - { SPELL_SOCIOPATH, SPELL_DELUSIONAL, SPELL_KLEPTOMANIA, SPELL_MEGALOMANIA, SPELL_PARANOIA, SPELL_MANIC, SPELL_NARCISSISM, SPELL_MARTYR_COMPLEX, SPELL_DEMENTIA } - }; - - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - uint32 spellId = Acore::Containers::SelectRandomContainerElement(triggeredSpells[caster->getClass()]); - caster->CastSpell(caster, spellId, true, nullptr, aurEff); - - if (roll_chance_i(10)) - caster->Unit::Say(SAY_MADNESS); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_aura_of_madness::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 41404 - Dementia -class spell_item_dementia : public AuraScript -{ - PrepareAuraScript(spell_item_dementia); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_DEMENTIA_POS, - SPELL_DEMENTIA_NEG - }); - } - - void HandlePeriodicDummy(AuraEffect const* aurEff) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), RAND(SPELL_DEMENTIA_POS, SPELL_DEMENTIA_NEG), aurEff); - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_item_dementia::HandlePeriodicDummy, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); - } -}; - -enum DeadlyPrecision -{ - SPELL_DEADLY_PRECISION = 71564 -}; - -// 71564 - Deadly Precision -class spell_item_deadly_precision : public AuraScript -{ - PrepareAuraScript(spell_item_deadly_precision); - - void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->RemoveAuraFromStack(GetId(), GetTarget()->GetGUID()); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_deadly_precision::HandleStackDrop, EFFECT_0, SPELL_AURA_MOD_RATING); - } -}; - -// 71563 - Deadly Precision Dummy -class spell_item_deadly_precision_dummy : public SpellScript -{ - PrepareSpellScript(spell_item_deadly_precision_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEADLY_PRECISION }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_DEADLY_PRECISION); - GetCaster()->CastCustomSpell(spellInfo->Id, SPELLVALUE_AURA_STACK, spellInfo->StackAmount, GetCaster(), true); - } - - void Register() override - { - OnEffectHit += SpellEffectFn(spell_item_deadly_precision_dummy::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } -}; - -enum DeathbringersWill -{ - SPELL_STRENGTH_OF_THE_TAUNKA = 71484, // +600 Strength - SPELL_AGILITY_OF_THE_VRYKUL = 71485, // +600 Agility - SPELL_POWER_OF_THE_TAUNKA = 71486, // +1200 Attack Power - SPELL_AIM_OF_THE_IRON_DWARVES = 71491, // +600 Critical - SPELL_SPEED_OF_THE_VRYKUL = 71492, // +600 Haste - - SPELL_AGILITY_OF_THE_VRYKUL_HERO = 71556, // +700 Agility - SPELL_POWER_OF_THE_TAUNKA_HERO = 71558, // +1400 Attack Power - SPELL_AIM_OF_THE_IRON_DWARVES_HERO = 71559, // +700 Critical - SPELL_SPEED_OF_THE_VRYKUL_HERO = 71560, // +700 Haste - SPELL_STRENGTH_OF_THE_TAUNKA_HERO = 71561 // +700 Strength -}; - -// Item - 50362: Deathbringer's Will -// 71519 - Item - Icecrown 25 Normal Melee Trinket - -// Item - 50363: Deathbringer's Will -// 71562 - Item - Icecrown 25 Heroic Melee Trinket -template <uint32 StrengthSpellId, uint32 AgilitySpellId, uint32 APSpellId, uint32 CriticalSpellId, uint32 HasteSpellId> -class spell_item_deathbringers_will : public SpellScriptLoader -{ -public: - spell_item_deathbringers_will(char const* ScriptName) : SpellScriptLoader(ScriptName) { } - - template <uint32 Strength, uint32 Agility, uint32 AttackPower, uint32 Critical, uint32 Haste> - class spell_item_deathbringers_will_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_deathbringers_will_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - Strength, - Agility, - AttackPower, - Critical, - Haste - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static std::vector<uint32> const triggeredSpells[MAX_CLASSES] = - { - //CLASS_NONE - { }, - //CLASS_WARRIOR - { Strength, Critical, Haste }, - //CLASS_PALADIN - { Strength, Critical, Haste }, - //CLASS_HUNTER - { Agility, Critical, AttackPower }, - //CLASS_ROGUE - { Agility, Haste, AttackPower }, - //CLASS_PRIEST - { }, - //CLASS_DEATH_KNIGHT - { Strength, Critical, Haste }, - //CLASS_SHAMAN - { Agility, Haste, AttackPower }, - //CLASS_MAGE - { }, - //CLASS_WARLOCK - { }, - //CLASS_UNK - { }, - //CLASS_DRUID - { Strength, Agility, Haste } - }; - - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - std::vector<uint32> const& randomSpells = triggeredSpells[caster->getClass()]; - if (randomSpells.empty()) - return; - - uint32 spellId = Acore::Containers::SelectRandomContainerElement(randomSpells); - caster->CastSpell(caster, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_deathbringers_will_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_deathbringers_will_AuraScript<StrengthSpellId, AgilitySpellId, APSpellId, CriticalSpellId, HasteSpellId>(); - } -}; - -enum DiscerningEyeBeastMisc -{ - SPELL_DISCERNING_EYE_BEAST = 59914 -}; - -// 59915 - Discerning Eye of the Beast Dummy -class spell_item_discerning_eye_beast_dummy : public AuraScript -{ - PrepareAuraScript(spell_item_discerning_eye_beast_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DISCERNING_EYE_BEAST }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_DISCERNING_EYE_BEAST, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_discerning_eye_beast_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -enum FrozenShadoweave -{ - SPELL_SHADOWMEND = 39373 -}; - -// 39372 - Frozen Shadoweave -// Frozen Shadoweave set 3p bonus -class spell_item_frozen_shadoweave : public AuraScript -{ - PrepareAuraScript(spell_item_frozen_shadoweave); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHADOWMEND }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - Unit* caster = eventInfo.GetActor(); - caster->CastCustomSpell(SPELL_SHADOWMEND, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_frozen_shadoweave::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// Item 23004 - Idol of Longevity -// 28847 - Healing Touch Refund -enum IdolOfLongevity -{ - SPELL_HEALING_TOUCH_MANA = 28848 -}; - -class spell_item_healing_touch_refund : public AuraScript -{ - PrepareAuraScript(spell_item_healing_touch_refund); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HEALING_TOUCH_MANA }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_HEALING_TOUCH_MANA, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_healing_touch_refund::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -enum Heartpierce -{ - SPELL_INVIGORATION_MANA = 71881, - SPELL_INVIGORATION_ENERGY = 71882, - SPELL_INVIGORATION_RAGE = 71883, - SPELL_INVIGORATION_RP = 71884, - - SPELL_INVIGORATION_RP_HERO = 71885, - SPELL_INVIGORATION_RAGE_HERO = 71886, - SPELL_INVIGORATION_ENERGY_HERO = 71887, - SPELL_INVIGORATION_MANA_HERO = 71888 -}; - -// Item - 49982: Heartpierce -// 71880 - Item - Icecrown 25 Normal Dagger Proc - -// Item - 50641: Heartpierce (Heroic) -// 71892 - Item - Icecrown 25 Heroic Dagger Proc -template <uint32 EnergySpellId, uint32 ManaSpellId, uint32 RageSpellId, uint32 RPSpellId> -class spell_item_heartpierce : public SpellScriptLoader -{ -public: - spell_item_heartpierce(char const* ScriptName) : SpellScriptLoader(ScriptName) { } - - template <uint32 Energy, uint32 Mana, uint32 Rage, uint32 RunicPower> - class spell_item_heartpierce_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_heartpierce_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - Energy, - Mana, - Rage, - RunicPower - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - - uint32 spellId; - switch (caster->getPowerType()) - { - case POWER_MANA: - spellId = Mana; - break; - case POWER_ENERGY: - spellId = Energy; - break; - case POWER_RAGE: - spellId = Rage; - break; - // Death Knights can't use daggers, but oh well - case POWER_RUNIC_POWER: - spellId = RunicPower; - break; - default: - return; - } - - caster->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_heartpierce_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_heartpierce_AuraScript<EnergySpellId, ManaSpellId, RageSpellId, RPSpellId>(); - } -}; - -// 40971 - Bonus Healing (Crystal Spire of Karabor) -class spell_item_crystal_spire_of_karabor : public AuraScript -{ - PrepareAuraScript(spell_item_crystal_spire_of_karabor); - - bool CheckProc(ProcEventInfo& eventInfo) - { - int32 pct = GetSpellInfo()->Effects[EFFECT_0].BasePoints; - if (HealInfo* healInfo = eventInfo.GetHealInfo()) - if (Unit* healTarget = healInfo->GetTarget()) - if (healTarget->GetHealth() - healInfo->GetEffectiveHeal() <= healTarget->CountPctFromMaxHealth(pct)) - return true; - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_crystal_spire_of_karabor::CheckProc); - } -}; - -enum MarkOfConquest -{ - SPELL_MARK_OF_CONQUEST_ENERGIZE = 39599 -}; - -// Item - 27920: Mark of Conquest -// Item - 27921: Mark of Conquest -// 33510 - Health Restore -class spell_item_mark_of_conquest : public AuraScript -{ - PrepareAuraScript(spell_item_mark_of_conquest); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MARK_OF_CONQUEST_ENERGIZE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - if (eventInfo.GetTypeMask() & (PROC_FLAG_DONE_RANGED_AUTO_ATTACK | PROC_FLAG_DONE_SPELL_RANGED_DMG_CLASS)) - { - // in that case, do not cast heal spell - PreventDefaultAction(); - // but mana instead - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_MARK_OF_CONQUEST_ENERGIZE, true, nullptr, aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_mark_of_conquest::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum PersistentShieldMisc -{ - SPELL_PERSISTENT_SHIELD_TRIGGERED = 26470 -}; - -// 26467 - Persistent Shield -class spell_item_persistent_shield : public AuraScript -{ - PrepareAuraScript(spell_item_persistent_shield); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PERSISTENT_SHIELD_TRIGGERED }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetHeal(); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - int32 bp0 = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 15); - - // Scarab Brooch does not replace stronger shields - if (AuraEffect const* shield = target->GetAuraEffect(SPELL_PERSISTENT_SHIELD_TRIGGERED, EFFECT_0, caster->GetGUID())) - if (shield->GetAmount() > bp0) - return; - - caster->CastCustomSpell(SPELL_PERSISTENT_SHIELD_TRIGGERED, SPELLVALUE_BASE_POINT0, bp0, target, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_persistent_shield::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_persistent_shield::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -enum PetHealing -{ - SPELL_HEALTH_LINK = 37382 -}; - -// 37381 - Pet Healing -// Hunter T5 2P Bonus -// Warlock T5 2P Bonus -class spell_item_pet_healing : public AuraScript -{ - PrepareAuraScript(spell_item_pet_healing); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_HEALTH_LINK }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 bp = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - Unit* caster = eventInfo.GetActor(); - caster->CastCustomSpell(SPELL_HEALTH_LINK, SPELLVALUE_BASE_POINT0, bp, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_pet_healing::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -enum SwiftHandJusticeMisc -{ - SPELL_SWIFT_HAND_OF_JUSTICE_HEAL = 59913 -}; - -// 59906 - Swift Hand of Justice Dummy -class spell_item_swift_hand_justice_dummy : public AuraScript -{ - PrepareAuraScript(spell_item_swift_hand_justice_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SWIFT_HAND_OF_JUSTICE_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - int32 amount = caster->CountPctFromMaxHealth(aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_SWIFT_HAND_OF_JUSTICE_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_swift_hand_justice_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -enum TotemOfFlowingWater -{ - SPELL_LESSER_HEALING_WAVE_MANA = 28850 -}; - -// Item - 23005: Totem of Flowing Water -// 28849 - Lesser Healing Wave -class spell_item_totem_of_flowing_water : public AuraScript -{ - PrepareAuraScript(spell_item_totem_of_flowing_water); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_LESSER_HEALING_WAVE_MANA }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_LESSER_HEALING_WAVE_MANA, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_totem_of_flowing_water::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -enum ShardOfTheScale -{ - SPELL_PURIFIED_CAUTERIZING_HEAL = 69733, - SPELL_PURIFIED_SEARING_FLAMES = 69729, - - SPELL_SHINY_CAUTERIZING_HEAL = 69734, - SPELL_SHINY_SEARING_FLAMES = 69730 -}; - -// Item - 49310: Purified Shard of the Scale -// 69755 - Purified Shard of the Scale - Equip Effect - -// Item - 49488: Shiny Shard of the Scale -// 69739 - Shiny Shard of the Scale - Equip Effect -template <uint32 HealProcSpellId, uint32 DamageProcSpellId> -class spell_item_shard_of_the_scale : public SpellScriptLoader -{ -public: - spell_item_shard_of_the_scale(char const* ScriptName) : SpellScriptLoader(ScriptName) { } - - template <uint32 HealProc, uint32 DamageProc> - class spell_item_shard_of_the_scale_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_shard_of_the_scale_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - HealProc, - DamageProc - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - - if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS) - caster->CastSpell(target, HealProc, true, nullptr, aurEff); - - if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG) - caster->CastSpell(target, DamageProc, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_shard_of_the_scale_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_shard_of_the_scale_AuraScript<HealProcSpellId, DamageProcSpellId>(); - } -}; - -enum ExaltedSunwellNeck -{ - SPELL_LIGHTS_WRATH = 45479, // Light's Wrath if Exalted by Aldor - SPELL_ARCANE_BOLT = 45429, // Arcane Bolt if Exalted by Scryers - - SPELL_LIGHTS_STRENGTH = 45480, // Light's Strength if Exalted by Aldor - SPELL_ARCANE_STRIKE = 45428, // Arcane Strike if Exalted by Scryers - - SPELL_LIGHTS_WARD = 45432, // Light's Ward if Exalted by Aldor - SPELL_ARCANE_INSIGHT = 45431, // Arcane Insight if Exalted by Scryers - - SPELL_LIGHTS_SALVATION = 45478, // Light's Salvation if Exalted by Aldor - SPELL_ARCANE_SURGE = 45430, // Arcane Surge if Exalted by Scryers - - FACTION_ALDOR = 932, - FACTION_SCRYERS = 934 -}; - -// Item - 34678: Shattered Sun Pendant of Acumen -// 45481 - Sunwell Exalted Caster Neck - -// Item - 34679: Shattered Sun Pendant of Might -// 45482 - Sunwell Exalted Melee Neck - -// Item - 34680: Shattered Sun Pendant of Resolve -// 45483 - Sunwell Exalted Tank Neck - -// Item - 34677: Shattered Sun Pendant of Restoration -// 45484 Sunwell Exalted Healer Neck -template <uint32 AldorSpellId, uint32 ScryersSpellId> -class spell_item_sunwell_neck : public SpellScriptLoader -{ -public: - spell_item_sunwell_neck(char const* ScriptName) : SpellScriptLoader(ScriptName) { } - - template <uint32 Aldors, uint32 Scryers> - class spell_item_sunwell_neck_AuraScript : public AuraScript - { - PrepareAuraScript(spell_item_sunwell_neck_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ Aldors, Scryers }) && - sFactionStore.LookupEntry(FACTION_ALDOR) && - sFactionStore.LookupEntry(FACTION_SCRYERS); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetActor()->GetTypeId() != TYPEID_PLAYER) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Player* player = eventInfo.GetActor()->ToPlayer(); - Unit* target = eventInfo.GetProcTarget(); - - // Aggression checks are in the spell system... just cast and forget - if (player->GetReputationRank(FACTION_ALDOR) == REP_EXALTED) - player->CastSpell(target, Aldors, true, nullptr, aurEff); - - if (player->GetReputationRank(FACTION_SCRYERS) == REP_EXALTED) - player->CastSpell(target, Scryers, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_sunwell_neck_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_sunwell_neck_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_sunwell_neck_AuraScript<AldorSpellId, ScryersSpellId>(); - } -}; - -enum ZandalarianCharms -{ - SPELL_UNSTABLE_POWER_AURA_STACK = 24659, - SPELL_RESTLESS_STRENGTH_AURA_STACK = 24662 -}; - -// Item - 19950: Zandalarian Hero Charm -// 24658 - Unstable Power - -// Item - 19949: Zandalarian Hero Medallion -// 24661 - Restless Strength -class spell_item_zandalarian_charm : public SpellScriptLoader -{ -public: - spell_item_zandalarian_charm(char const* ScriptName, uint32 SpellId) : SpellScriptLoader(ScriptName), _spellId(SpellId) { } - - class spell_item_zandalarian_charm_AuraScript : public AuraScript - { - friend class spell_item_zandalarian_charm; - spell_item_zandalarian_charm_AuraScript(uint32 SpellId) : AuraScript(), _spellId(SpellId) { } - - PrepareAuraScript(spell_item_zandalarian_charm_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ _spellId }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (spellInfo->Id != m_scriptSpellId) - return true; - - return false; - } - - void HandleStackDrop(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->RemoveAuraFromStack(_spellId); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_item_zandalarian_charm_AuraScript::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_item_zandalarian_charm_AuraScript::HandleStackDrop, EFFECT_0, SPELL_AURA_DUMMY); - } - - uint32 _spellId; - }; - - AuraScript* GetAuraScript() const override - { - return new spell_item_zandalarian_charm_AuraScript(_spellId); - } - -private: - uint32 _spellId; -}; - -class spell_item_blood_draining_enchant : public AuraScript -{ - PrepareAuraScript(spell_item_blood_draining_enchant); - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (!eventInfo.GetActionTarget() || !eventInfo.GetDamageInfo() || (eventInfo.GetActionTarget()->GetHealth() - eventInfo.GetDamageInfo()->GetDamage()) >= eventInfo.GetActionTarget()->CountPctFromMaxHealth(35)) - { - return; - } - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(64569 /*SPELL_BLOOD_RESERVE*/)) - { - int32 basepoints = spellInfo->Effects[EFFECT_0].CalcValue() * this->GetStackAmount(); - eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActionTarget(), true); - eventInfo.GetActionTarget()->RemoveAurasDueToSpell(GetSpellInfo()->Id); // Remove rest auras - } - - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(64569 /*SPELL_BLOOD_RESERVE*/); - int32 basepoints = spellInfo->Effects[EFFECT_0].CalcValue() * this->GetStackAmount(); - eventInfo.GetActionTarget()->CastCustomSpell(spellInfo->Id, SPELLVALUE_BASE_POINT0, basepoints, eventInfo.GetActionTarget(), true); - eventInfo.GetActionTarget()->RemoveAurasDueToSpell(GetSpellInfo()->Id); // Remove rest auras - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_item_blood_draining_enchant::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - class spell_item_snowman : public SpellScript { PrepareSpellScript(spell_item_snowman); @@ -5137,43 +3851,6 @@ void AddSC_item_spell_scripts() RegisterSpellScript(spell_item_recall); RegisterSpellScript(spell_item_wraith_scythe_drain_life); RegisterSpellScript(spell_item_mirrens_drinking_hat); - RegisterSpellScript(spell_item_soul_preserver); - RegisterSpellScript(spell_item_death_choice); - new spell_item_trinket_stack("spell_item_lightning_capacitor", SPELL_LIGHTNING_CAPACITOR_STACK, SPELL_LIGHTNING_CAPACITOR_TRIGGER); - new spell_item_trinket_stack("spell_item_thunder_capacitor", SPELL_THUNDER_CAPACITOR_STACK, SPELL_THUNDER_CAPACITOR_TRIGGER); - new spell_item_trinket_stack("spell_item_toc25_normal_caster_trinket", SPELL_TOC25_CASTER_TRINKET_NORMAL_STACK, SPELL_TOC25_CASTER_TRINKET_NORMAL_TRIGGER); - new spell_item_trinket_stack("spell_item_toc25_heroic_caster_trinket", SPELL_TOC25_CASTER_TRINKET_HEROIC_STACK, SPELL_TOC25_CASTER_TRINKET_HEROIC_TRIGGER); - RegisterSpellScript(spell_item_darkmoon_card_greatness); - RegisterSpellScript(spell_item_charm_witch_doctor); - RegisterSpellScript(spell_item_mana_drain); - RegisterSpellScript(spell_item_alchemists_stone); - new spell_item_anger_capacitor<8>("spell_item_tiny_abomination_in_a_jar"); - new spell_item_anger_capacitor<7>("spell_item_tiny_abomination_in_a_jar_hero"); - RegisterSpellScript(spell_item_aura_of_madness); - RegisterSpellScript(spell_item_dementia); - RegisterSpellScript(spell_item_deadly_precision); - RegisterSpellScript(spell_item_deadly_precision_dummy); - new spell_item_deathbringers_will<SPELL_STRENGTH_OF_THE_TAUNKA, SPELL_AGILITY_OF_THE_VRYKUL, SPELL_POWER_OF_THE_TAUNKA, SPELL_AIM_OF_THE_IRON_DWARVES, SPELL_SPEED_OF_THE_VRYKUL>("spell_item_deathbringers_will_normal"); - new spell_item_deathbringers_will<SPELL_STRENGTH_OF_THE_TAUNKA_HERO, SPELL_AGILITY_OF_THE_VRYKUL_HERO, SPELL_POWER_OF_THE_TAUNKA_HERO, SPELL_AIM_OF_THE_IRON_DWARVES_HERO, SPELL_SPEED_OF_THE_VRYKUL_HERO>("spell_item_deathbringers_will_heroic"); - RegisterSpellScript(spell_item_discerning_eye_beast_dummy); - RegisterSpellScript(spell_item_frozen_shadoweave); - RegisterSpellScript(spell_item_healing_touch_refund); - new spell_item_heartpierce<SPELL_INVIGORATION_ENERGY, SPELL_INVIGORATION_MANA, SPELL_INVIGORATION_RAGE, SPELL_INVIGORATION_RP>("spell_item_heartpierce"); - new spell_item_heartpierce<SPELL_INVIGORATION_ENERGY_HERO, SPELL_INVIGORATION_MANA_HERO, SPELL_INVIGORATION_RAGE_HERO, SPELL_INVIGORATION_RP_HERO>("spell_item_heartpierce_hero"); - RegisterSpellScript(spell_item_crystal_spire_of_karabor); - RegisterSpellScript(spell_item_mark_of_conquest); - RegisterSpellScript(spell_item_persistent_shield); - RegisterSpellScript(spell_item_pet_healing); - RegisterSpellScript(spell_item_swift_hand_justice_dummy); - RegisterSpellScript(spell_item_totem_of_flowing_water); - new spell_item_shard_of_the_scale<SPELL_PURIFIED_CAUTERIZING_HEAL, SPELL_PURIFIED_SEARING_FLAMES>("spell_item_purified_shard_of_the_scale"); - new spell_item_shard_of_the_scale<SPELL_SHINY_CAUTERIZING_HEAL, SPELL_SHINY_SEARING_FLAMES>("spell_item_shiny_shard_of_the_scale"); - new spell_item_sunwell_neck<SPELL_LIGHTS_WRATH, SPELL_ARCANE_BOLT>("spell_item_sunwell_exalted_caster_neck"); - new spell_item_sunwell_neck<SPELL_LIGHTS_STRENGTH, SPELL_ARCANE_STRIKE>("spell_item_sunwell_exalted_melee_neck"); - new spell_item_sunwell_neck<SPELL_LIGHTS_WARD, SPELL_ARCANE_INSIGHT>("spell_item_sunwell_exalted_tank_neck"); - new spell_item_sunwell_neck<SPELL_LIGHTS_SALVATION, SPELL_ARCANE_SURGE>("spell_item_sunwell_exalted_healer_neck"); - new spell_item_zandalarian_charm("spell_item_unstable_power", SPELL_UNSTABLE_POWER_AURA_STACK); - new spell_item_zandalarian_charm("spell_item_restless_strength", SPELL_RESTLESS_STRENGTH_AURA_STACK); RegisterSpellScript(spell_item_snowman); RegisterSpellScript(spell_item_freeze_rookery_egg); } diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index f2e32797ad..699ae8ff46 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -31,11 +31,12 @@ enum MageSpells { - SPELL_MAGE_BLAZING_SPEED = 31643, + // Ours SPELL_MAGE_BURNOUT_TRIGGER = 44450, SPELL_MAGE_IMPROVED_BLIZZARD_CHILLED = 12486, SPELL_MAGE_COMBUSTION = 11129, + // Theirs SPELL_MAGE_COLD_SNAP = 11958, SPELL_MAGE_FOCUS_MAGIC_PROC = 54648, SPELL_MAGE_FROST_WARDING_R1 = 11189, @@ -54,49 +55,9 @@ enum MageSpells SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT = 70908, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY = 70907, SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126, - - SPELL_MAGE_CHILLED = 12484, - SPELL_MAGE_MANA_SURGE = 37445, - SPELL_MAGE_MAGIC_ABSORPTION_MANA = 29442, - SPELL_MAGE_ARCANE_POTENCY_RANK_1 = 57529, - SPELL_MAGE_ARCANE_POTENCY_RANK_2 = 57531, - SPELL_MAGE_HOT_STREAK_PROC = 48108, - SPELL_MAGE_ARCANE_SURGE = 37436, - SPELL_MAGE_COMBUSTION_PROC = 28682, - SPELL_MAGE_EMPOWERED_FIRE_PROC = 67545, - SPELL_MAGE_T10_2P_BONUS = 70752, - SPELL_MAGE_T10_2P_BONUS_EFFECT = 70753, - SPELL_MAGE_T8_4P_BONUS = 64869, - SPELL_MAGE_MISSILE_BARRAGE = 44401, - SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA = 44544, SPELL_MAGE_FINGERS_OF_FROST = 44543 }; -// -31641 - Blazing Speed -class spell_mage_blazing_speed : public AuraScript -{ - PrepareAuraScript(spell_mage_blazing_speed); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_BLAZING_SPEED }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (Unit* target = eventInfo.GetActionTarget()) - { - target->CastSpell(target, SPELL_MAGE_BLAZING_SPEED, true, nullptr, aurEff); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_blazing_speed::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - class spell_mage_arcane_blast : public SpellScript { PrepareSpellScript(spell_mage_arcane_blast); @@ -139,7 +100,7 @@ class spell_mage_burning_determination : public AuraScript return false; // Xinef: immuned effect should just eat charge - if (eventInfo.GetHitMask() & PROC_HIT_IMMUNE) + if (eventInfo.GetHitMask() & PROC_EX_IMMUNE) { eventInfo.GetActionTarget()->RemoveAurasDueToSpell(54748); return false; @@ -154,10 +115,10 @@ class spell_mage_burning_determination : public AuraScript return true; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); - GetUnitOwner()->CastSpell(GetUnitOwner(), 54748, true, nullptr, aurEff); + GetUnitOwner()->CastSpell(GetUnitOwner(), 54748, true); } void Register() override @@ -972,349 +933,6 @@ class spell_mage_summon_water_elemental : public SpellScript } }; -// -31571 - Arcane Potency -class spell_mage_arcane_potency : public AuraScript -{ - PrepareAuraScript(spell_mage_arcane_potency); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MAGE_ARCANE_POTENCY_RANK_1, - SPELL_MAGE_ARCANE_POTENCY_RANK_2 - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static uint32 const triggerSpell[2] = { SPELL_MAGE_ARCANE_POTENCY_RANK_1, SPELL_MAGE_ARCANE_POTENCY_RANK_2 }; - - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - uint32 spellId = triggerSpell[GetSpellInfo()->GetRank() - 1]; - caster->CastSpell(caster, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_arcane_potency::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 11129 - Combustion -class spell_mage_combustion : public AuraScript -{ - PrepareAuraScript(spell_mage_combustion); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_COMBUSTION_PROC }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Do not take charges, add a stack of crit buff - if (!(eventInfo.GetHitMask() & PROC_HIT_CRITICAL)) - { - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_MAGE_COMBUSTION_PROC, true); - return false; - } - - return true; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_mage_combustion::CheckProc); - } -}; - -// -11185 - Improved Blizzard -class spell_mage_imp_blizzard : public AuraScript -{ - PrepareAuraScript(spell_mage_imp_blizzard); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_CHILLED }); - } - - void HandleChill(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - uint32 triggerSpellId = sSpellMgr->GetSpellWithRank(SPELL_MAGE_CHILLED, GetSpellInfo()->GetRank()); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), triggerSpellId, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_imp_blizzard::HandleChill, EFFECT_0, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - } -}; - -// 37447 - Improved Mana Gems -// 61062 - Improved Mana Gems -class spell_mage_imp_mana_gems : public AuraScript -{ - PrepareAuraScript(spell_mage_imp_mana_gems); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_MANA_SURGE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell((Unit*)nullptr, SPELL_MAGE_MANA_SURGE, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_imp_mana_gems::HandleProc, EFFECT_1, SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - } -}; - -// -31656 - Empowered Fire -class spell_mage_empowered_fire : public AuraScript -{ - PrepareAuraScript(spell_mage_empowered_fire); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_EMPOWERED_FIRE_PROC }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (spellInfo->Id == SPELL_MAGE_IGNITE) - return true; - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - - Unit* target = GetTarget(); - int32 bp0 = int32(CalculatePct(target->GetCreateMana(), aurEff->GetAmount())); - target->CastCustomSpell(SPELL_MAGE_EMPOWERED_FIRE_PROC, SPELLVALUE_BASE_POINT0, bp0, target, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_mage_empowered_fire::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_mage_empowered_fire::HandleProc, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER); - } -}; - -// 74396 - Fingers of Frost -class spell_mage_fingers_of_frost : public AuraScript -{ - PrepareAuraScript(spell_mage_fingers_of_frost); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA }); - } - - void HandleDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->RemoveAuraFromStack(GetId()); - } - - void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveAurasDueToSpell(SPELL_MAGE_FINGERS_OF_FROST_AURASTATE_AURA); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_fingers_of_frost::HandleDummy, EFFECT_0, SPELL_AURA_DUMMY); - AfterEffectRemove += AuraEffectRemoveFn(spell_mage_fingers_of_frost::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// 48108 - Hot Streak -// 57761 - Fireball! -class spell_mage_gen_extra_effects : public AuraScript -{ - PrepareAuraScript(spell_mage_gen_extra_effects); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_MAGE_T10_2P_BONUS, - SPELL_MAGE_T10_2P_BONUS_EFFECT, - SPELL_MAGE_T8_4P_BONUS - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - Unit* caster = eventInfo.GetActor(); - // Prevent double proc for Arcane missiles - if (caster == eventInfo.GetProcTarget()) - return false; - - // Proc chance is unknown, we'll just use dummy aura amount - if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_MAGE_T8_4P_BONUS, EFFECT_0)) - if (roll_chance_i(aurEff->GetAmount())) - return false; - - return true; - } - - void HandleProc(ProcEventInfo& eventInfo) - { - Unit* caster = eventInfo.GetActor(); - - if (caster->HasAura(SPELL_MAGE_T10_2P_BONUS)) - caster->CastSpell((Unit*)nullptr, SPELL_MAGE_T10_2P_BONUS_EFFECT, true); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_mage_gen_extra_effects::CheckProc); - OnProc += AuraProcFn(spell_mage_gen_extra_effects::HandleProc); - } -}; - -// 56375 - Glyph of Polymorph -class spell_mage_glyph_of_polymorph : public AuraScript -{ - PrepareAuraScript(spell_mage_glyph_of_polymorph); - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* target = eventInfo.GetProcTarget(); - target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, ObjectGuid::Empty, target->GetAura(32409)); // SW:D shall not be removed. - target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); - target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_polymorph::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 56374 - Glyph of Icy Veins -class spell_mage_glyph_of_icy_veins : public AuraScript -{ - PrepareAuraScript(spell_mage_glyph_of_icy_veins); - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - caster->RemoveAurasByType(SPELL_AURA_HASTE_SPELLS, ObjectGuid::Empty, 0, true, false); - caster->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_icy_veins::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -44445 - Hot Streak -class spell_mage_hot_streak : public AuraScript -{ - PrepareAuraScript(spell_mage_hot_streak); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_HOT_STREAK_PROC }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - AuraEffect* counter = GetEffect(EFFECT_1); - if (!counter) - return; - - // Count spell criticals in a row in second aura - if (eventInfo.GetHitMask() & PROC_HIT_CRITICAL) - { - counter->SetAmount(counter->GetAmount() * 2); - if (counter->GetAmount() < 100) // not enough - return; - - // roll chance - if (!roll_chance_i(aurEff->GetAmount())) - return; - - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, SPELL_MAGE_HOT_STREAK_PROC, true, nullptr, aurEff); - } - - // reset counter - counter->SetAmount(25); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_hot_streak::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -29441 - Magic Absorption -class spell_mage_magic_absorption : public AuraScript -{ - PrepareAuraScript(spell_mage_magic_absorption); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_MAGE_MAGIC_ABSORPTION_MANA }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActionTarget(); - int32 bp = CalculatePct(static_cast<int32>(caster->GetMaxPower(POWER_MANA)), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_MAGE_MAGIC_ABSORPTION_MANA, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_mage_magic_absorption::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -44404 - Missile Barrage -class spell_mage_missile_barrage : public AuraScript -{ - PrepareAuraScript(spell_mage_missile_barrage); - - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - // Arcane Blast - full chance - if (spellInfo->SpellFamilyFlags[0] & 0x20000000) - return true; - - // Rest of spells have half chance - return roll_chance_i(50); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_mage_missile_barrage::CheckProc); - } -}; - #define FingersOfFrostScriptName "spell_mage_fingers_of_frost_proc_aura" class spell_mage_fingers_of_frost_proc_aura : public AuraScript { PrepareAuraScript(spell_mage_fingers_of_frost_proc_aura); @@ -1425,7 +1043,6 @@ class spell_mage_fingers_of_frost_proc : public AuraScript void AddSC_mage_spell_scripts() { - RegisterSpellScript(spell_mage_blazing_speed); RegisterSpellScript(spell_mage_arcane_blast); RegisterSpellScript(spell_mage_burning_determination); RegisterSpellScript(spell_mage_molten_armor); @@ -1447,18 +1064,6 @@ void AddSC_mage_spell_scripts() RegisterSpellScript(spell_mage_master_of_elements); RegisterSpellScript(spell_mage_polymorph_cast_visual); RegisterSpellScript(spell_mage_summon_water_elemental); - RegisterSpellScript(spell_mage_arcane_potency); - RegisterSpellScript(spell_mage_combustion); - RegisterSpellScript(spell_mage_imp_blizzard); - RegisterSpellScript(spell_mage_imp_mana_gems); - RegisterSpellScript(spell_mage_empowered_fire); - RegisterSpellScript(spell_mage_fingers_of_frost); - RegisterSpellScript(spell_mage_gen_extra_effects); - RegisterSpellScript(spell_mage_glyph_of_polymorph); - RegisterSpellScript(spell_mage_glyph_of_icy_veins); - RegisterSpellScript(spell_mage_hot_streak); - RegisterSpellScript(spell_mage_magic_absorption); - RegisterSpellScript(spell_mage_missile_barrage); RegisterSpellScript(spell_mage_fingers_of_frost_proc_aura); RegisterSpellScript(spell_mage_fingers_of_frost_proc); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index c77f49d8ee..a3588b7d12 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -28,7 +28,6 @@ #include "SpellMgr.h" #include "SpellScript.h" #include "UnitAI.h" -#include "GameTime.h" enum PaladinSpells { @@ -39,7 +38,6 @@ enum PaladinSpells SPELL_PALADIN_HOLY_SHOCK_R1 = 20473, SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912, SPELL_PALADIN_HOLY_SHOCK_R1_HEALING = 25914, - SPELL_PALADIN_ILLUMINATION_ENERGIZE = 20272, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_DRUID = 37878, SPELL_PALADIN_BLESSING_OF_LOWER_CITY_PALADIN = 37879, @@ -83,50 +81,12 @@ enum PaladinSpells SPELL_PALADIN_AURA_MASTERY_IMMUNE = 64364, SPELL_GENERIC_ARENA_DAMPENING = 74410, - SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411, - - SPELL_PALADIN_SACRED_SHIELD = 53601, - SPELL_PALADIN_T9_HOLY_4P_BONUS = 67191, - SPELL_PALADIN_FLASH_OF_LIGHT_PROC = 66922, - - SPELL_PALADIN_JUDGEMENTS_OF_THE_JUST_PROC = 68055, - - SPELL_PALADIN_GLYPH_OF_DIVINITY_PROC = 54986, - - SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA = 31930, - SPELL_REPLENISHMENT = 57669, - SPELL_PALADIN_RIGHTEOUS_VENGEANCE_DAMAGE = 61840, - SPELL_PALADIN_SHEATH_OF_LIGHT_HEAL = 54203, - SPELL_PALADIN_SACRED_SHIELD_TRIGGER = 58597, - SPELL_PALADIN_T8_HOLY_4P_BONUS = 64895, - SPELL_PALADIN_HEART_OF_THE_CRUSADER_EFF_R1 = 21183, - - SPELL_PALADIN_HOLY_POWER_ARMOR = 28790, - SPELL_PALADIN_HOLY_POWER_ATTACK_POWER = 28791, - SPELL_PALADIN_HOLY_POWER_SPELL_POWER = 28793, - SPELL_PALADIN_HOLY_POWER_MP5 = 28795, - - SPELL_PALADIN_HOLY_VENGEANCE = 31803, - SPELL_PALADIN_SEAL_OF_VENGEANCE_DAMAGE = 42463, - SPELL_PALADIN_BLOOD_CORRUPTION = 53742, - SPELL_PALADIN_SEAL_OF_CORRUPTION_DAMAGE = 53739, - - SPELL_PALADIN_SPIRITUAL_ATTUNEMENT_MANA = 31786, - - SPELL_PALADIN_ENDURING_LIGHT = 40471, - SPELL_PALADIN_ENDURING_JUDGEMENT = 40472, - - SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL = 54968, - SPELL_PALADIN_HOLY_MENDING = 64891, - - SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL = 20267, - SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA = 20268 + SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411 }; enum PaladinSpellIcons { - PALADIN_ICON_ID_RETRIBUTION_AURA = 555, - PALADIN_ICON_ID_HAMMER_OF_THE_RIGHTEOUS = 3023 + PALADIN_ICON_ID_RETRIBUTION_AURA = 555 }; class spell_pal_seal_of_command_aura : public AuraScript @@ -258,6 +218,13 @@ class spell_pal_sacred_shield_base : public AuraScript } } + bool CheckProc(ProcEventInfo& eventInfo) + { + HealInfo* healinfo = eventInfo.GetHealInfo(); + DamageInfo* damageinfo = eventInfo.GetDamageInfo(); + return !(eventInfo.GetHitMask() & PROC_EX_INTERNAL_HOT) && ((healinfo && healinfo->GetHeal() > 0) || (damageinfo && damageinfo->GetDamage() > 0)); + } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); @@ -313,6 +280,7 @@ class spell_pal_sacred_shield_base : public AuraScript void Register() override { DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_sacred_shield_base::CalculateAmount, EFFECT_0, SPELL_AURA_DUMMY); + DoCheckProc += AuraCheckProcFn(spell_pal_sacred_shield_base::CheckProc); OnEffectProc += AuraEffectProcFn(spell_pal_sacred_shield_base::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); } }; @@ -870,51 +838,6 @@ class spell_pal_holy_shock : public SpellScript } }; -// -20210 - Illumination -class spell_pal_illumination : public AuraScript -{ - PrepareAuraScript(spell_pal_illumination); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_HOLY_SHOCK_R1_HEALING, SPELL_PALADIN_ILLUMINATION_ENERGIZE, SPELL_PALADIN_HOLY_SHOCK_R1 }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // this script is valid only for the Holy Shock procs of illumination - if (eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetSpellInfo()) - { - SpellInfo const* originalSpell = nullptr; - - // if proc comes from the Holy Shock heal, need to get mana cost of original spell - else it's the original heal itself - if (eventInfo.GetHealInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x00010000) - { - originalSpell = sSpellMgr->GetSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_PALADIN_HOLY_SHOCK_R1, eventInfo.GetHealInfo()->GetSpellInfo()->GetRank())); - } - else - { - originalSpell = eventInfo.GetHealInfo()->GetSpellInfo(); - } - - if (originalSpell && aurEff->GetSpellInfo()) - { - Unit* target = eventInfo.GetActor(); // Paladin is the target of the energize - - uint32 bp = CalculatePct(originalSpell->CalcPowerCost(target, originalSpell->GetSchoolMask()), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); - target->CastCustomSpell(SPELL_PALADIN_ILLUMINATION_ENERGIZE, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); - } - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_illumination::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 53407 - Judgement of Justice // 20271 - Judgement of Light // 53408 - Judgement of Wisdom @@ -1120,7 +1043,7 @@ class spell_pal_seal_of_righteousness : public AuraScript return false; } - return target->IsAlive() && !eventInfo.GetTriggerAuraSpell() && (damageInfo->GetDamage() || (eventInfo.GetHitMask() & PROC_HIT_ABSORB)); + return target->IsAlive() && !eventInfo.GetTriggerAuraSpell() && (damageInfo->GetDamage() || (eventInfo.GetHitMask() & PROC_EX_ABSORB)); } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) @@ -1148,598 +1071,6 @@ class spell_pal_seal_of_righteousness : public AuraScript } }; -// -31871 - Divine Purpose -class spell_pal_divine_purpose : public AuraScript -{ - PrepareAuraScript(spell_pal_divine_purpose); - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (!roll_chance_i(aurEff->GetAmount())) - return; - - eventInfo.GetProcTarget()->RemoveAurasWithMechanic(1 << MECHANIC_STUN, AURA_REMOVE_BY_ENEMY_SPELL); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_divine_purpose::HandleProc, EFFECT_2, SPELL_AURA_DUMMY); - } -}; - -// 54939 - Glyph of Divinity -class spell_pal_glyph_of_divinity : public AuraScript -{ - PrepareAuraScript(spell_pal_glyph_of_divinity); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_GLYPH_OF_DIVINITY_PROC }); - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - // Lay on Hands (Rank 1) does not have mana effect - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->Effects[EFFECT_1].Effect != SPELL_EFFECT_ENERGIZE) - return; - - Unit* caster = eventInfo.GetActor(); - if (caster == eventInfo.GetProcTarget()) - return; - - int32 mana = spellInfo->Effects[EFFECT_1].CalcValue() * 2; - caster->CastCustomSpell(SPELL_PALADIN_GLYPH_OF_DIVINITY_PROC, SPELLVALUE_BASE_POINT1, mana, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_glyph_of_divinity::OnProc, EFFECT_0, SPELL_AURA_ADD_PCT_MODIFIER); - } -}; - -// 54937 - Glyph of Holy Light (dummy aura) -class spell_pal_glyph_of_holy_light_dummy : public AuraScript -{ - PrepareAuraScript(spell_pal_glyph_of_holy_light_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount()); - - caster->CastCustomSpell(SPELL_PALADIN_GLYPH_OF_HOLY_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_glyph_of_holy_light_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -20335 - Heart of the Crusader -class spell_pal_heart_of_the_crusader : public AuraScript -{ - PrepareAuraScript(spell_pal_heart_of_the_crusader); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_HEART_OF_THE_CRUSADER_EFF_R1 }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_PALADIN_HEART_OF_THE_CRUSADER_EFF_R1, GetSpellInfo()->GetRank()); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_heart_of_the_crusader::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -20234 - Improved Lay on Hands -class spell_pal_improved_lay_of_hands : public AuraScript -{ - PrepareAuraScript(spell_pal_improved_lay_of_hands); - - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActionTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff, GetTarget()->GetGUID()); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_improved_lay_of_hands::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// -53569 - Infusion of Light -class spell_pal_infusion_of_light : public AuraScript -{ - PrepareAuraScript(spell_pal_infusion_of_light); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PALADIN_SACRED_SHIELD, - SPELL_PALADIN_T9_HOLY_4P_BONUS, - SPELL_PALADIN_FLASH_OF_LIGHT_PROC - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - { - // Flash of Light HoT on Flash of Light when Sacred Shield active - if (spellInfo->SpellFamilyFlags[0] & 0x40000000 && spellInfo->SpellIconID == 242) - { - PreventDefaultAction(); - - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - Unit* procTarget = eventInfo.GetActionTarget(); - if (procTarget && procTarget->HasAura(SPELL_PALADIN_SACRED_SHIELD)) - { - Unit* target = GetTarget(); - int32 duration = sSpellMgr->AssertSpellInfo(SPELL_PALADIN_FLASH_OF_LIGHT_PROC)->GetMaxDuration() / 1000; - int32 pct = GetSpellInfo()->Effects[EFFECT_2].CalcValue(); - int32 bp0 = CalculatePct(healInfo->GetHeal() / duration, pct); - - // Item - Paladin T9 Holy 4P Bonus - if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_PALADIN_T9_HOLY_4P_BONUS, 0)) - AddPct(bp0, aurEff->GetAmount()); - - target->CastCustomSpell(SPELL_PALADIN_FLASH_OF_LIGHT_PROC, SPELLVALUE_BASE_POINT0, bp0, procTarget, true, nullptr, aurEff); - } - } - // but should not proc on non-critical Holy Shocks - else if ((spellInfo->SpellFamilyFlags[0] & 0x200000 || spellInfo->SpellFamilyFlags[1] & 0x10000) && !(eventInfo.GetHitMask() & PROC_HIT_CRITICAL)) - PreventDefaultAction(); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_infusion_of_light::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 40470 - Paladin Tier 6 Trinket -class spell_pal_item_t6_trinket : public AuraScript -{ - PrepareAuraScript(spell_pal_item_t6_trinket); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PALADIN_ENDURING_LIGHT, - SPELL_PALADIN_ENDURING_JUDGEMENT - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - uint32 spellId; - int32 chance; - - // Holy Light & Flash of Light - if (spellInfo->SpellFamilyFlags[0] & 0xC0000000) - { - spellId = SPELL_PALADIN_ENDURING_LIGHT; - chance = 15; - } - // Judgements - else if (spellInfo->SpellFamilyFlags[0] & 0x00800000) - { - spellId = SPELL_PALADIN_ENDURING_JUDGEMENT; - chance = 50; - } - else - return; - - if (roll_chance_i(chance)) - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 20185 - Judgement of Light -class spell_pal_judgement_of_light_heal : public AuraScript -{ - PrepareAuraScript(spell_pal_judgement_of_light_heal); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetProcTarget(); - int32 amount = static_cast<int32>(caster->CountPctFromMaxHealth(aurEff->GetAmount())); - - caster->CastCustomSpell(SPELL_PALADIN_JUDGEMENT_OF_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_judgement_of_light_heal::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 20186 - Judgement of Wisdom -class spell_pal_judgement_of_wisdom_mana : public AuraScript -{ - PrepareAuraScript(spell_pal_judgement_of_wisdom_mana); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetProcTarget()->getPowerType() == POWER_MANA; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetProcTarget(); - int32 amount = CalculatePct(static_cast<int32>(caster->GetCreateMana()), aurEff->GetAmount()); - - caster->CastCustomSpell(SPELL_PALADIN_JUDGEMENT_OF_WISDOM_MANA, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pal_judgement_of_wisdom_mana::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pal_judgement_of_wisdom_mana::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -53695 - Judgements of the Just -class spell_pal_judgements_of_the_just : public AuraScript -{ - PrepareAuraScript(spell_pal_judgements_of_the_just); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_JUDGEMENTS_OF_THE_JUST_PROC }); - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - GetTarget()->CastSpell(eventInfo.GetActionTarget(), SPELL_PALADIN_JUDGEMENTS_OF_THE_JUST_PROC, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_judgements_of_the_just::OnProc, EFFECT_0, SPELL_AURA_ADD_FLAT_MODIFIER); - } -}; - -// -31876 - Judgements of the Wise -class spell_pal_judgements_of_the_wise : public AuraScript -{ - PrepareAuraScript(spell_pal_judgements_of_the_wise); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_REPLENISHMENT, - SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - caster->CastSpell((Unit*)nullptr, SPELL_PALADIN_JUDGEMENTS_OF_THE_WISE_MANA, true, nullptr, aurEff); - caster->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_judgements_of_the_wise::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 53601 - Sacred Shield (dummy) -class spell_pal_sacred_shield_dummy : public AuraScript -{ - PrepareAuraScript(spell_pal_sacred_shield_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PALADIN_SACRED_SHIELD_TRIGGER, - SPELL_PALADIN_T8_HOLY_4P_BONUS - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = GetCaster(); - if (!caster) - return; - - TimePoint now = GameTime::Now(); - if (_cooldownEnd > now) - return; - - Seconds cooldown(aurEff->GetAmount()); - if (AuraEffect const* bonus = caster->GetAuraEffect(SPELL_PALADIN_T8_HOLY_4P_BONUS, EFFECT_0, caster->GetGUID())) - cooldown = Seconds(bonus->GetAmount()); - - _cooldownEnd = now + cooldown; - caster->CastSpell(eventInfo.GetActionTarget(), SPELL_PALADIN_SACRED_SHIELD_TRIGGER, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_sacred_shield_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } - - // Cooldown tracking can't be done in DB because of T8 bonus - TimePoint _cooldownEnd = std::chrono::steady_clock::time_point::min(); -}; - -// 31801 - Seal of Vengeance -// 53736 - Seal of Corruption -template <uint32 DoTSpellId, uint32 DamageSpellId> -class spell_pal_seal_of_vengeance : public SpellScriptLoader -{ -public: - spell_pal_seal_of_vengeance(char const* ScriptName) : SpellScriptLoader(ScriptName) { } - - template <uint32 DoTSpell, uint32 DamageSpell> - class spell_pal_seal_of_vengeance_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pal_seal_of_vengeance_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - DoTSpell, - DamageSpell - }); - } - - /* - When an auto-attack lands (does not dodge/parry/miss) that can proc a seal the of the following things happen independently of each other (see 2 roll system). - - 1) A "hidden strike" which uses melee combat mechanics occurs. If it lands it refreshes/stacks SoV DoT. Only white swings can trigger a refresh or stack. (This hidden strike mechanic can also proc things like berserking..) - 2) A weapon damage based proc will occur if you used a special (CS/DS/judge) or if you have a 5 stack (from auto attacks). This attack can not be avoided. - - Remember #2 happens regardless of #1 landing, it just requires the initial attack (autos, cs, etc) to land. - - Stack Number % of Weapon Damage % with SotP - 0 0% 0% - 1 6.6% 7.6% - 2 13.2% 15.2% - 3 19.8% 22.8% - 4 26.4% 30.4% - 5 33% 38% - */ - - void HandleApplyDoT(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - if (!(eventInfo.GetTypeMask() & PROC_FLAG_DONE_MELEE_AUTO_ATTACK)) - { - // Patch 3.2.0 Notes: Only auto-attacks and Hammer of the Righteous can place the debuff on the paladin's current target(s). - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != PALADIN_ICON_ID_HAMMER_OF_THE_RIGHTEOUS) - return; - } - - // don't cast triggered, spell already has SPELL_ATTR4_CAN_CAST_WHILE_CASTING attr - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), DoTSpell, TRIGGERED_NO_PERIODIC_RESET, nullptr, aurEff); - } - - void HandleSeal(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - - AuraEffect const* sealDot = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PALADIN, 0x00000000, 0x00000800, 0x00000000, caster->GetGUID()); - if (!sealDot) - return; - - uint8 const stacks = sealDot->GetBase()->GetStackAmount(); - uint8 const maxStacks = sealDot->GetSpellInfo()->StackAmount; - - if (stacks < maxStacks && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_SPELL_MELEE_DMG_CLASS)) - return; - - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(DamageSpell); - int32 amount = spellInfo->Effects[EFFECT_0].CalcValue(); - amount *= stacks; - amount /= maxStacks; - - caster->CastCustomSpell(DamageSpell, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_seal_of_vengeance_AuraScript::HandleApplyDoT, EFFECT_0, SPELL_AURA_DUMMY); - OnEffectProc += AuraEffectProcFn(spell_pal_seal_of_vengeance_AuraScript::HandleSeal, EFFECT_0, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_pal_seal_of_vengeance_AuraScript<DoTSpellId, DamageSpellId>(); - } -}; - -// 20375 - Seal of Command -// 21084 - Seal of Righteousness -// 31801 - Seal of Vengeance -// 31892 - Seal of Blood -// 33127 - Seal of Command -// 38008 - Seal of Blood -// 41459 - Seal of Blood -// 53720 - Seal of the Martyr -// 53736 - Seal of Corruption -class spell_pal_seals : public AuraScript -{ - PrepareAuraScript(spell_pal_seals); - - // Effect 2 is used by Judgement code, we prevent the proc to avoid console logging of unknown spell trigger - bool CheckDummyProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - return false; - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_pal_seals::CheckDummyProc, EFFECT_2, SPELL_AURA_DUMMY); - } -}; - -// -31785 - Spiritual Attunement -class spell_pal_spiritual_attunement : public AuraScript -{ - PrepareAuraScript(spell_pal_spiritual_attunement); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PALADIN_SPIRITUAL_ATTUNEMENT_MANA }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // "when healed by other friendly targets' spells" - if (eventInfo.GetProcTarget() == eventInfo.GetActionTarget()) - return false; - - return eventInfo.GetHealInfo() && eventInfo.GetHealInfo()->GetEffectiveHeal(); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - HealInfo* healInfo = eventInfo.GetHealInfo(); - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetEffectiveHeal()), aurEff->GetAmount()); - - eventInfo.GetActionTarget()->CastCustomSpell(SPELL_PALADIN_SPIRITUAL_ATTUNEMENT_MANA, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pal_spiritual_attunement::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pal_spiritual_attunement::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 28789 - Holy Power -class spell_pal_t3_6p_bonus : public AuraScript -{ - PrepareAuraScript(spell_pal_t3_6p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PALADIN_HOLY_POWER_ARMOR, - SPELL_PALADIN_HOLY_POWER_ATTACK_POWER, - SPELL_PALADIN_HOLY_POWER_SPELL_POWER, - SPELL_PALADIN_HOLY_POWER_MP5 - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - uint32 spellId; - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - - switch (target->getClass()) - { - case CLASS_PALADIN: - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_DRUID: - spellId = SPELL_PALADIN_HOLY_POWER_MP5; - break; - case CLASS_MAGE: - case CLASS_WARLOCK: - spellId = SPELL_PALADIN_HOLY_POWER_SPELL_POWER; - break; - case CLASS_HUNTER: - case CLASS_ROGUE: - spellId = SPELL_PALADIN_HOLY_POWER_ATTACK_POWER; - break; - case CLASS_WARRIOR: - spellId = SPELL_PALADIN_HOLY_POWER_ARMOR; - break; - default: - return; - } - - caster->CastSpell(target, spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pal_t3_6p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - void AddSC_paladin_spell_scripts() { RegisterSpellAndAuraScriptPair(spell_pal_seal_of_command, spell_pal_seal_of_command_aura); @@ -1760,7 +1091,6 @@ void AddSC_paladin_spell_scripts() RegisterSpellAndAuraScriptPair(spell_pal_hand_of_sacrifice, spell_pal_hand_of_sacrifice_aura); RegisterSpellScript(spell_pal_hand_of_salvation); RegisterSpellScript(spell_pal_holy_shock); - RegisterSpellScript(spell_pal_illumination); RegisterSpellScriptWithArgs(spell_pal_judgement, "spell_pal_judgement_of_justice", SPELL_PALADIN_JUDGEMENT_OF_JUSTICE); RegisterSpellScriptWithArgs(spell_pal_judgement, "spell_pal_judgement_of_light", SPELL_PALADIN_JUDGEMENT_OF_LIGHT); RegisterSpellScriptWithArgs(spell_pal_judgement, "spell_pal_judgement_of_wisdom", SPELL_PALADIN_JUDGEMENT_OF_WISDOM); @@ -1768,21 +1098,4 @@ void AddSC_paladin_spell_scripts() RegisterSpellScript(spell_pal_lay_on_hands); RegisterSpellScript(spell_pal_righteous_defense); RegisterSpellScript(spell_pal_seal_of_righteousness); - RegisterSpellScript(spell_pal_divine_purpose); - RegisterSpellScript(spell_pal_glyph_of_divinity); - RegisterSpellScript(spell_pal_glyph_of_holy_light_dummy); - RegisterSpellScript(spell_pal_heart_of_the_crusader); - RegisterSpellScript(spell_pal_improved_lay_of_hands); - RegisterSpellScript(spell_pal_infusion_of_light); - RegisterSpellScript(spell_pal_item_t6_trinket); - RegisterSpellScript(spell_pal_judgement_of_light_heal); - RegisterSpellScript(spell_pal_judgement_of_wisdom_mana); - RegisterSpellScript(spell_pal_judgements_of_the_just); - RegisterSpellScript(spell_pal_judgements_of_the_wise); - RegisterSpellScript(spell_pal_sacred_shield_dummy); - new spell_pal_seal_of_vengeance<SPELL_PALADIN_HOLY_VENGEANCE, SPELL_PALADIN_SEAL_OF_VENGEANCE_DAMAGE>("spell_pal_seal_of_vengeance"); - new spell_pal_seal_of_vengeance<SPELL_PALADIN_BLOOD_CORRUPTION, SPELL_PALADIN_SEAL_OF_CORRUPTION_DAMAGE>("spell_pal_seal_of_corruption"); - RegisterSpellScript(spell_pal_seals); - RegisterSpellScript(spell_pal_spiritual_attunement); - RegisterSpellScript(spell_pal_t3_6p_bonus); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index e1d9295b92..89624091b6 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -31,7 +31,6 @@ enum PriestSpells { - SPELL_PRIEST_BLESSED_RECOVERY_R1 = 27813, SPELL_PRIEST_DIVINE_AEGIS = 47753, SPELL_PRIEST_EMPOWERED_RENEW = 63544, SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING = 55675, @@ -54,22 +53,7 @@ enum PriestSpells SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411, SPELL_PRIEST_TWIN_DISCIPLINE_R1 = 47586, SPELL_PRIEST_SPIRITUAL_HEALING_R1 = 14898, - SPELL_PRIEST_DIVINE_PROVIDENCE_R1 = 47562, - - SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA = 58227, - SPELL_REPLENISHMENT = 57669, - SPELL_PRIEST_BODY_AND_SOUL_POISON_TRIGGER = 64136, - SPELL_PRIEST_ABOLISH_DISEASE = 552, - SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL = 15290, - SPELL_PRIEST_DIVINE_BLESSING = 40440, - SPELL_PRIEST_DIVINE_WRATH = 40441, - SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL = 56131, - SPELL_PRIEST_ORACULAR_HEAL = 26170, - SPELL_PRIEST_ARMOR_OF_FAITH = 28810, - SPELL_PRIEST_BLESSED_HEALING = 70772, - SPELL_PRIEST_MIND_BLAST_R1 = 8092, - SPELL_PRIEST_SHADOW_WORD_DEATH_R1 = 32379, - SPELL_PRIEST_MIND_FLAY_DAMAGE = 58381 + SPELL_PRIEST_DIVINE_PROVIDENCE_R1 = 47562 }; enum PriestSpellIcons @@ -165,41 +149,6 @@ class spell_pri_shadowfiend_scaling : public AuraScript } }; -// -27811 - Blessed Recovery -class spell_pri_blessed_recovery : public AuraScript -{ - PrepareAuraScript(spell_pri_blessed_recovery); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_BLESSED_RECOVERY_R1 }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* dmgInfo = eventInfo.GetDamageInfo(); - if (!dmgInfo || !dmgInfo->GetDamage()) - return; - - Unit* target = eventInfo.GetActionTarget(); - uint32 triggerSpell = sSpellMgr->GetSpellWithRank(SPELL_PRIEST_BLESSED_RECOVERY_R1, aurEff->GetSpellInfo()->GetRank()); - SpellInfo const* triggerInfo = sSpellMgr->AssertSpellInfo(triggerSpell); - - int32 bp = CalculatePct(static_cast<int32>(dmgInfo->GetDamage()), aurEff->GetAmount()); - - ASSERT(triggerInfo->GetMaxTicks() > 0); - bp /= triggerInfo->GetMaxTicks(); - - target->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_blessed_recovery::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // -34861 - Circle of Healing class spell_pri_circle_of_healing : public SpellScript { @@ -400,6 +349,15 @@ class spell_pri_item_greater_heal_refund : public AuraScript return ValidateSpellInfo({ SPELL_PRIEST_ITEM_EFFICIENCY }); } + bool CheckProc(ProcEventInfo& eventInfo) + { + if (HealInfo* healInfo = eventInfo.GetHealInfo()) + if (Unit* healTarget = healInfo->GetTarget()) + if (eventInfo.GetHitMask() & PROC_EX_NO_OVERHEAL && healTarget->IsFullHealth()) + return true; + return false; + } + void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); @@ -408,6 +366,7 @@ class spell_pri_item_greater_heal_refund : public AuraScript void Register() override { + DoCheckProc += AuraCheckProcFn(spell_pri_item_greater_heal_refund::CheckProc); OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -563,33 +522,6 @@ class spell_pri_mind_sear : public SpellScript } }; -// -47580 - Pain and Suffering (dummy aura) -class spell_pri_pain_and_suffering_dummy : public SpellScriptLoader -{ -public: - spell_pri_pain_and_suffering_dummy() : SpellScriptLoader("spell_pri_pain_and_suffering_dummy") { } - - class spell_pri_pain_and_suffering_dummy_AuraScript : public AuraScript - { - PrepareAuraScript(spell_pri_pain_and_suffering_dummy_AuraScript); - - bool CheckDummy(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) - { - return false; - } - - void Register() override - { - DoCheckEffectProc += AuraCheckEffectProcFn(spell_pri_pain_and_suffering_dummy_AuraScript::CheckDummy, EFFECT_1, SPELL_AURA_DUMMY); - } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_pri_pain_and_suffering_dummy_AuraScript; - } -}; - // 47948 - Pain and Suffering (Proc) class spell_pri_pain_and_suffering_proc : public SpellScript { @@ -994,326 +926,9 @@ class spell_pri_mind_control : public AuraScript } }; -// 26169 - Oracle Healing Bonus -class spell_pri_aq_3p_bonus : public AuraScript -{ - PrepareAuraScript(spell_pri_aq_3p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_ORACULAR_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - if (caster == eventInfo.GetProcTarget()) - return; - - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), 10); - caster->CastCustomSpell(SPELL_PRIEST_ORACULAR_HEAL, SPELLVALUE_BASE_POINT0, amount, caster, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_aq_3p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -64127 - Body and Soul -class spell_pri_body_and_soul : public AuraScript -{ - PrepareAuraScript(spell_pri_body_and_soul); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PRIEST_BODY_AND_SOUL_POISON_TRIGGER, - SPELL_PRIEST_ABOLISH_DISEASE - }); - } - - void HandleProcTriggerSpell(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - // Proc only on Power Word: Shield - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || !(spellInfo->SpellFamilyFlags[0] & 0x00000001)) - { - PreventDefaultAction(); - return; - } - } - - void HandleProcDummy(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // Proc only on self casted abolish disease - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - Unit* caster = eventInfo.GetActor(); - if (spellInfo->Id != SPELL_PRIEST_ABOLISH_DISEASE || caster != eventInfo.GetProcTarget()) - return; - - if (roll_chance_i(aurEff->GetAmount())) - caster->CastSpell(caster, SPELL_PRIEST_BODY_AND_SOUL_POISON_TRIGGER, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul::HandleProcTriggerSpell, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul::HandleProcDummy, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - -// 55677 - Glyph of Dispel Magic -class spell_pri_glyph_of_dispel_magic : public AuraScript -{ - PrepareAuraScript(spell_pri_glyph_of_dispel_magic); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - // Dispel Magic shares spellfamilyflag with abolish disease - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != 74) - return; - - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - int32 amount = static_cast<int32>(target->CountPctFromMaxHealth(aurEff->GetAmount())); - - caster->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_glyph_of_dispel_magic::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -47569 - Improved Shadowform -class spell_pri_imp_shadowform : public AuraScript -{ - PrepareAuraScript(spell_pri_imp_shadowform); - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - if (roll_chance_i(aurEff->GetAmount())) - eventInfo.GetActor()->RemoveMovementImpairingAuras(true); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_imp_shadowform::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -15337 - Improved Spirit Tap -class spell_pri_improved_spirit_tap : public AuraScript -{ - PrepareAuraScript(spell_pri_improved_spirit_tap); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PRIEST_SHADOW_WORD_DEATH_R1, - SPELL_PRIEST_MIND_BLAST_R1 - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - { - if (spellInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PRIEST_SHADOW_WORD_DEATH_R1)) || - spellInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_PRIEST_MIND_BLAST_R1))) - return true; - else if (spellInfo->Id == SPELL_PRIEST_MIND_FLAY_DAMAGE) - return roll_chance_i(50); - } - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pri_improved_spirit_tap::CheckProc); - } -}; - -// 40438 - Priest Tier 6 Trinket -class spell_pri_item_t6_trinket : public AuraScript -{ - PrepareAuraScript(spell_pri_item_t6_trinket); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_PRIEST_DIVINE_BLESSING, - SPELL_PRIEST_DIVINE_WRATH - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_HEAL) - caster->CastSpell((Unit*)nullptr, SPELL_PRIEST_DIVINE_BLESSING, true, nullptr, aurEff); - - if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_DAMAGE) - caster->CastSpell((Unit*)nullptr, SPELL_PRIEST_DIVINE_WRATH, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 57989 - Shadowfiend Death -class spell_pri_shadowfiend_death : public AuraScript -{ - PrepareAuraScript(spell_pri_shadowfiend_death); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return false; - - Unit* shadowfiend = eventInfo.GetActionTarget(); - if (!shadowfiend->GetOwner()) - return false; - - return shadowfiend->HealthBelowPctDamaged(1, damageInfo->GetDamage()); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActionTarget()->GetOwner(); - caster->CastSpell(caster, SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA, aurEff, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pri_shadowfiend_death::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pri_shadowfiend_death::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 15286 - Vampiric Embrace -class spell_pri_vampiric_embrace : public AuraScript -{ - PrepareAuraScript(spell_pri_vampiric_embrace); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 selfHeal = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - int32 partyHeal = selfHeal / 5; - Unit* caster = eventInfo.GetActor(); - caster->CastCustomSpell((Unit*)nullptr, SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL, &partyHeal, &selfHeal, nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_embrace::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 28809 - Greater Heal -class spell_pri_t3_4p_bonus : public AuraScript -{ - PrepareAuraScript(spell_pri_t3_4p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_ARMOR_OF_FAITH }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_PRIEST_ARMOR_OF_FAITH, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_pri_t3_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 37594 - Greater Heal Refund -class spell_pri_t5_heal_2p_bonus : public AuraScript -{ - PrepareAuraScript(spell_pri_t5_heal_2p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PRIEST_ITEM_EFFICIENCY }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (HealInfo* healInfo = eventInfo.GetHealInfo()) - if (Unit* healTarget = healInfo->GetTarget()) - if (healInfo->GetEffectiveHeal()) - if (healTarget->GetHealth() >= healTarget->GetMaxHealth()) - return true; - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_pri_t5_heal_2p_bonus::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_pri_t5_heal_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - void AddSC_priest_spell_scripts() { RegisterSpellScript(spell_pri_shadowfiend_scaling); - RegisterSpellScript(spell_pri_blessed_recovery); RegisterSpellScript(spell_pri_circle_of_healing); RegisterSpellScript(spell_pri_divine_aegis); RegisterSpellScript(spell_pri_divine_hymn); @@ -1326,7 +941,6 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_mana_burn); RegisterSpellScript(spell_pri_mana_leech); RegisterSpellScript(spell_pri_mind_sear); - new spell_pri_pain_and_suffering_dummy(); RegisterSpellScript(spell_pri_pain_and_suffering_proc); RegisterSpellScript(spell_pri_penance); RegisterSpellAndAuraScriptPair(spell_pri_power_word_shield, spell_pri_power_word_shield_aura); @@ -1335,14 +949,4 @@ void AddSC_priest_spell_scripts() RegisterSpellScript(spell_pri_shadow_word_death); RegisterSpellScript(spell_pri_vampiric_touch); RegisterSpellScript(spell_pri_mind_control); - RegisterSpellScript(spell_pri_aq_3p_bonus); - RegisterSpellScript(spell_pri_body_and_soul); - RegisterSpellScript(spell_pri_glyph_of_dispel_magic); - RegisterSpellScript(spell_pri_imp_shadowform); - RegisterSpellScript(spell_pri_improved_spirit_tap); - RegisterSpellScript(spell_pri_item_t6_trinket); - RegisterSpellScript(spell_pri_shadowfiend_death); - RegisterSpellScript(spell_pri_vampiric_embrace); - RegisterSpellScript(spell_pri_t3_4p_bonus); - RegisterSpellScript(spell_pri_t5_heal_2p_bonus); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index deee9a2a61..bb6b8b9e2f 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -42,9 +42,6 @@ enum RogueSpells SPELL_ROGUE_SHIV_TRIGGERED = 5940, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628, - SPELL_ROGUE_GLYPH_OF_BACKSTAB_TRIGGER = 63975, - SPELL_ROGUE_QUICK_RECOVERY_ENERGY = 31663, - SPELL_ROGUE_CRIPPLING_POISON = 3409 }; class spell_rog_savage_combat : public AuraScript @@ -129,7 +126,7 @@ class spell_rog_blade_flurry : public AuraScript CustomSpellValues values; values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage); - values.AddSpellMod(SPELLVALUE_FORCED_CRIT_RESULT, int32(eventInfo.GetHitMask() & PROC_HIT_CRITICAL)); + values.AddSpellMod(SPELLVALUE_FORCED_CRIT_RESULT, int32(eventInfo.GetHitMask() & PROC_EX_CRITICAL_HIT)); GetTarget()->CastCustomSpell(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK, values, procTarget, TRIGGERED_FULL_MASK, nullptr, aurEff); } } @@ -641,13 +638,13 @@ class spell_rog_tricks_of_the_trade : public AuraScript return _redirectTarget; } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/) { PreventDefaultAction(); Unit* target = GetTarget(); - target->CastSpell(_redirectTarget, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST, true, nullptr, aurEff); - target->CastSpell(target, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC, true, nullptr, aurEff); + target->CastSpell(_redirectTarget, SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST, true); + target->CastSpell(target, SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC, true); Remove(AURA_REMOVE_BY_DEFAULT); // maybe handle by proc charges } @@ -678,154 +675,6 @@ class spell_rog_tricks_of_the_trade_proc : public AuraScript } }; -// -51664 - Cut to the Chase -class spell_rog_cut_to_the_chase : public AuraScript -{ - PrepareAuraScript(spell_rog_cut_to_the_chase); - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - // "refresh your Slice and Dice duration to its 5 combo point maximum" - Unit* caster = eventInfo.GetActor(); - // lookup Slice and Dice - if (AuraEffect const* snd = caster->GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x00040000, 0x00000000, 0x00000000, caster->GetGUID())) - { - // Max 5 cp duration - uint32 countMax = snd->GetSpellInfo()->GetMaxDuration(); - - snd->GetBase()->SetDuration(countMax, true); - snd->GetBase()->SetMaxDuration(snd->GetBase()->GetDuration()); - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_rog_cut_to_the_chase::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -51625 - Deadly Brew -class spell_rog_deadly_brew : public AuraScript -{ - PrepareAuraScript(spell_rog_deadly_brew); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ROGUE_CRIPPLING_POISON }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_ROGUE_CRIPPLING_POISON, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_rog_deadly_brew::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -31244 - Quick Recovery -class spell_rog_quick_recovery : public AuraScript -{ - PrepareAuraScript(spell_rog_quick_recovery); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ROGUE_QUICK_RECOVERY_ENERGY }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - Unit* caster = eventInfo.GetActor(); - int32 amount = CalculatePct(spellInfo->CalcPowerCost(caster, spellInfo->GetSchoolMask()), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_ROGUE_QUICK_RECOVERY_ENERGY, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_rog_quick_recovery::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 56800 - Glyph of Backstab (dummy) -class spell_rog_glyph_of_backstab : public AuraScript -{ - PrepareAuraScript(spell_rog_glyph_of_backstab); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_ROGUE_GLYPH_OF_BACKSTAB_TRIGGER }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_ROGUE_GLYPH_OF_BACKSTAB_TRIGGER, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_rog_glyph_of_backstab::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -13983 - Setup -class spell_rog_setup : public AuraScript -{ - PrepareAuraScript(spell_rog_setup); - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (Player* target = GetTarget()->ToPlayer()) - if (eventInfo.GetActor() == target->GetSelectedUnit()) - return true; - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_rog_setup::CheckProc); - } -}; - -// -51627 - Turn the Tables -class spell_rog_turn_the_tables : public AuraScript -{ - PrepareAuraScript(spell_rog_turn_the_tables); - - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - - Unit* caster = GetCaster(); - if (!caster) - return; - - Unit* target = GetTarget(); - target->CastSpell((Unit*)nullptr, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true, nullptr, aurEff, caster->GetGUID()); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_rog_turn_the_tables::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - void AddSC_rogue_spell_scripts() { RegisterSpellScript(spell_rog_savage_combat); @@ -841,10 +690,4 @@ void AddSC_rogue_spell_scripts() RegisterSpellScript(spell_rog_shiv); RegisterSpellScript(spell_rog_tricks_of_the_trade); RegisterSpellScript(spell_rog_tricks_of_the_trade_proc); - RegisterSpellScript(spell_rog_cut_to_the_chase); - RegisterSpellScript(spell_rog_deadly_brew); - RegisterSpellScript(spell_rog_quick_recovery); - RegisterSpellScript(spell_rog_glyph_of_backstab); - RegisterSpellScript(spell_rog_setup); - RegisterSpellScript(spell_rog_turn_the_tables); } diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 0c45006950..6977a08244 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -31,7 +31,6 @@ enum ShamanSpells { - SPELL_SHAMAN_ANCESTRAL_AWAKENING_DUMMY = 52759, SPELL_SHAMAN_GLYPH_OF_FERAL_SPIRIT = 63271, SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC = 52752, SPELL_SHAMAN_BIND_SIGHT = 6277, @@ -50,10 +49,8 @@ enum ShamanSpells SPELL_SHAMAN_ITEM_MANA_SURGE = 23571, SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480, SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694, - SPELL_SHAMAN_LIGHTNING_SHIELD_R1 = 26364, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE = 52032, SPELL_SHAMAN_MANA_TIDE_TOTEM = 39609, - SPELL_SHAMAN_NATURE_GUARDIAN = 31616, SPELL_SHAMAN_SATED = 57724, SPELL_SHAMAN_STORM_EARTH_AND_FIRE = 51483, SPELL_SHAMAN_TOTEM_EARTHBIND_EARTHGRAB = 64695, @@ -62,66 +59,13 @@ enum ShamanSpells SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042, SPELL_SHAMAN_BLESSING_OF_THE_ETERNALS_R1 = 51554, SPELL_SHAMAN_STORMSTRIKE = 17364, - SPELL_SHAMAN_LAVA_LASH = 60103, - SPELL_SHAMAN_TOTEMIC_MASTERY = 38437, - SPELL_SHAMAN_TIDAL_FORCE_CRIT = 55166, - SPELL_SHAMAN_TOTEMIC_POWER_MP5 = 28824, - SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER = 28825, - SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER = 28826, - SPELL_SHAMAN_TOTEMIC_POWER_ARMOR = 28827, - SPELL_SHAMAN_WINDFURY_WEAPON_R1 = 8232, - SPELL_SHAMAN_WINDFURY_ATTACK_MH = 25504, - SPELL_SHAMAN_WINDFURY_ATTACK_OH = 33750, - SPELL_SHAMAN_ENERGY_SURGE = 40465, - SPELL_SHAMAN_POWER_SURGE = 40466, - SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE_HEAL = 55533, - SPELL_SHAMAN_SPIRIT_HUNT_HEAL = 58879, - SPELL_SHAMAN_ELECTRIFIED = 64930, - SPELL_SHAMAN_LAVA_BURST_BONUS_DAMAGE = 71824, - SPELL_SHAMAN_CHAINED_HEAL = 70809, - SPELL_SHAMAN_TOTEM_OF_WRATH_SPELL_POWER = 63283, - SPELL_SHAMAN_FREEZE = 63685, - SPELL_SHAMAN_FLAMETONGUE_ATTACK = 10444, - SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD_R1 = 45284, - SPELL_SHAMAN_CHAIN_LIGHTNING_OVERLOAD_R1 = 45297, - SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1 = 26364, - SPELL_SHAMAN_SHAMANISTIC_RAGE_PROC = 30824, - SPELL_SHAMAN_MAELSTROM_POWER = 70831, - SPELL_SHAMAN_T10_ENHANCEMENT_4P_BONUS = 70832 + SPELL_SHAMAN_LAVA_LASH = 60103 }; enum ShamanSpellIcons { SHAMAN_ICON_ID_RESTORATIVE_TOTEMS = 338, - SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW = 3087, - SHAMAN_ICON_ID_TOTEM_OF_WRATH = 2019 -}; - -// -51556 - Ancestral Awakening -class spell_sha_ancestral_awakening : public AuraScript -{ - PrepareAuraScript(spell_sha_ancestral_awakening); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_ANCESTRAL_AWAKENING_DUMMY }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount()); - eventInfo.GetActor()->CastCustomSpell(SPELL_SHAMAN_ANCESTRAL_AWAKENING_DUMMY, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_ancestral_awakening::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } + SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW = 3087 }; class spell_sha_totem_of_wrath : public SpellScript @@ -199,30 +143,24 @@ class spell_sha_t10_restoration_4p_bonus : public AuraScript } }; -// 38443 - Totemic Mastery (Tier 6 - 2P) class spell_sha_totemic_mastery : public AuraScript { PrepareAuraScript(spell_sha_totemic_mastery); - bool Validate(SpellInfo const* /*spellInfo*/) override + void HandlePeriodic(AuraEffect const* /*aurEff*/) { - return ValidateSpellInfo({ SPELL_SHAMAN_TOTEMIC_MASTERY }); - } + PreventDefaultAction(); - void HandleDummy(AuraEffect const* aurEff) - { - Unit* target = GetTarget(); - for (uint8 i = SUMMON_TYPE_TOTEM_FIRE; i < MAX_TOTEM_SLOT; ++i) - if (!target->m_SummonSlot[i]) + for (uint8 i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i) + if (!GetTarget()->m_SummonSlot[i]) return; - target->CastSpell(target, SPELL_SHAMAN_TOTEMIC_MASTERY, aurEff); - PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), 38437, true); } void Register() override { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_totemic_mastery::HandleDummy, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_sha_totemic_mastery::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); } }; @@ -834,218 +772,6 @@ class spell_sha_flame_shock : public AuraScript } }; -// -10400 - Flametongue Weapon (Passive) -class spell_sha_flametongue_weapon : public AuraScript -{ - PrepareAuraScript(spell_sha_flametongue_weapon); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_FLAMETONGUE_ATTACK }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - Player* player = eventInfo.GetActor()->ToPlayer(); - if (!player) - return false; - - Item* item = player->GetItemByGuid(GetAura()->GetCastItemGUID()); - if (!item || !item->IsEquipped()) - return false; - - WeaponAttackType attType = static_cast<WeaponAttackType>(player->GetAttackBySlot(item->GetSlot())); - if (attType != BASE_ATTACK && attType != OFF_ATTACK) - return false; - - if (((attType == BASE_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_MAINHAND_ATTACK)) || - ((attType == OFF_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK))) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Player* player = eventInfo.GetActor()->ToPlayer(); - Unit* target = eventInfo.GetProcTarget(); - WeaponAttackType attType = BASE_ATTACK; - if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK) - attType = OFF_ATTACK; - - Item* item = ASSERT_NOTNULL(player->GetWeaponForAttack(attType)); - - float const basePoints = GetSpellInfo()->Effects[aurEff->GetEffIndex()].CalcValue(); - - // Flametongue max damage is normalized based on a 4.0 speed weapon - // Tooltip says max damage = BasePoints / 25, so BasePoints / 25 / 4 to get base damage per 1.0s AS - float fireDamage = basePoints / 100.0f; - float const attackSpeed = player->GetAttackTime(attType) / 1000.f; - fireDamage *= attackSpeed; - - // clip value between (BasePoints / 77) and (BasePoints / 25) as the tooltip indicates - RoundToInterval(fireDamage, basePoints / 77.0f, basePoints / 25.0f); - - // Calculate Spell Power scaling - float spellPowerBonus = player->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) + target->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE); - float const spCoeff = 0.03811f; - spellPowerBonus *= spCoeff * attackSpeed; - - // All done, now proc damage - int32 amount = static_cast<int32>(fireDamage + spellPowerBonus); - player->CastCustomSpell(SPELL_SHAMAN_FLAMETONGUE_ATTACK, SPELLVALUE_BASE_POINT0, amount, target, true, item, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_sha_flametongue_weapon::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_sha_flametongue_weapon::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -63373 - Frozen Power -class spell_sha_frozen_power : public AuraScript -{ - PrepareAuraScript(spell_sha_frozen_power); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_FREEZE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - if (!roll_chance_i(aurEff->GetAmount())) - return; - - Unit* caster = eventInfo.GetActor(); - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_FREEZE); - float minDistance(spellInfo->GetEffect(EFFECT_0).CalcValue(caster)); - - Unit* target = eventInfo.GetProcTarget(); - if (caster->GetDistance(target) < minDistance) - return; - - caster->CastSpell(target, SPELL_SHAMAN_FREEZE, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_frozen_power::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - -// 63279 - Glyph of Earth Shield -class spell_sha_glyph_of_earth_shield : public AuraScript -{ - PrepareAuraScript(spell_sha_glyph_of_earth_shield); - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - SpellInfo const* earthShield = eventInfo.GetSpellInfo(); - if (!earthShield) - return; - - AuraEffect* earthShieldEffect = eventInfo.GetProcTarget()->GetAuraEffect(earthShield->Id, EFFECT_0, eventInfo.GetActor()->GetGUID()); - if (!earthShieldEffect) - return; - - int32 amount = earthShieldEffect->GetAmount(); - AddPct(amount, aurEff->GetAmount()); - earthShieldEffect->SetAmount(amount); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_earth_shield::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 55440 - Glyph of Healing Wave -class spell_sha_glyph_of_healing_wave : public AuraScript -{ - PrepareAuraScript(spell_sha_glyph_of_healing_wave); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - if (caster == eventInfo.GetProcTarget()) - return; - - HealInfo* healInfo = eventInfo.GetHealInfo(); - if (!healInfo || !healInfo->GetHeal()) - return; - - int32 amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE_HEAL, SPELLVALUE_BASE_POINT0, amount, (Unit*)nullptr, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_healing_wave::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 63280 - Glyph of Totem of Wrath -class spell_sha_glyph_of_totem_of_wrath : public AuraScript -{ - PrepareAuraScript(spell_sha_glyph_of_totem_of_wrath); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_TOTEM_OF_WRATH_SPELL_POWER }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Totem of Wrath shares family flags with other totems - // filter by spellIcon instead - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo || spellInfo->SpellIconID != SHAMAN_ICON_ID_TOTEM_OF_WRATH) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - - // Fire totem summon slot - Creature* totem = ObjectAccessor::GetCreature(*caster, caster->m_SummonSlot[1]); - if (!totem) - return; - - SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(totem->m_spells[0]); - if (!totemSpell) - return; - - int32 bp0 = CalculatePct(totemSpell->Effects[EFFECT_0].CalcValue(caster), aurEff->GetAmount()); - int32 bp1 = CalculatePct(totemSpell->Effects[EFFECT_1].CalcValue(caster), aurEff->GetAmount()); - caster->CastCustomSpell((Unit*)nullptr, SPELL_SHAMAN_TOTEM_OF_WRATH_SPELL_POWER, &bp0, &bp1, nullptr, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_sha_glyph_of_totem_of_wrath::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_totem_of_wrath::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 52041, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761 - Healing Stream Totem class spell_sha_healing_stream_totem : public SpellScript { @@ -1061,7 +787,6 @@ class spell_sha_healing_stream_totem : public SpellScript int32 damage = GetEffectValue(); SpellInfo const* triggeringSpell = GetTriggeringSpell(); if (Unit* target = GetHitUnit()) - { if (Unit* caster = GetCaster()) { if (Unit* owner = caster->GetOwner()) @@ -1081,7 +806,6 @@ class spell_sha_healing_stream_totem : public SpellScript } caster->CastCustomSpell(target, SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); } - } } void Register() override @@ -1097,12 +821,13 @@ class spell_sha_heroism : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_SHAMAN_EXHAUSTION }); + return ValidateSpellInfo({ SPELL_SHAMAN_EXHAUSTION, SPELL_SHAMAN_SATED }); } void RemoveInvalidTargets(std::list<WorldObject*>& targets) { targets.remove_if(Acore::UnitAuraCheck(true, SPELL_SHAMAN_EXHAUSTION)); + targets.remove_if(Acore::UnitAuraCheck(true, SPELL_SHAMAN_SATED)); } void ApplyDebuff() @@ -1113,333 +838,14 @@ class spell_sha_heroism : public SpellScript void Register() override { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID); - + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID); AfterHit += SpellHitFn(spell_sha_heroism::ApplyDebuff); } }; -// -324 - Lightning Shield -class spell_sha_lightning_shield : public AuraScript -{ - PrepareAuraScript(spell_sha_lightning_shield); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LIGHTNING_SHIELD_R1)) - return false; - return true; - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetActionTarget()) - return true; - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - uint32 triggerSpell = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LIGHTNING_SHIELD_R1, aurEff->GetSpellInfo()->GetRank()); - - eventInfo.GetActionTarget()->CastSpell(eventInfo.GetActor(), triggerSpell, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_sha_lightning_shield::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_sha_lightning_shield::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 52031, 52033, 52034, 52035, 52036, 58778, 58779, 58780 - Mana Spring Totem -class spell_sha_mana_spring_totem : public SpellScript -{ - PrepareSpellScript(spell_sha_mana_spring_totem); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - int32 damage = GetEffectValue(); - if (Unit* target = GetHitUnit()) - if (Unit* caster = GetCaster()) - if (target->getPowerType() == POWER_MANA) - caster->CastCustomSpell(target, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_sha_mana_spring_totem::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// 39610 - Mana Tide Totem -class spell_sha_mana_tide_totem : public SpellScript -{ - PrepareSpellScript(spell_sha_mana_tide_totem); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_GLYPH_OF_MANA_TIDE, SPELL_SHAMAN_MANA_TIDE_TOTEM }); - } - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Unit* caster = GetCaster()) - if (Unit* unitTarget = GetHitUnit()) - { - if (unitTarget->getPowerType() == POWER_MANA) - { - int32 effValue = GetEffectValue(); - // Glyph of Mana Tide - if (Unit* owner = caster->GetOwner()) - if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_MANA_TIDE, 0)) - effValue += dummy->GetAmount(); - // Regenerate 6% of Total Mana Every 3 secs - int32 effBasePoints0 = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), effValue)); - caster->CastCustomSpell(unitTarget, SPELL_SHAMAN_MANA_TIDE_TOTEM, &effBasePoints0, nullptr, nullptr, true, nullptr, nullptr, GetOriginalCaster()->GetGUID()); - } - } - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_sha_mana_tide_totem::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } -}; - -// -30881 - Nature's Guardian -class spell_sha_nature_guardian : public AuraScript -{ - PrepareAuraScript(spell_sha_nature_guardian); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_NATURE_GUARDIAN)) - return false; - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - int32 healthpct = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); // %s2 - the 30% threshold for health - - if (Unit* target = eventInfo.GetActionTarget()) - { - if (target->HealthBelowPctDamaged(healthpct, eventInfo.GetDamageInfo()->GetDamage())) - { - - uint32 bp = CalculatePct(target->GetMaxHealth(), aurEff->GetAmount()); - target->CastCustomSpell(SPELL_SHAMAN_NATURE_GUARDIAN, SPELLVALUE_BASE_POINT0, bp, target, true, nullptr, aurEff); - - // @TODO: FIX ME PLEASE - // Threat reduction is around 10% confirmed in retail and from wiki -// Unit* attacker = eventInfo.GetActor(); -// if (attacker->IsAlive()) -// attacker->getThreatMgr().modifyThreatPercent(target, -10); - } - } - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_nature_guardian::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 6495 - Sentry Totem -class spell_sha_sentry_totem : public AuraScript -{ - PrepareAuraScript(spell_sha_sentry_totem); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_BIND_SIGHT }); - } - - void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Unit* caster = GetCaster()) - if (caster->GetTypeId() == TYPEID_PLAYER) - caster->ToPlayer()->StopCastingBindSight(); - } - - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } -}; - -// -51490 - Thunderstorm -class spell_sha_thunderstorm : public SpellScript -{ - PrepareSpellScript(spell_sha_thunderstorm); - - void HandleKnockBack(SpellEffIndex effIndex) - { - // Glyph of Thunderstorm - if (GetCaster()->HasAura(SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM)) - PreventHitDefaultEffect(effIndex); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_sha_thunderstorm::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); - } -}; - -// -16257 - SpellName -class spell_sha_flurry_proc : public AuraScript -{ - PrepareAuraScript(spell_sha_flurry_proc); - - bool CheckProc(ProcEventInfo& eventInfo) - { - // Should not proc from Windfury Attack, Stormstrike and Lava Lash - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - { - constexpr std::array<uint32, 2> spellIcons = {SPELL_SHAMAN_STORMSTRIKE, SPELL_SHAMAN_LAVA_LASH}; - const auto found = std::find(std::begin(spellIcons), std::end(spellIcons), spellInfo->Id); - - if ((spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellInfo->SpellFamilyFlags[0] & 0x00800000) != 0) || found != std::end(spellIcons)) - { - return false; - } - } - - return true; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_sha_flurry_proc::CheckProc); - } -}; - -class spell_sha_astral_shift_aura : public AuraScript -{ - PrepareAuraScript(spell_sha_astral_shift_aura); - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_SILENCE) | (1 << MECHANIC_STUN) | (1 << MECHANIC_FEAR))) - return true; - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_sha_astral_shift_aura::CheckProc); - } -}; - -// -16180 - Improved Water Shield -class spell_sha_imp_water_shield : public AuraScript -{ - PrepareAuraScript(spell_sha_imp_water_shield); - - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - // If we're here, we've already passed initial aura roll - // So just chance based on 100% - - // Default chance for Healing Wave and Riptide - int32 chance = 100; - // Lesser Healing Wave - 0.6 of default - if (spellInfo->SpellFamilyFlags[0] & 0x00000080) - chance = 60; - // Chain heal - 0.3 of default - else if (spellInfo->SpellFamilyFlags[0] & 0x00000100) - chance = 30; - - if (!roll_chance_i(chance)) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - // Get Water Shield - AuraEffect const* waterShield = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x00000000, 0x00000020, 0x00000000, caster->GetGUID()); - if (!waterShield) - return; - - uint32 spellId = waterShield->GetSpellInfo()->Effects[waterShield->GetEffIndex()].TriggerSpell; - caster->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_sha_imp_water_shield::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_sha_imp_water_shield::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -30675 - Lightning Overload -class spell_sha_lightning_overload : public AuraScript -{ - PrepareAuraScript(spell_sha_lightning_overload); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD_R1, - SPELL_SHAMAN_CHAIN_LIGHTNING_OVERLOAD_R1 - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - uint32 spellId; - - // Lightning Bolt - if (spellInfo->SpellFamilyFlags[0] & 0x00000001) - spellId = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LIGHTNING_BOLT_OVERLOAD_R1, spellInfo->GetRank()); - // Chain Lightning - else - { - // Chain lightning has [LightOverload_Proc_Chance] / [Max_Number_of_Targets] chance to proc of each individual target hit. - // A maxed LO would have a 33% / 3 = 11% chance to proc of each target. - // LO chance was already "accounted" at the proc chance roll, now need to divide the chance by [Max_Number_of_Targets] - float chance = 100.0f / spellInfo->GetEffect(EFFECT_0).ChainTarget; - if (!roll_chance_f(chance)) - return; - - spellId = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_CHAIN_LIGHTNING_OVERLOAD_R1, spellInfo->GetRank()); - } - - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_lightning_overload::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 23551 - Lightning Shield T2 Bonus +// 23551 - Lightning Shield class spell_sha_item_lightning_shield : public AuraScript { PrepareAuraScript(spell_sha_item_lightning_shield); @@ -1461,14 +867,14 @@ class spell_sha_item_lightning_shield : public AuraScript } }; -// 23552 - Lightning Shield T2 Bonus +// 23552 - Lightning Shield class spell_sha_item_lightning_shield_trigger : public AuraScript { PrepareAuraScript(spell_sha_item_lightning_shield_trigger); bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE }); + return ValidateSpellInfo({ SPELL_SHAMAN_ITEM_MANA_SURGE }); } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) @@ -1490,80 +896,27 @@ class spell_sha_item_mana_surge : public AuraScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_SHAMAN_ITEM_MANA_SURGE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - int32 mana = spellInfo->CalcPowerCost(GetTarget(), eventInfo.GetSchoolMask()); - int32 damage = CalculatePct(mana, 35); - - GetTarget()->CastCustomSpell(SPELL_SHAMAN_ITEM_MANA_SURGE, SPELLVALUE_BASE_POINT0, damage, GetTarget(), true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + return ValidateSpellInfo({ SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE }); } -}; - -// 40463 - Shaman Tier 6 Trinket -class spell_sha_item_t6_trinket : public AuraScript -{ - PrepareAuraScript(spell_sha_item_t6_trinket); - bool Validate(SpellInfo const* /*spellInfo*/) override + bool CheckProc(ProcEventInfo& eventInfo) { - return ValidateSpellInfo( - { - SPELL_SHAMAN_ENERGY_SURGE, - SPELL_SHAMAN_POWER_SURGE - }); + return eventInfo.GetSpellInfo() != nullptr; } void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) { PreventDefaultAction(); - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return; - - uint32 spellId; - int32 chance; - - // Lesser Healing Wave - if (spellInfo->SpellFamilyFlags[0] & 0x00000080) - { - spellId = SPELL_SHAMAN_ENERGY_SURGE; - chance = 10; - } - // Lightning Bolt - else if (spellInfo->SpellFamilyFlags[0] & 0x00000001) - { - spellId = SPELL_SHAMAN_ENERGY_SURGE; - chance = 15; - } - // Stormstrike - else if (spellInfo->SpellFamilyFlags[1] & 0x00000010) - { - spellId = SPELL_SHAMAN_POWER_SURGE; - chance = 50; - } - else - return; + int32 mana = eventInfo.GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetSchoolMask()); + int32 damage = CalculatePct(mana, 35); - if (roll_chance_i(chance)) - eventInfo.GetActor()->CastSpell((Unit*)nullptr, spellId, true, nullptr, aurEff); + GetTarget()->CastCustomSpell(SPELL_SHAMAN_ITEM_MANA_SURGE, SPELLVALUE_BASE_POINT0, damage, GetTarget(), true, nullptr, aurEff); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_item_t6_trinket::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + DoCheckProc += AuraCheckProcFn(spell_sha_item_mana_surge::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); } }; @@ -1593,7 +946,7 @@ class spell_sha_item_t10_elemental_2p_bonus : public AuraScript // 60103 - Lava Lash class spell_sha_lava_lash : public SpellScript { - PrepareSpellScript(spell_sha_lava_lash); + PrepareSpellScript(spell_sha_lava_lash) bool Load() override { @@ -1606,12 +959,11 @@ class spell_sha_lava_lash : public SpellScript { int32 damage = GetEffectValue(); int32 hitDamage = GetHitDamage(); - if (Item* offhand = caster->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) + if (caster->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) { // Damage is increased by 25% if your off-hand weapon is enchanted with Flametongue. - if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x200000, 0, 0)) - if (aurEff->GetBase()->GetCastItemGUID() == offhand->GetGUID()) - AddPct(hitDamage, damage); + if (caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x200000, 0, 0)) + AddPct(hitDamage, damage); SetHitDamage(hitDamage); } } @@ -1621,333 +973,139 @@ class spell_sha_lava_lash : public SpellScript { OnEffectHitTarget += SpellEffectFn(spell_sha_lava_lash::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); } - -}; - -// 53817 - Maelstrom Weapon -class spell_sha_maelstrom_weapon : public AuraScript -{ - PrepareAuraScript(spell_sha_maelstrom_weapon); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SHAMAN_MAELSTROM_POWER, - SPELL_SHAMAN_T10_ENHANCEMENT_4P_BONUS - }); - } - - void HandleBonus(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) - { - if (GetStackAmount() < GetSpellInfo()->StackAmount) - return; - - Unit* caster = GetUnitOwner(); - AuraEffect const* maelstrom = caster->GetAuraEffect(SPELL_SHAMAN_T10_ENHANCEMENT_4P_BONUS, EFFECT_0); - if (!maelstrom || !roll_chance_i(maelstrom->GetAmount())) - return; - - caster->CastSpell((Unit*)nullptr, SPELL_SHAMAN_MAELSTROM_POWER, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_sha_maelstrom_weapon::HandleBonus, EFFECT_0, SPELL_AURA_ADD_PCT_MODIFIER, AURA_EFFECT_HANDLE_CHANGE_AMOUNT); - } -}; - -// 30823 - Shamanistic Rage -class spell_sha_shamanistic_rage : public AuraScript -{ - PrepareAuraScript(spell_sha_shamanistic_rage); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_SHAMANISTIC_RAGE_PROC }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - PreventDefaultAction(); - - Unit* target = GetTarget(); - int32 amount = CalculatePct(static_cast<int32>(target->GetTotalAttackPowerValue(BASE_ATTACK)), aurEff->GetAmount()); - target->CastCustomSpell(SPELL_SHAMAN_SHAMANISTIC_RAGE_PROC, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_shamanistic_rage::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } }; -// 58877 - Spirit Hunt -class spell_sha_spirit_hunt : public AuraScript -{ - PrepareAuraScript(spell_sha_spirit_hunt); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SHAMAN_SPIRIT_HUNT_HEAL }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - Unit* caster = eventInfo.GetActor(); - Unit* target = caster->GetOwner(); - if (!target) - return; - - int32 amount = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_SHAMAN_SPIRIT_HUNT_HEAL, SPELLVALUE_BASE_POINT0, amount, caster, true, nullptr, aurEff); - caster->CastCustomSpell(SPELL_SHAMAN_SPIRIT_HUNT_HEAL, SPELLVALUE_BASE_POINT0, amount, target, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_sha_spirit_hunt::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// -51525 - Static Shock -class spell_sha_static_shock : public AuraScript +// 52031, 52033, 52034, 52035, 52036, 58778, 58779, 58780 - Mana Spring Totem +class spell_sha_mana_spring_totem : public SpellScript { - PrepareAuraScript(spell_sha_static_shock); + PrepareSpellScript(spell_sha_mana_spring_totem); bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1 }); + return ValidateSpellInfo({ SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE }); } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleDummy(SpellEffIndex /*effIndex*/) { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - - // Get Lightning Shield - AuraEffect const* lightningShield = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x00000400, 0x00000000, 0x00000000, caster->GetGUID()); - if (!lightningShield) - return; - - uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LIGHTNING_SHIELD_DAMAGE_R1, lightningShield->GetSpellInfo()->GetRank()); - eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), spellId, true, nullptr, aurEff); - lightningShield->GetBase()->DropCharge(); + int32 damage = GetEffectValue(); + if (Unit* target = GetHitUnit()) + if (Unit* caster = GetCaster()) + if (target->getPowerType() == POWER_MANA) + caster->CastCustomSpell(target, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID()); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_static_shock::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_sha_mana_spring_totem::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; -// 55198 - Tidal Force -class spell_sha_tidal_force_dummy : public AuraScript +// 39610 - Mana Tide Totem +class spell_sha_mana_tide_totem : public SpellScript { - PrepareAuraScript(spell_sha_tidal_force_dummy); + PrepareSpellScript(spell_sha_mana_tide_totem); bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo({ SPELL_SHAMAN_TIDAL_FORCE_CRIT }); + return ValidateSpellInfo({ SPELL_SHAMAN_GLYPH_OF_MANA_TIDE, SPELL_SHAMAN_MANA_TIDE_TOTEM }); } - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + void HandleDummy(SpellEffIndex /*effIndex*/) { - PreventDefaultAction(); - eventInfo.GetActor()->RemoveAuraFromStack(SPELL_SHAMAN_TIDAL_FORCE_CRIT); + if (Unit* caster = GetCaster()) + if (Unit* unitTarget = GetHitUnit()) + { + if (unitTarget->getPowerType() == POWER_MANA) + { + int32 effValue = GetEffectValue(); + // Glyph of Mana Tide + if (Unit* owner = caster->GetOwner()) + if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_MANA_TIDE, 0)) + effValue += dummy->GetAmount(); + // Regenerate 6% of Total Mana Every 3 secs + int32 effBasePoints0 = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), effValue)); + caster->CastCustomSpell(unitTarget, SPELL_SHAMAN_MANA_TIDE_TOTEM, &effBasePoints0, nullptr, nullptr, true, nullptr, nullptr, GetOriginalCaster()->GetGUID()); + } + } } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_tidal_force_dummy::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_sha_mana_tide_totem::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); } }; -// 28823 - Totemic Power -class spell_sha_t3_6p_bonus : public AuraScript +// 6495 - Sentry Totem +class spell_sha_sentry_totem : public AuraScript { - PrepareAuraScript(spell_sha_t3_6p_bonus); + PrepareAuraScript(spell_sha_sentry_totem); - bool Validate(SpellInfo const* /*spellInfo*/) override + bool Validate(SpellInfo const* /*spell*/) override { - return ValidateSpellInfo( - { - SPELL_SHAMAN_TOTEMIC_POWER_ARMOR, - SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER, - SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER, - SPELL_SHAMAN_TOTEMIC_POWER_MP5 - }); + return ValidateSpellInfo({ SPELL_SHAMAN_BIND_SIGHT }); } - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - PreventDefaultAction(); - - uint32 spellId; - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - - switch (target->getClass()) - { - case CLASS_PALADIN: - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_DRUID: - spellId = SPELL_SHAMAN_TOTEMIC_POWER_MP5; - break; - case CLASS_MAGE: - case CLASS_WARLOCK: - spellId = SPELL_SHAMAN_TOTEMIC_POWER_SPELL_POWER; - break; - case CLASS_HUNTER: - case CLASS_ROGUE: - spellId = SPELL_SHAMAN_TOTEMIC_POWER_ATTACK_POWER; - break; - case CLASS_WARRIOR: - spellId = SPELL_SHAMAN_TOTEMIC_POWER_ARMOR; - break; - default: - return; - } - - caster->CastSpell(target, spellId, true, nullptr, aurEff); + if (Unit* caster = GetCaster()) + if (caster->GetTypeId() == TYPEID_PLAYER) + caster->ToPlayer()->StopCastingBindSight(); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_t3_6p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); } }; -// 70817 - Item - Shaman T10 Elemental 4P Bonus -class spell_sha_t10_elemental_4p_bonus : public AuraScript +// -51490 - Thunderstorm +class spell_sha_thunderstorm : public SpellScript { - PrepareAuraScript(spell_sha_t10_elemental_4p_bonus); + PrepareSpellScript(spell_sha_thunderstorm); - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) + void HandleKnockBack(SpellEffIndex effIndex) { - PreventDefaultAction(); - - Unit* caster = eventInfo.GetActor(); - Unit* target = eventInfo.GetProcTarget(); - - // try to find spell Flame Shock on the target - AuraEffect* flameShock = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0x00000000, 0x00000000, caster->GetGUID()); - if (!flameShock) - return; - - Aura* flameShockAura = flameShock->GetBase(); - - int32 maxDuration = flameShockAura->GetMaxDuration(); - int32 newDuration = flameShockAura->GetDuration() + aurEff->GetAmount() * IN_MILLISECONDS; - - flameShockAura->SetDuration(newDuration); - // is it blizzlike to change max duration for FS? - if (newDuration > maxDuration) - flameShockAura->SetMaxDuration(newDuration); + // Glyph of Thunderstorm + if (GetCaster()->HasAura(SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM)) + PreventHitDefaultEffect(effIndex); } void Register() override { - OnEffectProc += AuraEffectProcFn(spell_sha_t10_elemental_4p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + OnEffectHitTarget += SpellEffectFn(spell_sha_thunderstorm::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); } }; -// 33757 - Windfury Weapon (Passive) -class spell_sha_windfury_weapon : public AuraScript +// -16257 - SpellName +class spell_sha_flurry_proc : public AuraScript { - PrepareAuraScript(spell_sha_windfury_weapon); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_SHAMAN_WINDFURY_WEAPON_R1, - SPELL_SHAMAN_WINDFURY_ATTACK_MH, - SPELL_SHAMAN_WINDFURY_ATTACK_OH - }); - } + PrepareAuraScript(spell_sha_flurry_proc); bool CheckProc(ProcEventInfo& eventInfo) { - Player* player = eventInfo.GetActor()->ToPlayer(); - if (!player) - return false; - - Item* item = player->GetItemByGuid(GetAura()->GetCastItemGUID()); - if (!item || !item->IsEquipped()) - return false; - - WeaponAttackType attType = static_cast<WeaponAttackType>(player->GetAttackBySlot(item->GetSlot())); - if (attType != BASE_ATTACK && attType != OFF_ATTACK) - return false; - - if (((attType == BASE_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_MAINHAND_ATTACK)) || - ((attType == OFF_ATTACK) && !(eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK))) - return false; - - return true; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Player* player = eventInfo.GetActor()->ToPlayer(); - - uint32 spellId = 0; - WeaponAttackType attType = BASE_ATTACK; - if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_MAINHAND_ATTACK) - spellId = SPELL_SHAMAN_WINDFURY_ATTACK_MH; - - if (eventInfo.GetTypeMask() & PROC_FLAG_DONE_OFFHAND_ATTACK) + // Should not proc from Windfury Attack, Stormstrike and Lava Lash + if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) { - spellId = SPELL_SHAMAN_WINDFURY_ATTACK_OH; - attType = OFF_ATTACK; - } - - Item* item = ASSERT_NOTNULL(player->GetWeaponForAttack(attType)); + constexpr std::array<uint32, 2> spellIcons = {SPELL_SHAMAN_STORMSTRIKE, SPELL_SHAMAN_LAVA_LASH}; + const auto found = std::find(std::begin(spellIcons), std::end(spellIcons), spellInfo->Id); - int32 enchantId = static_cast<int32>(item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)); - int32 extraAttackPower = 0; - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(SPELL_SHAMAN_WINDFURY_WEAPON_R1); - while (spellInfo) - { - if (spellInfo->Effects[EFFECT_0].MiscValue == enchantId) + if ((spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellInfo->SpellFamilyFlags[0] & 0x00800000) != 0) || found != std::end(spellIcons)) { - extraAttackPower = spellInfo->Effects[EFFECT_1].CalcValue(player); - break; + return false; } - spellInfo = spellInfo->GetNextRankSpell(); } - if (!extraAttackPower) - return; - - // Value gained from additional AP - int32 amount = static_cast<int32>(extraAttackPower / 14.f * player->GetAttackTime(attType) / 1000.f); - - // Attack twice - for (uint8 i = 0; i < 2; ++i) - player->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, item, aurEff); + return true; } void Register() override { - DoCheckProc += AuraCheckProcFn(spell_sha_windfury_weapon::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_sha_windfury_weapon::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + DoCheckProc += AuraCheckProcFn(spell_sha_flurry_proc::CheckProc); } }; void AddSC_shaman_spell_scripts() { - RegisterSpellScript(spell_sha_ancestral_awakening); RegisterSpellScript(spell_sha_totem_of_wrath); RegisterSpellScript(spell_sha_spirit_walk); RegisterSpellScript(spell_sha_t10_restoration_4p_bonus); @@ -1972,29 +1130,9 @@ void AddSC_shaman_spell_scripts() RegisterSpellScript(spell_sha_item_mana_surge); RegisterSpellScript(spell_sha_item_t10_elemental_2p_bonus); RegisterSpellScript(spell_sha_lava_lash); - RegisterSpellScript(spell_sha_lightning_shield); RegisterSpellScript(spell_sha_mana_spring_totem); RegisterSpellScript(spell_sha_mana_tide_totem); - RegisterSpellScript(spell_sha_nature_guardian); RegisterSpellScript(spell_sha_sentry_totem); RegisterSpellScript(spell_sha_thunderstorm); RegisterSpellScript(spell_sha_flurry_proc); - RegisterSpellScript(spell_sha_flametongue_weapon); - RegisterSpellScript(spell_sha_frozen_power); - RegisterSpellScript(spell_sha_glyph_of_earth_shield); - RegisterSpellScript(spell_sha_glyph_of_healing_wave); - RegisterSpellScript(spell_sha_glyph_of_totem_of_wrath); - RegisterSpellScript(spell_sha_healing_stream_totem); - RegisterSpellScript(spell_sha_astral_shift_aura); - RegisterSpellScript(spell_sha_imp_water_shield); - RegisterSpellScript(spell_sha_lightning_overload); - RegisterSpellScript(spell_sha_item_t6_trinket); - RegisterSpellScript(spell_sha_maelstrom_weapon); - RegisterSpellScript(spell_sha_shamanistic_rage); - RegisterSpellScript(spell_sha_spirit_hunt); - RegisterSpellScript(spell_sha_static_shock); - RegisterSpellScript(spell_sha_tidal_force_dummy); - RegisterSpellScript(spell_sha_t3_6p_bonus); - RegisterSpellScript(spell_sha_t10_elemental_4p_bonus); - RegisterSpellScript(spell_sha_windfury_weapon); } diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index a2b222b440..f23d3a2477 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -43,7 +43,6 @@ enum WarlockSpells SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444, - SPELL_WARLOCK_DEMONIC_PACT_PROC = 48090, SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, SPELL_WARLOCK_GLYPH_OF_DRAIN_SOUL_AURA = 58070, SPELL_WARLOCK_GLYPH_OF_DRAIN_SOUL_PROC = 58068, @@ -59,38 +58,17 @@ enum WarlockSpells SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956, SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553, - SPELL_WARLOCK_NETHER_PROTECTION_HOLY = 54370, - SPELL_WARLOCK_NETHER_PROTECTION_FIRE = 54371, - SPELL_WARLOCK_NETHER_PROTECTION_FROST = 54372, - SPELL_WARLOCK_NETHER_PROTECTION_ARCANE = 54373, - SPELL_WARLOCK_NETHER_PROTECTION_SHADOW = 54374, - SPELL_WARLOCK_NETHER_PROTECTION_NATURE = 54375, SPELL_WARLOCK_SOULSHATTER = 32835, SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117, SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_R1 = 18213, - SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC = 18371, - SPELL_WARLOCK_GLYPH_OF_LIFE_TAP_TRIGGERED = 63321, - SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1 = 27285, - SPELL_WARLOCK_SEED_OF_CORRUPTION_GENERIC = 32865, - SPELL_WARLOCK_SHADOW_TRANCE = 17941, - SPELL_WARLOCK_SOUL_LEECH_HEAL = 30294, - SPELL_WARLOCK_IMP_SOUL_LEECH_R1 = 54117, - SPELL_WARLOCK_SOUL_LEECH_PET_MANA_1 = 54607, - SPELL_WARLOCK_SOUL_LEECH_PET_MANA_2 = 59118, - SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_1 = 54300, - SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_2 = 59117, - SPELL_REPLENISHMENT = 57669, - SPELL_WARLOCK_SHADOWFLAME = 37378, - SPELL_WARLOCK_FLAMESHADOW = 37379, - SPELL_WARLOCK_GLYPH_OF_SUCCUBUS = 56250 + SPELL_WARLOCK_IMPROVED_DRAIN_SOUL_PROC = 18371 }; enum WarlockSpellIcons { WARLOCK_ICON_ID_IMPROVED_LIFE_TAP = 208, - WARLOCK_ICON_ID_MANA_FEED = 1982, - WARLOCK_ICON_ID_DEMONIC_PACT = 3220 + WARLOCK_ICON_ID_MANA_FEED = 1982 }; class spell_warl_eye_of_kilrogg : public AuraScript @@ -659,42 +637,6 @@ class spell_warl_everlasting_affliction : public SpellScript } }; -// 54909, 53646 - Demonic Pact -class spell_warl_demonic_pact : public AuraScript -{ - PrepareAuraScript(spell_warl_demonic_pact); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_DEMONIC_PACT_PROC }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - return eventInfo.GetActor() && eventInfo.GetActor()->IsPet(); - } - - void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - if (Unit* owner = eventInfo.GetActor()->GetOwner()) - { - if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, WARLOCK_ICON_ID_DEMONIC_PACT, EFFECT_0)) - { - int32 bp0 = static_cast<int32>((aurEff->GetAmount() * owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) + 100.0f) / 100.0f); - owner->CastCustomSpell(SPELL_WARLOCK_DEMONIC_PACT_PROC, SPELLVALUE_BASE_POINT0, bp0, (Unit*)nullptr, true, nullptr, aurEff); - } - } - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warl_demonic_pact::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warl_demonic_pact::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // 18541 - Ritual of Doom Effect class spell_warl_ritual_of_doom_effect : public SpellScript { @@ -712,92 +654,6 @@ class spell_warl_ritual_of_doom_effect : public SpellScript } }; -// -27243 - Seed of Corruption -class spell_warl_seed_of_corruption_dummy : public AuraScript -{ - PrepareAuraScript(spell_warl_seed_of_corruption_dummy); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1 }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 amount = aurEff->GetAmount() - damageInfo->GetDamage(); - if (amount > 0) - { - const_cast<AuraEffect*>(aurEff)->SetAmount(amount); - if (!GetTarget()->HealthBelowPctDamaged(1, damageInfo->GetDamage())) - return; - } - - Remove(); - - Unit* caster = GetCaster(); - if (!caster) - return; - - uint32 spellId = sSpellMgr->GetSpellWithRank(SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE_R1, GetSpellInfo()->GetRank()); - caster->CastSpell(eventInfo.GetActionTarget(), spellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_dummy::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - -// 32863 - Seed of Corruption -// 36123 - Seed of Corruption -// 38252 - Seed of Corruption -// 39367 - Seed of Corruption -// 44141 - Seed of Corruption -// 70388 - Seed of Corruption -// Monster spells, triggered only on amount drop (not on death) -class spell_warl_seed_of_corruption_generic : public AuraScript -{ - PrepareAuraScript(spell_warl_seed_of_corruption_generic); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_GENERIC }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - int32 amount = aurEff->GetAmount() - damageInfo->GetDamage(); - if (amount > 0) - { - const_cast<AuraEffect*>(aurEff)->SetAmount(amount); - return; - } - - Remove(); - - Unit* caster = GetCaster(); - if (!caster) - return; - - caster->CastSpell(eventInfo.GetActionTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_GENERIC, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_generic::HandleProc, EFFECT_1, SPELL_AURA_DUMMY); - } -}; - // -27285 - Seed of Corruption class spell_warl_seed_of_corruption : public SpellScript { @@ -828,61 +684,6 @@ class spell_warl_seed_of_corruption : public SpellScript } }; -// -30293 - Soul Leech -class spell_warl_soul_leech : public AuraScript -{ - PrepareAuraScript(spell_warl_soul_leech); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_WARLOCK_SOUL_LEECH_HEAL, - SPELL_WARLOCK_IMP_SOUL_LEECH_R1, - SPELL_WARLOCK_SOUL_LEECH_PET_MANA_1, - SPELL_WARLOCK_SOUL_LEECH_PET_MANA_2, - SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_1, - SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_2, - SPELL_REPLENISHMENT - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static uint32 const casterMana[2] = { SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_1, SPELL_WARLOCK_SOUL_LEECH_CASTER_MANA_2 }; - static uint32 const petMana[2] = { SPELL_WARLOCK_SOUL_LEECH_PET_MANA_1, SPELL_WARLOCK_SOUL_LEECH_PET_MANA_2 }; - - PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) - return; - - Unit* caster = eventInfo.GetActor(); - int32 bp = CalculatePct(static_cast<int32>(damageInfo->GetDamage()), aurEff->GetAmount()); - caster->CastCustomSpell(SPELL_WARLOCK_SOUL_LEECH_HEAL, SPELLVALUE_BASE_POINT0, bp, caster, true, nullptr, aurEff); - - // Improved Soul Leech code below - AuraEffect const* impSoulLeech = GetTarget()->GetAuraEffectOfRankedSpell(SPELL_WARLOCK_IMP_SOUL_LEECH_R1, EFFECT_1, aurEff->GetCasterGUID()); - if (!impSoulLeech) - return; - - uint8 impSoulLeechRank = impSoulLeech->GetSpellInfo()->GetRank(); - uint32 selfSpellId = casterMana[impSoulLeechRank - 1]; - uint32 petSpellId = petMana[impSoulLeechRank - 1]; - - caster->CastSpell((Unit*)nullptr, selfSpellId, true, nullptr, aurEff); - caster->CastSpell((Unit*)nullptr, petSpellId, true, nullptr, aurEff); - - if (roll_chance_i(impSoulLeech->GetAmount())) - caster->CastSpell((Unit*)nullptr, SPELL_REPLENISHMENT, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_soul_leech::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 29858 - Soulshatter class spell_warl_soulshatter : public SpellScript { @@ -1012,97 +813,6 @@ class spell_warl_life_tap : public SpellScript } }; -// -30299 - Nether Protection -class spell_warl_nether_protection : public AuraScript -{ - PrepareAuraScript(spell_warl_nether_protection); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_NETHER_PROTECTION_HOLY, SPELL_WARLOCK_NETHER_PROTECTION_FIRE, SPELL_WARLOCK_NETHER_PROTECTION_FROST, SPELL_WARLOCK_NETHER_PROTECTION_ARCANE, SPELL_WARLOCK_NETHER_PROTECTION_SHADOW, SPELL_WARLOCK_NETHER_PROTECTION_NATURE }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetDamageInfo()) - { - switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) - { - case SPELL_SCHOOL_HOLY: - case SPELL_SCHOOL_FIRE: - case SPELL_SCHOOL_NATURE: - case SPELL_SCHOOL_FROST: - case SPELL_SCHOOL_SHADOW: - case SPELL_SCHOOL_ARCANE: - return true; - default: - break; - } - } - - return false; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - uint32 triggerspell = 0; - - switch (GetFirstSchoolInMask(eventInfo.GetDamageInfo()->GetSchoolMask())) - { - case SPELL_SCHOOL_HOLY: - triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_HOLY; - break; - case SPELL_SCHOOL_FIRE: - triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_FIRE; - break; - case SPELL_SCHOOL_NATURE: - triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_NATURE; - break; - case SPELL_SCHOOL_FROST: - triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_FROST; - break; - case SPELL_SCHOOL_SHADOW: - triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_SHADOW; - break; - case SPELL_SCHOOL_ARCANE: - triggerspell = SPELL_WARLOCK_NETHER_PROTECTION_ARCANE; - break; - default: - return; - } - - if (Unit* target = eventInfo.GetActionTarget()) - target->CastSpell(target, triggerspell, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warl_nether_protection::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warl_nether_protection::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// -63156 - Decimation -class spell_warl_decimation : public AuraScript -{ - PrepareAuraScript(spell_warl_decimation); - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (SpellInfo const* spellInfo = eventInfo.GetSpellInfo()) - if (eventInfo.GetActionTarget()->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellInfo, eventInfo.GetActor())) - return true; - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warl_decimation::CheckProc); - } -}; - // 48018 - Demonic Circle: Summon class spell_warl_demonic_circle_summon : public AuraScript { @@ -1258,31 +968,6 @@ class spell_warl_haunt_aura : public AuraScript } }; -// 37377 - Shadowflame -// 39437 - Shadowflame Hellfire and RoF -template <uint32 TriggerSpellId> -class spell_warl_t4_2p_bonus : public AuraScript -{ - PrepareAuraScript(spell_warl_t4_2p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ TriggerSpellId }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, TriggerSpellId, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_t4_2p_bonus::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // -30108 - Unstable Affliction class spell_warl_unstable_affliction : public AuraScript { @@ -1413,53 +1098,6 @@ class spell_warl_shadow_ward : public AuraScript } }; -// -18094 - Nightfall -// 56218 - Glyph of Corruption -class spell_warl_glyph_of_corruption_nightfall : public AuraScript -{ - PrepareAuraScript(spell_warl_glyph_of_corruption_nightfall); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_SHADOW_TRANCE }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, SPELL_WARLOCK_SHADOW_TRANCE, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_corruption_nightfall::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - -// 63320 - Glyph of Life Tap -class spell_warl_glyph_of_life_tap : public AuraScript -{ - PrepareAuraScript(spell_warl_glyph_of_life_tap); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARLOCK_GLYPH_OF_LIFE_TAP_TRIGGERED }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, SPELL_WARLOCK_GLYPH_OF_LIFE_TAP_TRIGGERED, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_life_tap::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 63310 - Glyph of Shadowflame class spell_warl_glyph_of_shadowflame : public AuraScript { @@ -1654,7 +1292,6 @@ void AddSC_warlock_spell_scripts() RegisterSpellAndAuraScriptPair(spell_warl_haunt, spell_warl_haunt_aura); RegisterSpellScript(spell_warl_health_funnel); RegisterSpellScript(spell_warl_life_tap); - RegisterSpellScript(spell_warl_nether_protection); RegisterSpellScript(spell_warl_ritual_of_doom_effect); RegisterSpellScript(spell_warl_seed_of_corruption); RegisterSpellScript(spell_warl_shadow_ward); @@ -1662,15 +1299,6 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_soulshatter); RegisterSpellScript(spell_warl_unstable_affliction); RegisterSpellScript(spell_warl_drain_soul); - RegisterSpellScript(spell_warl_demonic_pact); - RegisterSpellScript(spell_warl_decimation); - RegisterSpellScript(spell_warl_seed_of_corruption_dummy); - RegisterSpellScript(spell_warl_seed_of_corruption_generic); - RegisterSpellScript(spell_warl_soul_leech); - RegisterSpellScriptWithArgs(spell_warl_t4_2p_bonus<SPELL_WARLOCK_FLAMESHADOW>, "spell_warl_t4_2p_bonus_shadow"); - RegisterSpellScriptWithArgs(spell_warl_t4_2p_bonus<SPELL_WARLOCK_SHADOWFLAME>, "spell_warl_t4_2p_bonus_fire"); - RegisterSpellScript(spell_warl_glyph_of_corruption_nightfall); - RegisterSpellScript(spell_warl_glyph_of_life_tap); RegisterSpellScript(spell_warl_shadowburn); RegisterSpellScript(spell_warl_glyph_of_felguard); } diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index d91904236b..77108ca9af 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -35,7 +35,6 @@ enum WarriorSpells SPELL_WARRIOR_IMPROVED_SPELL_REFLECTION_TRIGGER = 59725, SPELL_WARRIOR_BLOODTHIRST = 23885, SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881, - SPELL_WARRIOR_BLOODSURGE_R1 = 29723, SPELL_WARRIOR_CHARGE = 34846, SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653, SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162, @@ -43,8 +42,6 @@ enum WarriorSpells SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC = 12721, SPELL_WARRIOR_EXECUTE = 20647, - SPELL_WARRIOR_EXECUTE_GCD_REDUCED = 71069, - SPELL_WARRIOR_EXTRA_CHARGE = 70849, SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367, SPELL_WARRIOR_GLYPH_OF_VIGILANCE = 63326, SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156, @@ -52,8 +49,6 @@ enum WarriorSpells SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976, SPELL_WARRIOR_RETALIATION_DAMAGE = 22858, SPELL_WARRIOR_SLAM = 50783, - SPELL_WARRIOR_SLAM_GCD_REDUCED = 71072, - SPELL_WARRIOR_SUDDEN_DEATH_R1 = 46913, SPELL_WARRIOR_SUNDER_ARMOR = 58567, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1 = 12723, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2 = 26654, @@ -64,11 +59,6 @@ enum WarriorSpells SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2 = 64850, SPELL_WARRIOR_VIGILANCE_PROC = 50725, SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT = 59665, - SPELL_WARRIOR_SECOND_WIND_TRIGGER_1 = 29841, - SPELL_WARRIOR_SECOND_WIND_TRIGGER_2 = 29842, - SPELL_WARRIOR_GLYPH_OF_BLOCKING = 58374, - SPELL_WARRIOR_STOICISM = 70845, - SPELL_WARRIOR_T10_MELEE_4P_BONUS = 70847, SPELL_WARRIOR_WHIRLWIND_OFF = 44949 }; @@ -83,7 +73,6 @@ enum MiscSpells SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY = 25899, SPELL_PRIEST_RENEWED_HOPE = 63944, SPELL_GEN_DAMAGE_REDUCTION_AURA = 68066, - SPELL_CATEGORY_SHIELD_SLAM = 1209 }; class spell_warr_mocking_blow : public SpellScript @@ -173,7 +162,7 @@ class spell_warr_improved_spell_reflection : public AuraScript CustomSpellValues values; values.AddSpellMod(SPELLVALUE_MAX_TARGETS, aurEff->GetAmount()); values.AddSpellMod(SPELLVALUE_RADIUS_MOD, 2000); // Base range = 100, final range = 20 value / 10000.0f = 0.2f - eventInfo.GetActor()->CastCustomSpell(SPELL_WARRIOR_IMPROVED_SPELL_REFLECTION_TRIGGER, values, eventInfo.GetActor(), TRIGGERED_FULL_MASK, nullptr, aurEff); + eventInfo.GetActor()->CastCustomSpell(SPELL_WARRIOR_IMPROVED_SPELL_REFLECTION_TRIGGER, values, eventInfo.GetActor(), TRIGGERED_FULL_MASK, nullptr); } void Register() override @@ -235,31 +224,6 @@ class spell_warr_improved_spell_reflection_trigger_aura : public AuraScript } }; -// 70844 - Item - Warrior T10 Protection 4P Bonus -class spell_warr_item_t10_prot_4p_bonus : public AuraScript -{ - PrepareAuraScript(spell_warr_item_t10_prot_4p_bonus); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARRIOR_STOICISM }); - } - - void HandleProc(ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* target = eventInfo.GetActionTarget(); - int32 bp0 = CalculatePct(target->GetMaxHealth(), GetSpellInfo()->Effects[EFFECT_1].CalcValue()); - target->CastCustomSpell(SPELL_WARRIOR_STOICISM, SPELLVALUE_BASE_POINT0, bp0, (Unit*)nullptr, true); - } - - void Register() override - { - OnProc += AuraProcFn(spell_warr_item_t10_prot_4p_bonus::HandleProc); - } -}; - // 12975 - Last Stand class spell_warr_last_stand : public SpellScript { @@ -290,13 +254,7 @@ class spell_warr_deep_wounds : public SpellScript bool Validate(SpellInfo const* /*spellInfo*/) override { - return ValidateSpellInfo( - { - SPELL_WARRIOR_DEEP_WOUNDS_RANK_1, - SPELL_WARRIOR_DEEP_WOUNDS_RANK_2, - SPELL_WARRIOR_DEEP_WOUNDS_RANK_3, - SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC - }); + return ValidateSpellInfo({ SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC }); } void HandleDummy(SpellEffIndex /*effIndex*/) @@ -311,7 +269,7 @@ class spell_warr_deep_wounds : public SpellScript ApplyPct(damage, 16.0f * GetSpellInfo()->GetRank() / 6.0f); target->CastDelayedSpellWithPeriodicAmount(caster, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, SPELL_AURA_PERIODIC_DAMAGE, damage, EFFECT_0); - caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, &damage, nullptr, nullptr, true); + //caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC, &damage, nullptr, nullptr, true); } } @@ -415,47 +373,6 @@ class spell_warr_damage_shield : public AuraScript } }; -// -12834 - Deep Wounds Aura -class spell_warr_deep_wounds_aura : public AuraScript -{ - PrepareAuraScript(spell_warr_deep_wounds_aura); - - bool Validate(SpellInfo const* spellInfo) override - { - return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo) - return false; - - return eventInfo.GetActor()->GetTypeId() == TYPEID_PLAYER; - } - - void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - - Unit* actor = eventInfo.GetActor(); - float damage = 0.f; - - if (eventInfo.GetDamageInfo()->GetAttackType() == OFF_ATTACK) - damage = (actor->GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + actor->GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)) / 2.f; - else - damage = (actor->GetFloatValue(UNIT_FIELD_MINDAMAGE) + actor->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2.f; - - actor->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, SPELLVALUE_BASE_POINT0, int32(damage), eventInfo.GetProcTarget(), true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warr_deep_wounds_aura::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warr_deep_wounds_aura::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - // -5308 - Execute class spell_warr_execute : public SpellScript { @@ -513,71 +430,6 @@ class spell_warr_execute : public SpellScript } }; -// -29723 - Sudden Death -// -46913 - Bloodsurge -class spell_warr_extra_proc : public AuraScript -{ - PrepareAuraScript(spell_warr_extra_proc); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_WARRIOR_T10_MELEE_4P_BONUS, - SPELL_WARRIOR_EXTRA_CHARGE, - SPELL_WARRIOR_SLAM_GCD_REDUCED, - SPELL_WARRIOR_EXECUTE_GCD_REDUCED - }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) - { - Unit* target = GetTarget(); - AuraEffect const* bonusAurEff = target->GetAuraEffect(SPELL_WARRIOR_T10_MELEE_4P_BONUS, EFFECT_0); - if (!bonusAurEff) - return; - - if (!roll_chance_i(bonusAurEff->GetAmount())) - return; - - target->CastSpell((Unit*)nullptr, SPELL_WARRIOR_EXTRA_CHARGE, true, nullptr, aurEff); - - SpellInfo const* auraInfo = aurEff->GetSpellInfo(); - if (auraInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_BLOODSURGE_R1))) - target->CastSpell((Unit*)nullptr, SPELL_WARRIOR_SLAM_GCD_REDUCED, true, nullptr, aurEff); - else if (auraInfo->IsRankOf(sSpellMgr->AssertSpellInfo(SPELL_WARRIOR_SUDDEN_DEATH_R1))) - target->CastSpell((Unit*)nullptr, SPELL_WARRIOR_EXECUTE_GCD_REDUCED, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warr_extra_proc::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); - } -}; - -// 58375 - Glyph of Blocking -class spell_warr_glyph_of_blocking : public AuraScript -{ - PrepareAuraScript(spell_warr_glyph_of_blocking); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_WARRIOR_GLYPH_OF_BLOCKING }); - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - PreventDefaultAction(); - Unit* caster = eventInfo.GetActor(); - caster->CastSpell(caster, SPELL_WARRIOR_GLYPH_OF_BLOCKING, true, nullptr, aurEff); - } - - void Register() override - { - OnEffectProc += AuraEffectProcFn(spell_warr_glyph_of_blocking::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 12809 - Concussion Blow class spell_warr_concussion_blow : public SpellScript { @@ -736,46 +588,6 @@ class spell_warr_rend : public AuraScript } }; -// -29834 - Second Wind -class spell_warr_second_wind : public AuraScript -{ - PrepareAuraScript(spell_warr_second_wind); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo( - { - SPELL_WARRIOR_SECOND_WIND_TRIGGER_1, - SPELL_WARRIOR_SECOND_WIND_TRIGGER_2 - }); - } - - bool CheckProc(ProcEventInfo& eventInfo) - { - SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); - if (!spellInfo) - return false; - - return (spellInfo->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN))) != 0; - } - - void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo) - { - static uint32 const triggeredSpells[2] = { SPELL_WARRIOR_SECOND_WIND_TRIGGER_1, SPELL_WARRIOR_SECOND_WIND_TRIGGER_2 }; - - PreventDefaultAction(); - Unit* caster = eventInfo.GetActionTarget(); - uint32 spellId = triggeredSpells[GetSpellInfo()->GetRank() - 1]; - caster->CastSpell(caster, spellId, true, nullptr, aurEff); - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warr_second_wind::CheckProc); - OnEffectProc += AuraEffectProcFn(spell_warr_second_wind::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); - } -}; - // 64380, 65941 - Shattering Throw class spell_warr_shattering_throw : public SpellScript { @@ -846,7 +658,7 @@ class spell_warr_sweeping_strikes : public AuraScript if (spellInfo && spellInfo->Id == SPELL_WARRIOR_EXECUTE && !_procTarget->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT)) { // If triggered by Execute (while target is not under 20% hp) deals normalized weapon damage - GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, true, nullptr, aurEff); + GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, aurEff); } else { @@ -866,30 +678,6 @@ private: Unit* _procTarget = nullptr; }; -// 28845 - Cheat Death -class spell_warr_t3_prot_8p_bonus : public AuraScript -{ - PrepareAuraScript(spell_warr_t3_prot_8p_bonus); - - bool CheckProc(ProcEventInfo& eventInfo) - { - if (eventInfo.GetActionTarget()->HealthBelowPct(20)) - return true; - - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (damageInfo && damageInfo->GetDamage()) - if (GetTarget()->HealthBelowPctDamaged(20, damageInfo->GetDamage())) - return true; - - return false; - } - - void Register() override - { - DoCheckProc += AuraCheckProcFn(spell_warr_t3_prot_8p_bonus::CheckProc); - } -}; - // 50720 - Vigilance class spell_warr_vigilance : public AuraScript { @@ -1024,6 +812,38 @@ class spell_warr_glyph_of_sunder_armor : public AuraScript } }; +// Spell 28845 - Cheat Death + +enum CheatDeath +{ + SPELL_CHEAT_DEATH_TRIGGER = 28846 +}; + +class spell_warr_t3_prot_8p_bonus : public AuraScript +{ + PrepareAuraScript(spell_warr_t3_prot_8p_bonus); + + bool CheckProc(ProcEventInfo& eventInfo) + { + return eventInfo.GetActionTarget() && eventInfo.GetActionTarget()->GetHealthPct() <= 20.0f; + } + + void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + if (Unit* target = eventInfo.GetActionTarget()) + { + target->CastSpell(target, SPELL_CHEAT_DEATH_TRIGGER, true); + } + } + + void Register() override + { + DoCheckProc += AuraCheckProcFn(spell_warr_t3_prot_8p_bonus::CheckProc); + OnEffectProc += AuraEffectProcFn(spell_warr_t3_prot_8p_bonus::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } +}; + // 20230 - Retaliation class spell_warr_retaliation : public AuraScript { @@ -1084,10 +904,4 @@ void AddSC_warrior_spell_scripts() RegisterSpellScript(spell_warr_vigilance); RegisterSpellScript(spell_warr_vigilance_trigger); RegisterSpellScript(spell_warr_t3_prot_8p_bonus); - RegisterSpellScript(spell_warr_item_t10_prot_4p_bonus); - RegisterSpellScript(spell_warr_deep_wounds_aura); - RegisterSpellScript(spell_warr_extra_proc); - RegisterSpellScript(spell_warr_glyph_of_blocking); - RegisterSpellScript(spell_warr_second_wind); - RegisterSpellScript(spell_warr_t3_prot_8p_bonus); } diff --git a/src/server/shared/DataStores/DBCStructure.h b/src/server/shared/DataStores/DBCStructure.h index fd173dd184..38f0d6405d 100644 --- a/src/server/shared/DataStores/DBCStructure.h +++ b/src/server/shared/DataStores/DBCStructure.h @@ -1676,7 +1676,7 @@ struct SpellEntry std::array<uint32, 2> SpellVisual; // 131-132 m_spellVisualID uint32 SpellIconID; // 133 m_spellIconID uint32 ActiveIconID; // 134 m_activeIconID - uint32 SpellPriority; // 135 + uint32 SpellPriority; // 135 not used std::array<char const*, 16> SpellName; // 136-151 m_name_lang //uint32 SpellNameFlag; // 152 not used std::array<char const*, 16> Rank; // 153-168 m_nameSubtext_lang diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 737338ae4e..584e0c3f85 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -455,7 +455,7 @@ enum SpellAttr2 : uint32 SPELL_ATTR2_IGNORE_WEAPONSKILL = 0x08000000, // TITLE Unknown attribute 27@Attr2 SPELL_ATTR2_NOT_AN_ACTION = 0x10000000, // TITLE Unknown attribute 28@Attr2 SPELL_ATTR2_CANT_CRIT = 0x20000000, // TITLE Cannot critically strike - SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC = 0x40000000, // TITLE Allow triggered spell to trigger (type 1) DESCRIPTION Without this attribute, any triggered spell will be unable to trigger other auras' procs + SPELL_ATTR2_ACTIVE_THREAT = 0x40000000, // TITLE Allow triggered spell to trigger (type 1) DESCRIPTION Without this attribute, any triggered spell will be unable to trigger other auras' procs SPELL_ATTR2_RETAIN_ITEM_CAST = 0x80000000 // TITLE Food buff (client only) }; @@ -471,7 +471,7 @@ enum SpellAttr3 : uint32 SPELL_ATTR3_NO_AVOIDANCE = 0x00000040, // TITLE Unknown attribute 6@Attr3 SPELL_ATTR3_DOT_STACKING_RULE = 0x00000080, // TITLE Stack separately for each caster SPELL_ATTR3_ONLY_ON_PLAYER = 0x00000100, // TITLE Can only target players - SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2 = 0x00000200, // TITLE Allow triggered spell to trigger (type 2) DESCRIPTION Without this attribute, any triggered spell will be unable to trigger other auras' procs + SPELL_ATTR3_NOT_A_PROC = 0x00000200, // TITLE Allow triggered spell to trigger (type 2) DESCRIPTION Without this attribute, any triggered spell will be unable to trigger other auras' procs SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON = 0x00000400, // TITLE Require main hand weapon SPELL_ATTR3_ONLY_BATTLEGROUNDS = 0x00000800, // TITLE Can only be cast in battleground SPELL_ATTR3_ONLY_ON_GHOSTS = 0x00001000, // TITLE Can only target ghost players @@ -481,14 +481,14 @@ enum SpellAttr3 : uint32 SPELL_ATTR3_SUPRESS_CASTER_PROCS = 0x00010000, // TITLE Cannot trigger procs SPELL_ATTR3_SUPRESS_TARGET_PROCS = 0x00020000, // TITLE No initial aggro SPELL_ATTR3_ALWAYS_HIT = 0x00040000, // TITLE Ignore hit result DESCRIPTION Spell cannot miss, or be dodged/parried/blocked - SPELL_ATTR3_DISABLE_PROC = 0x00080000, // TITLE Cannot trigger spells during aura proc + SPELL_ATTR3_INSTANT_TARGET_PROCS = 0x00080000, // TITLE Cannot trigger spells during aura proc SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD = 0x00100000, // TITLE Persists through death SPELL_ATTR3_ONLY_PROC_OUTDOORS = 0x00200000, // TITLE Unknown attribute 21@Attr3 SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT = 0x00400000, // TITLE Requires equipped Wand (Mainline: Do Not Trigger Target Stand) SPELL_ATTR3_NO_DAMAGE_HISTORY = 0x00800000, // TITLE Unknown attribute 23@Attr3 SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON = 0x01000000, // TITLE Requires offhand weapon SPELL_ATTR3_TREAT_AS_PERIODIC = 0x02000000, // TITLE Treat as periodic effect - SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED = 0x04000000, // TITLE Can trigger from triggered spells + SPELL_ATTR3_CAN_PROC_FROM_PROCS = 0x04000000, // TITLE Can trigger from triggered spells SPELL_ATTR3_ONLY_PROC_ON_CASTER = 0x08000000, // TITLE Drain Soul SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS = 0x10000000, // TITLE Unknown attribute 28@Attr3 SPELL_ATTR3_IGNORE_CASTER_MODIFIERS = 0x20000000, // TITLE Damage dealt is unaffected by modifiers @@ -3225,7 +3225,7 @@ enum DiminishingReturnsType }; // Diminishing Return Groups -enum DiminishingGroup : uint16 +enum DiminishingGroup { DIMINISHING_NONE = 0, DIMINISHING_BANISH = 1, diff --git a/src/server/shared/enuminfo_SharedDefines.cpp b/src/server/shared/enuminfo_SharedDefines.cpp index 23c16f9b87..7514378619 100644 --- a/src/server/shared/enuminfo_SharedDefines.cpp +++ b/src/server/shared/enuminfo_SharedDefines.cpp @@ -445,7 +445,7 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr2>::ToString(SpellAttr2 value) case SPELL_ATTR2_IGNORE_WEAPONSKILL: return { "SPELL_ATTR2_IGNORE_WEAPONSKILL", "Unknown attribute 27@Attr2", "" }; case SPELL_ATTR2_NOT_AN_ACTION: return { "SPELL_ATTR2_NOT_AN_ACTION", "Unknown attribute 28@Attr2", "" }; case SPELL_ATTR2_CANT_CRIT: return { "SPELL_ATTR2_CANT_CRIT", "Cannot critically strike", "" }; - case SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC: return { "SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC", "Allow triggered spell to trigger (type 1)", "Without this attribute, any triggered spell will be unable to trigger other auras' procs" }; + case SPELL_ATTR2_ACTIVE_THREAT: return { "SPELL_ATTR2_ACTIVE_THREAT", "Allow triggered spell to trigger (type 1)", "Without this attribute, any triggered spell will be unable to trigger other auras' procs" }; case SPELL_ATTR2_RETAIN_ITEM_CAST: return { "SPELL_ATTR2_RETAIN_ITEM_CAST", "Food buff (client only)", "" }; default: throw std::out_of_range("value"); } @@ -489,7 +489,7 @@ AC_API_EXPORT SpellAttr2 EnumUtils<SpellAttr2>::FromIndex(size_t index) case 27: return SPELL_ATTR2_IGNORE_WEAPONSKILL; case 28: return SPELL_ATTR2_NOT_AN_ACTION; case 29: return SPELL_ATTR2_CANT_CRIT; - case 30: return SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC; + case 30: return SPELL_ATTR2_ACTIVE_THREAT; case 31: return SPELL_ATTR2_RETAIN_ITEM_CAST; default: throw std::out_of_range("index"); } @@ -530,7 +530,7 @@ AC_API_EXPORT size_t EnumUtils<SpellAttr2>::ToIndex(SpellAttr2 value) case SPELL_ATTR2_IGNORE_WEAPONSKILL: return 27; case SPELL_ATTR2_NOT_AN_ACTION: return 28; case SPELL_ATTR2_CANT_CRIT: return 29; - case SPELL_ATTR2_TRIGGERED_CAN_TRIGGER_PROC: return 30; + case SPELL_ATTR2_ACTIVE_THREAT: return 30; case SPELL_ATTR2_RETAIN_ITEM_CAST: return 31; default: throw std::out_of_range("value"); } @@ -553,7 +553,7 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr3>::ToString(SpellAttr3 value) case SPELL_ATTR3_NO_AVOIDANCE: return { "SPELL_ATTR3_NO_AVOIDANCE", "Unknown attribute 6@Attr3", "" }; case SPELL_ATTR3_DOT_STACKING_RULE: return { "SPELL_ATTR3_DOT_STACKING_RULE", "Stack separately for each caster", "" }; case SPELL_ATTR3_ONLY_ON_PLAYER: return { "SPELL_ATTR3_ONLY_ON_PLAYER", "Can only target players", "" }; - case SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2: return { "SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2", "Allow triggered spell to trigger (type 2)", "Without this attribute, any triggered spell will be unable to trigger other auras' procs" }; + case SPELL_ATTR3_NOT_A_PROC: return { "SPELL_ATTR3_NOT_A_PROC", "Allow triggered spell to trigger (type 2)", "Without this attribute, any triggered spell will be unable to trigger other auras' procs" }; case SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON: return { "SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON", "Require main hand weapon", "" }; case SPELL_ATTR3_ONLY_BATTLEGROUNDS: return { "SPELL_ATTR3_ONLY_BATTLEGROUNDS", "Can only be cast in battleground", "" }; case SPELL_ATTR3_ONLY_ON_GHOSTS: return { "SPELL_ATTR3_ONLY_ON_GHOSTS", "Can only target ghost players", "" }; @@ -563,14 +563,14 @@ AC_API_EXPORT EnumText EnumUtils<SpellAttr3>::ToString(SpellAttr3 value) case SPELL_ATTR3_SUPRESS_CASTER_PROCS: return { "SPELL_ATTR3_SUPRESS_CASTER_PROCS", "Cannot trigger procs", "" }; case SPELL_ATTR3_SUPRESS_TARGET_PROCS: return { "SPELL_ATTR3_SUPRESS_TARGET_PROCS", "No initial aggro", "" }; case SPELL_ATTR3_ALWAYS_HIT: return { "SPELL_ATTR3_ALWAYS_HIT", "Ignore hit result", "Spell cannot miss, or be dodged/parried/blocked" }; - case SPELL_ATTR3_DISABLE_PROC: return { "SPELL_ATTR3_DISABLE_PROC", "Cannot trigger spells during aura proc", "" }; + case SPELL_ATTR3_INSTANT_TARGET_PROCS: return { "SPELL_ATTR3_INSTANT_TARGET_PROCS", "Cannot trigger spells during aura proc", "" }; case SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD: return { "SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD", "Persists through death", "" }; case SPELL_ATTR3_ONLY_PROC_OUTDOORS: return { "SPELL_ATTR3_ONLY_PROC_OUTDOORS", "Unknown attribute 21@Attr3", "" }; case SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT: return { "SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT", "Requires equipped Wand (Mainline: Do Not Trigger Target Stand)", "" }; case SPELL_ATTR3_NO_DAMAGE_HISTORY: return { "SPELL_ATTR3_NO_DAMAGE_HISTORY", "Unknown attribute 23@Attr3", "" }; case SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON: return { "SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON", "Requires offhand weapon", "" }; case SPELL_ATTR3_TREAT_AS_PERIODIC: return { "SPELL_ATTR3_TREAT_AS_PERIODIC", "Treat as periodic effect", "" }; - case SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED: return { "SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED", "Can trigger from triggered spells", "" }; + case SPELL_ATTR3_CAN_PROC_FROM_PROCS: return { "SPELL_ATTR3_CAN_PROC_FROM_PROCS", "Can trigger from triggered spells", "" }; case SPELL_ATTR3_ONLY_PROC_ON_CASTER: return { "SPELL_ATTR3_ONLY_PROC_ON_CASTER", "Drain Soul", "" }; case SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS: return { "SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS", "Unknown attribute 28@Attr3", "" }; case SPELL_ATTR3_IGNORE_CASTER_MODIFIERS: return { "SPELL_ATTR3_IGNORE_CASTER_MODIFIERS", "Damage dealt is unaffected by modifiers", "" }; @@ -597,7 +597,7 @@ AC_API_EXPORT SpellAttr3 EnumUtils<SpellAttr3>::FromIndex(size_t index) case 6: return SPELL_ATTR3_NO_AVOIDANCE; case 7: return SPELL_ATTR3_DOT_STACKING_RULE; case 8: return SPELL_ATTR3_ONLY_ON_PLAYER; - case 9: return SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2; + case 9: return SPELL_ATTR3_NOT_A_PROC; case 10: return SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON; case 11: return SPELL_ATTR3_ONLY_BATTLEGROUNDS; case 12: return SPELL_ATTR3_ONLY_ON_GHOSTS; @@ -607,14 +607,14 @@ AC_API_EXPORT SpellAttr3 EnumUtils<SpellAttr3>::FromIndex(size_t index) case 16: return SPELL_ATTR3_SUPRESS_CASTER_PROCS; case 17: return SPELL_ATTR3_SUPRESS_TARGET_PROCS; case 18: return SPELL_ATTR3_ALWAYS_HIT; - case 19: return SPELL_ATTR3_DISABLE_PROC; + case 19: return SPELL_ATTR3_INSTANT_TARGET_PROCS; case 20: return SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD; case 21: return SPELL_ATTR3_ONLY_PROC_OUTDOORS; case 22: return SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT; case 23: return SPELL_ATTR3_NO_DAMAGE_HISTORY; case 24: return SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON; case 25: return SPELL_ATTR3_TREAT_AS_PERIODIC; - case 26: return SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED; + case 26: return SPELL_ATTR3_CAN_PROC_FROM_PROCS; case 27: return SPELL_ATTR3_ONLY_PROC_ON_CASTER; case 28: return SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS; case 29: return SPELL_ATTR3_IGNORE_CASTER_MODIFIERS; @@ -638,7 +638,7 @@ AC_API_EXPORT size_t EnumUtils<SpellAttr3>::ToIndex(SpellAttr3 value) case SPELL_ATTR3_NO_AVOIDANCE: return 6; case SPELL_ATTR3_DOT_STACKING_RULE: return 7; case SPELL_ATTR3_ONLY_ON_PLAYER: return 8; - case SPELL_ATTR3_TRIGGERED_CAN_TRIGGER_PROC_2: return 9; + case SPELL_ATTR3_NOT_A_PROC: return 9; case SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON: return 10; case SPELL_ATTR3_ONLY_BATTLEGROUNDS: return 11; case SPELL_ATTR3_ONLY_ON_GHOSTS: return 12; @@ -648,14 +648,14 @@ AC_API_EXPORT size_t EnumUtils<SpellAttr3>::ToIndex(SpellAttr3 value) case SPELL_ATTR3_SUPRESS_CASTER_PROCS: return 16; case SPELL_ATTR3_SUPRESS_TARGET_PROCS: return 17; case SPELL_ATTR3_ALWAYS_HIT: return 18; - case SPELL_ATTR3_DISABLE_PROC: return 19; + case SPELL_ATTR3_INSTANT_TARGET_PROCS: return 19; case SPELL_ATTR3_ALLOW_AURA_WHILE_DEAD: return 20; case SPELL_ATTR3_ONLY_PROC_OUTDOORS: return 21; case SPELL_ATTR3_CASTING_CANCELS_AUTOREPEAT: return 22; case SPELL_ATTR3_NO_DAMAGE_HISTORY: return 23; case SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON: return 24; case SPELL_ATTR3_TREAT_AS_PERIODIC: return 25; - case SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED: return 26; + case SPELL_ATTR3_CAN_PROC_FROM_PROCS: return 26; case SPELL_ATTR3_ONLY_PROC_ON_CASTER: return 27; case SPELL_ATTR3_IGNORE_CASTER_AND_TARGET_RESTRICTIONS: return 28; case SPELL_ATTR3_IGNORE_CASTER_MODIFIERS: return 29; |