diff --git a/sql/mangos.sql b/sql/mangos.sql index c7ce487fc..9468feb9d 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8965_02_mangos_command` bit(1) default NULL + `required_8996_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -14174,6 +14174,7 @@ INSERT INTO `spell_bonus_data` VALUES (30294, 0, 0, 0, 'Warlock - Soul Leech'), (31117, 1.8, 0, 0, 'Warlock - Unstable Affliction Dispell'), /* Item */ +(56160, 0, 0, 0, 'Item - Glyph of Power Word: Shield'), (40293, 0, 0, 0, 'Item - Siphon Essence'); /*!40000 ALTER TABLE `spell_bonus_data` ENABLE KEYS */; UNLOCK TABLES; @@ -14633,6 +14634,10 @@ INSERT INTO spell_chain VALUES (27067,20910,19306,4,0), (48998,27067,19306,5,0), (48999,48998,19306,6,0), +/*Entrapment*/ +(19184,0,19184,1,0), +(19387,19184,19184,2,0), +(19388,19387,19184,3,0), /*ExplosiveShot*/ (53301,0,53301,1,0), (60051,53301,53301,2,0), @@ -14649,6 +14654,10 @@ INSERT INTO spell_chain VALUES (1499,0,1499,1,0), (14310,1499,1499,2,0), (14311,14310,1499,3,0), +/*Hunting Party*/ +(53290,0,53290,1,0), +(53291,53290,53290,2,0), +(53292,53291,53290,3,0), /*ImmolationTrap*/ (13795,0,13795,1,0), (14302,13795,13795,2,0), @@ -14658,6 +14667,12 @@ INSERT INTO spell_chain VALUES (27023,14305,13795,6,0), (49055,27023,13795,7,0), (49056,49055,13795,8,0), +/**Master Tactician*/ +(34506,0,34506,1,0), +(34507,34506,34506,2,0), +(34508,34507,34506,3,0), +(34838,34508,34506,4,0), +(34839,34838,34506,5,0), /*MongooseBite*/ (1495,0,1495,1,0), (14269,1495,1495,2,0), @@ -15088,7 +15103,7 @@ INSERT INTO spell_chain VALUES /*------------------ --(163)Marksmanship ------------------*/ -/*AimedShot*/ +/*Aimed Shot*/ (19434,0,19434,1,0), (20900,19434,19434,2,0), (20901,20900,19434,3,0), @@ -15098,7 +15113,7 @@ INSERT INTO spell_chain VALUES (27065,20904,19434,7,0), (49049,27065,19434,8,0), (49050,49049,19434,9,0), -/*ArcaneShot*/ +/*Arcane Shot*/ (3044,0,3044,1,0), (14281,3044,3044,2,0), (14282,14281,3044,3,0), @@ -15110,13 +15125,16 @@ INSERT INTO spell_chain VALUES (27019,14287,3044,9,0), (49044,27019,3044,10,0), (49045,49044,3044,11,0), -/*Hunter'sMark*/ +/*Concussive Barrage*/ +(35100,0,35100,1,0), +(35102,35100,35100,2,0), +/*Hunter's Mark*/ (1130,0,1130,1,0), (14323,1130,1130,2,0), (14324,14323,1130,3,0), (14325,14324,1130,4,0), (53338,14325,1130,5,0), -/*KillShot*/ +/*Kill Shot*/ (53351,0,53351,1,0), (61005,53351,53351,2,0), (61006,61005,53351,3,0), @@ -15771,6 +15789,10 @@ INSERT INTO spell_chain VALUES (25289,11551,6673,7,0), (2048,25289,6673,8,0), (47436,2048,6673,9,0), +/*Bloodsurge*/ +(46913,0,46913,1,0), +(46914,46913,46913,2,0), +(46915,46914,46913,3,0), /*Cleave*/ (845,0,845,1,0), (7369,845,845,2,0), @@ -16208,6 +16230,9 @@ INSERT INTO spell_chain VALUES /*Frozen Power*/ (63373,0,63373,1,0), (63374,63373,63373,2,0), +/*Improved Stormstrike*/ +(51521,0,51521,1,0), +(51522,51521,51521,2,0), /*Life Tap*/ (1454,0,1454,1,0), (1455,1454,1454,2,0), @@ -17836,9 +17861,7 @@ INSERT INTO `spell_proc_event` VALUES (18119, 0x00000000, 5, 0x00000000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (18120, 0x00000000, 5, 0x00000000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (18820, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(19184, 0x00000000, 9, 0x00000014, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(19387, 0x00000000, 9, 0x00000014, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(19388, 0x00000000, 9, 0x00000014, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(19184, 0x00000000, 9, 0x00000010, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (19572, 0x00000000, 9, 0x00800000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (19573, 0x00000000, 9, 0x00800000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (20049, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), @@ -17863,6 +17886,7 @@ INSERT INTO `spell_proc_event` VALUES (20500, 0x00000000, 4, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (20501, 0x00000000, 4, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (20705, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20784, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (20911, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), (20925, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (21185, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), @@ -18035,12 +18059,14 @@ INSERT INTO `spell_proc_event` VALUES (34262, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (34320, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34355, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(34457, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34497, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34498, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34499, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34500, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34502, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (34503, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34506, 0x00000000, 9, 0x0007FA01, 0x00801081, 0x08000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (34584, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), (34586, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 0), (34598, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), @@ -18061,8 +18087,7 @@ INSERT INTO `spell_proc_event` VALUES (35080, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 60), (35083, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), (35086, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(35100, 0x00000000, 9, 0x00003001, 0x00000000, 0x00000000, 0x00010140, 0x00000000, 0.000000, 0.000000, 0), -(35102, 0x00000000, 9, 0x00003001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(35100, 0x00000000, 9, 0x00001000, 0x00000000, 0x00000001, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), (35121, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (36096, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), (36111, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -18189,9 +18214,7 @@ INSERT INTO `spell_proc_event` VALUES (46854, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (46855, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (46867, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(46913, 0x00000000, 4, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(46914, 0x00000000, 4, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(46915, 0x00000000, 4, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46913, 0x00000000, 4, 0x00000040, 0x00000404, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (46916, 0x00000000, 4, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (46951, 0x00000000, 4, 0x00000400, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (46952, 0x00000000, 0, 0x00000400, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -18270,6 +18293,7 @@ INSERT INTO `spell_proc_event` VALUES (51483, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (51485, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (51486, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(51521, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), (51528, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0), (51556, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (51557, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), @@ -18332,9 +18356,7 @@ INSERT INTO `spell_proc_event` VALUES (53256, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (53259, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (53260, 0x00000000, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53290, 0x00000000, 9, 0x00000800, 0x7FFFFFFF, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53291, 0x00000000, 9, 0x00000800, 0x7FFFFFFF, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53292, 0x00000000, 9, 0x00000800, 0x7FFFFFFF, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53290, 0x00000000, 9, 0x00000800, 0x00000001, 0x00000200, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (53380, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (53381, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (53382, 0x00000000, 10, 0x00800000, 0x00020000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), @@ -18353,6 +18375,7 @@ INSERT INTO `spell_proc_event` VALUES (53646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (53671, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (53673, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53817, 0x00000000, 11, 0x000001C3, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (54149, 0x00000000, 10, 0x00200000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (54151, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (54154, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -18405,7 +18428,7 @@ INSERT INTO `spell_proc_event` VALUES (56822, 0x00000000, 15, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56834, 0x00000000, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56835, 0x00000000, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(57352, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), +(57352, 0x00000000, 0, 0x00000001, 0x00000040, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), (57470, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (57472, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (57499, 0x00000000, 4, 0x40000001, 0x00010000, 0x00000000, 0x00014000, 0x00000000, 0.000000, 0.000000, 0), @@ -18424,7 +18447,7 @@ INSERT INTO `spell_proc_event` VALUES (58631, 0x00000000, 15, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58644, 0x00000000, 15, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58647, 0x00000000, 15, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58677, 0x00000000, 15, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58677, 0x00000000, 15, 0x00002000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (58872, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (58874, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (58901, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), @@ -18456,6 +18479,7 @@ INSERT INTO `spell_proc_event` VALUES (60770, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (60818, 0x00000000, 10, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (60826, 0x00000000, 15, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61062, 0x00000000, 3, 0x00000000, 0x00000100, 0x00000000, 0x00004000, 0x00010000, 0.000000, 0.000000, 0), (61188, 0x00000000, 5, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (61257, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0), (61324, 0x00000000, 10, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), diff --git a/sql/updates/8980_01_mangos_spell_bonus_data.sql b/sql/updates/8980_01_mangos_spell_bonus_data.sql new file mode 100644 index 000000000..a7f85f9ad --- /dev/null +++ b/sql/updates/8980_01_mangos_spell_bonus_data.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8965_02_mangos_command required_8980_01_mangos_spell_bonus_data bit; + +DELETE FROM spell_bonus_data WHERE entry = 56160; +INSERT INTO spell_bonus_data (entry, direct_bonus, dot_bonus, ap_bonus, comments) VALUES +(56160, 0, 0, 0, 'Item - Glyph of Power Word: Shield'); diff --git a/sql/updates/8981_01_mangos_spell_proc_event.sql b/sql/updates/8981_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..8474749b6 --- /dev/null +++ b/sql/updates/8981_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8980_01_mangos_spell_bonus_data required_8981_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` = 57352; +INSERT INTO `spell_proc_event` VALUES +(57352, 0x00000000, 0, 0x00000001, 0x00000040, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45); diff --git a/sql/updates/8988_01_mangos_spell_proc_event.sql b/sql/updates/8988_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..3616011fe --- /dev/null +++ b/sql/updates/8988_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8981_01_mangos_spell_proc_event required_8988_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (53817); +INSERT INTO `spell_proc_event` VALUES +(53817, 0x00000000, 11, 0x00000143, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000,0); diff --git a/sql/updates/8992_01_mangos_spell_proc_event.sql b/sql/updates/8992_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..0a1c795b2 --- /dev/null +++ b/sql/updates/8992_01_mangos_spell_proc_event.sql @@ -0,0 +1,41 @@ +ALTER TABLE db_version CHANGE COLUMN required_8988_01_mangos_spell_proc_event required_8992_01_mangos_spell_proc_event bit; + +/*Ferocious Inspiration*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34457); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(34457, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0); + +/*Frenzy*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (20784); +INSERT INTO `spell_proc_event` (`entry` ,`SchoolMask` ,`SpellFamilyName` ,`SpellFamilyMask0` ,`SpellFamilyMask1` ,`SpellFamilyMask2` ,`procFlags` ,`procEx` ,`ppmRate` ,`CustomChance` ,`Cooldown`)VALUES +(20784, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0); + +/*Master Tactician*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (34506, 34507, 34508, 34838, 34839); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(34506, 0x00000000, 9, 0x0007FA01, 0x00801081, 0x08000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +/*Hunting Party*/ +DELETE FROM `spell_proc_event` WHERE entry IN (53290, 53291, 53292); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(53290, 0x00000000, 9, 0x00000800, 0x00000001, 0x00000200, 0x00000000, 0x00000002, 0.000000, 0.000000, 0); + +/*Bloodsurge*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (46913, 46914, 46915); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `cooldown`) VALUES +(46913, 0x00000000, 4, 0x00000040, 0x00000404, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +/*Entrapment*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (19184, 19387, 19388); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(19184, 0x00000000, 9, 0x00000010, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +/*Concussive Barrage*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (35100, 35102); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(35100, 0x00000000, 9, 0x00001000, 0x00000000, 0x00000001, 0x00000100, 0x00000000, 0.000000, 0.000000, 0); + +/*Improved Stormstrike*/ +DELETE FROM `spell_proc_event` WHERE `entry` IN (51521, 51522); +INSERT INTO `spell_proc_event` (`entry`, `SchoolMask`, `SpellFamilyName`, `SpellFamilyMask0`, `SpellFamilyMask1`, `SpellFamilyMask2`, `procFlags`, `procEx`, `ppmRate`, `CustomChance`, `Cooldown`) VALUES +(51521, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1); diff --git a/sql/updates/8992_02_mangos_spell_chain.sql b/sql/updates/8992_02_mangos_spell_chain.sql new file mode 100644 index 000000000..a53e45a9a --- /dev/null +++ b/sql/updates/8992_02_mangos_spell_chain.sql @@ -0,0 +1,43 @@ +ALTER TABLE db_version CHANGE COLUMN required_8992_01_mangos_spell_proc_event required_8992_02_mangos_spell_chain bit; + +/*Master Tactician*/ +DELETE FROM spell_chain WHERE first_spell = 34506; +INSERT INTO spell_chain VALUES +(34506, 0, 34506, 1, 0), +(34507, 34506, 34506, 2, 0), +(34508, 34507, 34506, 3, 0), +(34838, 34508, 34506, 4, 0), +(34839, 34838, 34506, 5, 0); + +/*Hunting Party*/ +DELETE FROM spell_chain WHERE first_spell = 53290; +INSERT INTO spell_chain VALUES +(53290, 0, 53290, 1, 0), +(53291, 53290, 53290, 2, 0), +(53292, 53291, 53290, 3, 0); + +/*Bloodsurge*/ +DELETE FROM spell_chain WHERE first_spell = 46913; +INSERT INTO spell_chain VALUES +(46913, 0, 46913, 1, 0), +(46914, 46913, 46913, 2, 0), +(46915, 46914, 46913, 3, 0); + +/*Entrapment*/ +DELETE FROM spell_chain WHERE first_spell = 19184; +INSERT INTO spell_chain VALUES +(19184, 0, 19184, 1, 0), +(19387, 19184, 19184, 2, 0), +(19388, 19387, 19184, 3, 0); + +/*Concussive Barrage*/ +DELETE FROM spell_chain WHERE first_spell = 35100; +INSERT INTO spell_chain VALUES +(35100, 0, 35100, 1, 0), +(35102, 35100, 35100, 2, 0); + +/*Improved Stormstrike*/ +DELETE FROM spell_chain WHERE first_spell = 51521; +INSERT INTO spell_chain VALUES +(51521, 0, 51521, 1, 0), +(51522, 51521, 51521, 2, 0); diff --git a/sql/updates/8993_01_mangos_spell_proc_event.sql b/sql/updates/8993_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..2a6223285 --- /dev/null +++ b/sql/updates/8993_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8992_02_mangos_spell_chain required_8993_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (53817); +INSERT INTO `spell_proc_event` VALUES +(53817, 0x00000000, 11, 0x000001C3, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000,0); diff --git a/sql/updates/8995_01_mangos_spell_proc_event.sql b/sql/updates/8995_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..24bf418ba --- /dev/null +++ b/sql/updates/8995_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8993_01_mangos_spell_proc_event required_8995_01_mangos_spell_proc_event bit; + +DELETE FROM spell_proc_event WHERE entry=58677; +INSERT INTO spell_proc_event VALUES +(58677, 0x00000000, 15, 0x00002000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0); diff --git a/sql/updates/8996_01_mangos_spell_proc_event.sql b/sql/updates/8996_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..6a8d10424 --- /dev/null +++ b/sql/updates/8996_01_mangos_spell_proc_event.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_8995_01_mangos_spell_proc_event required_8996_01_mangos_spell_proc_event bit; + +DELETE FROM spell_proc_event WHERE entry=61062; +INSERT INTO spell_proc_event VALUES +(61062, 0x00000000, 3, 0x00000000, 0x00000100, 0x00000000, 0x00004000, 0x00010000, 0.000000, 0.000000, 0); + diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index f4ea2d3db..4a0300e6c 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -200,6 +200,14 @@ pkgdata_DATA = \ 8950_01_mangos_spell_proc_event.sql \ 8965_01_mangos_mangos_string.sql \ 8965_02_mangos_command.sql \ + 8980_01_mangos_spell_bonus_data.sql \ + 8981_01_mangos_spell_proc_event.sql \ + 8988_01_mangos_spell_proc_event.sql \ + 8992_01_mangos_spell_proc_event.sql \ + 8992_02_mangos_spell_chain.sql \ + 8993_01_mangos_spell_proc_event.sql \ + 8995_01_mangos_spell_proc_event.sql \ + 8996_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -380,4 +388,12 @@ EXTRA_DIST = \ 8950_01_mangos_spell_proc_event.sql \ 8965_01_mangos_mangos_string.sql \ 8965_02_mangos_command.sql \ + 8980_01_mangos_spell_bonus_data.sql \ + 8981_01_mangos_spell_proc_event.sql \ + 8988_01_mangos_spell_proc_event.sql \ + 8992_01_mangos_spell_proc_event.sql \ + 8992_02_mangos_spell_chain.sql \ + 8993_01_mangos_spell_proc_event.sql \ + 8995_01_mangos_spell_proc_event.sql \ + 8996_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 757d2c928..a5d4cf181 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -348,7 +348,8 @@ enum SummonPropType SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3 "%s's Opponent" SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3 "%s's Vehicle" SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells - SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3 + SUMMON_PROP_TYPE_LIGHTWELL = 11, // summon lightwell, 6 spells in 3.0.3 + SUMMON_PROP_TYPE_REPAIR_BOT = 12 // summon repir bot, 1 spells in 3.2.2a }; // SummonProperties.dbc, col 5 diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h index 1cb39b7d0..36c443565 100644 --- a/src/game/GossipDef.h +++ b/src/game/GossipDef.h @@ -70,7 +70,7 @@ enum GossipOptionIcon //POI icons. Many more exist, list not complete. enum Poi_Icon { - ICON_POI_BLANK = 0, // Blank (not visible) + ICON_POI_BLANK = 0, // Blank (not visible), in 2.4.3 have value 15 with 1..15 values in 0..14 range ICON_POI_GREY_AV_MINE = 1, // Grey mine lorry ICON_POI_RED_AV_MINE = 2, // Red mine lorry ICON_POI_BLUE_AV_MINE = 3, // Blue mine lorry diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 59a272a32..3b82ddd74 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -1026,9 +1026,12 @@ void WorldSession::HandleMoveTimeSkippedOpcode( WorldPacket & recv_data ) */ } -void WorldSession::HandleFeatherFallAck(WorldPacket &/*recv_data*/) +void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data) { DEBUG_LOG("WORLD: CMSG_MOVE_FEATHER_FALL_ACK"); + + // no used + recv_data.rpos(recv_data.wpos()); // prevent warnings spam } void WorldSession::HandleMoveUnRootAck(WorldPacket& recv_data) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 76d6545be..0786fffdd 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -248,8 +248,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) { // transports size limited - // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) - if( movementInfo.t_x > 50 || movementInfo.t_y > 50 || movementInfo.t_z > 50 ) + // (also received at zeppelin/lift leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) + if( movementInfo.t_x > 50 || movementInfo.t_y > 50 || movementInfo.t_z > 100 ) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam return; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 8e608a954..a13b45f5d 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -667,6 +667,12 @@ void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask * if (!((Creature*)this)->isCanTrainingOf(target, false)) appendValue &= ~(UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_TRAINER_CLASS | UNIT_NPC_FLAG_TRAINER_PROFESSION); } + + if (appendValue & UNIT_NPC_FLAG_STABLEMASTER) + { + if (target->getClass() != CLASS_HUNTER) + appendValue &= ~UNIT_NPC_FLAG_STABLEMASTER; + } } *data << uint32(appendValue); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index aca11b046..ca0db12f2 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7315,6 +7315,10 @@ bool PlayerCondition::Meets(Player const * player) const } return false; } + case CONDITION_RACE_CLASS: + if ((!value1 || (player->getRaceMask() & value1)) && (!value2 || (player->getClassMask() & value2))) + return true; + return false; default: return false; } @@ -7468,6 +7472,27 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val } break; } + case CONDITION_RACE_CLASS: + { + if (!value1 && !value2) + { + sLog.outErrorDb("Race_class condition has both values like 0, skipped"); + return false; + } + + if (value1 && !(value1 & RACEMASK_ALL_PLAYABLE)) + { + sLog.outErrorDb("Race_class condition has invalid player class %u, skipped", value1); + return false; + } + + if (value2 && !(value2 & CLASSMASK_ALL_PLAYABLE)) + { + sLog.outErrorDb("Race_class condition has invalid race mask %u, skipped", value2); + return false; + } + break; + } case CONDITION_NONE: break; } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 6fbf18d5c..e3b140ab1 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -319,11 +319,12 @@ enum ConditionType CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active. CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD commission aura active CONDITION_NO_AURA = 11, // spell_id effindex - CONDITION_ACTIVE_EVENT = 12, // event_id - CONDITION_AREA_FLAG = 13 // area_flag area_flag_not + CONDITION_ACTIVE_EVENT = 12, // event_id 0 + CONDITION_AREA_FLAG = 13, // area_flag area_flag_not + CONDITION_RACE_CLASS = 14, // race_mask class_mask }; -#define MAX_CONDITION 14 // maximum value in ConditionType enum +#define MAX_CONDITION 15 // maximum value in ConditionType enum struct PlayerCondition { diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 1a9af6755..063a00d8c 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -414,8 +414,7 @@ void Pet::SavePetToDB(PetSaveMode mode) << curmana << ", " << GetPower(POWER_HAPPINESS) << ", '"; - // save only spell slots from action bar - for(uint32 i = ACTION_BAR_INDEX_PET_SPELL_START; i < ACTION_BAR_INDEX_PET_SPELL_END; ++i) + for(uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i) { ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << " "; diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 57b048964..a58f7e5bf 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -324,23 +324,59 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) } count = (recv_data.size() == 24) ? 2 : 1; + + uint32 position[2]; + uint32 data[2]; + bool move_command = false; + for(uint8 i = 0; i < count; ++i) { - uint32 position; - uint32 data; + recv_data >> position[i]; + recv_data >> data[i]; - recv_data >> position; - recv_data >> data; - - uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data); - uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data); - - sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, uint32(act_state)); + uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); //ignore invalid position - if(position >= MAX_UNIT_ACTION_BAR_INDEX) + if(position[i] >= MAX_UNIT_ACTION_BAR_INDEX) return; + // in the normal case, command and reaction buttons can only be moved, not removed + // at moving count ==2, at removing count == 1 + // ignore attempt to remove command|reaction buttons (not possible at normal case) + if (act_state == ACT_COMMAND || act_state == ACT_REACTION) + { + if (count == 1) + return; + + move_command = true; + } + } + + // check swap + if (move_command) + { + uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]); + uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]); + UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]); + if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() || + act_state_0 != actionEntry_1->GetType()) + return; + + uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]); + uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]); + UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]); + if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() || + act_state_1 != actionEntry_0->GetType()) + return; + } + + for(uint8 i = 0; i < count; ++i) + { + uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]); + uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); + + sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position[i], spell_id, uint32(act_state)); + //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) { @@ -361,7 +397,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) ((Pet*)pet)->ToggleAutocast(spell_id, false); } - charmInfo->SetActionBar(position,spell_id,ActiveStates(act_state)); + charmInfo->SetActionBar(position[i],spell_id,ActiveStates(act_state)); } } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e363618ea..4bf9ccaca 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2088,6 +2088,12 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) if (npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask )) return NULL; + if (npcflagmask == UNIT_NPC_FLAG_STABLEMASTER) + { + if (getClass() != CLASS_HUNTER) + return NULL; + } + // if a dead unit should be able to talk - the creature must be alive and have special flags if (!unit->isAlive()) return NULL; @@ -5008,8 +5014,8 @@ void Player::SetRegularAttackTime() { for(int i = 0; i < MAX_ATTACK; ++i) { - Item *tmpitem = GetWeaponForAttack(WeaponAttackType(i)); - if(tmpitem && !tmpitem->IsBroken()) + Item *tmpitem = GetWeaponForAttack(WeaponAttackType(i),true,false); + if (tmpitem) { ItemPrototype const *proto = tmpitem->GetProto(); if(proto->Delay) @@ -5215,7 +5221,7 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType) { case BASE_ATTACK: { - Item *tmpitem = GetWeaponForAttack(attType,true); + Item *tmpitem = GetWeaponForAttack(attType,true,true); if (!tmpitem) UpdateSkill(SKILL_UNARMED,weapon_skill_gain); @@ -5226,7 +5232,7 @@ void Player::UpdateWeaponSkill (WeaponAttackType attType) case OFF_ATTACK: case RANGED_ATTACK: { - Item *tmpitem = GetWeaponForAttack(attType,true); + Item *tmpitem = GetWeaponForAttack(attType,true,true); if (tmpitem) UpdateSkill(tmpitem->GetSkill(),weapon_skill_gain); break; @@ -7034,8 +7040,8 @@ void Player::UpdateEquipSpellsAtFormChange() void Player::CastItemCombatSpell(Unit* Target, WeaponAttackType attType) { - Item *item = GetWeaponForAttack(attType, false); - if(!item || item->IsBroken()) + Item *item = GetWeaponForAttack(attType, true, false); + if(!item) return; ItemPrototype const *proto = item->GetProto(); @@ -7355,8 +7361,8 @@ bool Player::CheckAmmoCompatibility(const ItemPrototype *ammo_proto) const return false; // check ranged weapon - Item *weapon = GetWeaponForAttack( RANGED_ATTACK ); - if(!weapon || weapon->IsBroken() ) + Item *weapon = GetWeaponForAttack( RANGED_ATTACK, true, false ); + if (!weapon) return false; ItemPrototype const* weapon_proto = weapon->GetProto(); @@ -8173,14 +8179,14 @@ void Player::SetSheath( SheathState sheathed ) break; case SHEATH_STATE_MELEE: // prepared melee weapon { - SetVirtualItemSlot(0,GetWeaponForAttack(BASE_ATTACK,true)); - SetVirtualItemSlot(1,GetWeaponForAttack(OFF_ATTACK,true)); + SetVirtualItemSlot(0,GetWeaponForAttack(BASE_ATTACK,true,true)); + SetVirtualItemSlot(1,GetWeaponForAttack(OFF_ATTACK,true,true)); SetVirtualItemSlot(2,NULL); }; break; case SHEATH_STATE_RANGED: // prepared ranged weapon SetVirtualItemSlot(0,NULL); SetVirtualItemSlot(1,NULL); - SetVirtualItemSlot(2,GetWeaponForAttack(RANGED_ATTACK,true)); + SetVirtualItemSlot(2,GetWeaponForAttack(RANGED_ATTACK,true,true)); break; default: SetVirtualItemSlot(0,NULL); @@ -8551,7 +8557,7 @@ Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const return NULL; } -Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) const +Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const { uint16 slot; switch (attackType) @@ -8566,10 +8572,10 @@ Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool useable) cons if (!item || item->GetProto()->Class != ITEM_CLASS_WEAPON) return NULL; - if(!useable) - return item; + if (useable && !IsUseEquipedWeapon(attackType==BASE_ATTACK)) + return NULL; - if( item->IsBroken() || !IsUseEquipedWeapon(attackType==BASE_ATTACK) ) + if (nonbroken && item->IsBroken()) return NULL; return item; @@ -12491,7 +12497,7 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 me uint32 Player::GetGossipTextId(WorldObject *pSource) { if (!pSource || pSource->GetTypeId() != TYPEID_UNIT || !((Creature*)pSource)->GetDBTableGUIDLow()) - return 0; + return DEFAULT_GOSSIP_MESSAGE; if (uint32 pos = sObjectMgr.GetNpcGossip(((Creature*)pSource)->GetDBTableGUIDLow())) return pos; @@ -19638,7 +19644,7 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const { - Item* item = GetWeaponForAttack(attType,true); + Item* item = GetWeaponForAttack(attType,true,true); // unarmed only with base attack if(attType != BASE_ATTACK && !item) diff --git a/src/game/Player.h b/src/game/Player.h index 120352e7d..6bb6e0d42 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1163,7 +1163,8 @@ class MANGOS_DLL_SPEC Player : public Unit Item* GetItemByGuid( uint64 guid ) const; Item* GetItemByPos( uint16 pos ) const; Item* GetItemByPos( uint8 bag, uint8 slot ) const; - Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const; + Item* GetWeaponForAttack(WeaponAttackType attackType) const { return GetWeaponForAttack(attackType,false,false); } + Item* GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const; Item* GetShield(bool useable = false) const; static uint32 GetAttackBySlot( uint8 slot ); // MAX_ATTACK if not weapon slot std::vector &GetItemUpdateQueue() { return m_itemUpdateQueue; } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a130bfc02..6467ff854 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -686,6 +686,9 @@ void Spell::prepareDataForTriggerSystem() // Clearcasting trigger need do it else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000200000000) && m_spellInfo->SpellFamilyFlags2 & 0x8) m_canTrigger = true; + // Replenish Mana, item spell with triggered cases (Mana Agate, etc mana gems) + else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000010000000000)) + m_canTrigger = true; break; case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000800000000060)) @@ -2417,11 +2420,10 @@ void Spell::cancel() { Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); if( unit && unit->isAlive() ) - unit->RemoveAurasDueToSpell(m_spellInfo->Id); + unit->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID()); } } - m_caster->RemoveAurasDueToSpell(m_spellInfo->Id); SendChannelUpdate(0); SendInterrupted(0); SendCastResult(SPELL_FAILED_INTERRUPTED); @@ -3441,6 +3443,13 @@ void Spell::SendChannelUpdate(uint32 time) { if(time == 0) { + m_caster->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID()); + + if(uint64 target_guid = m_caster->GetChannelObjectGUID()) + if(target_guid != m_caster->GetGUID() && IS_UNIT_GUID(target_guid)) + if(Unit* target = ObjectAccessor::GetUnit(*m_caster, target_guid)) + target->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID()); + m_caster->SetChannelObjectGUID(0); m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0); } @@ -5563,8 +5572,8 @@ SpellCastResult Spell::CheckItems() if(m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER; if( m_attackType != RANGED_ATTACK ) break; - Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(m_attackType); - if(!pItem || pItem->IsBroken()) + Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(m_attackType,true,false); + if (!pItem) return SPELL_FAILED_EQUIPPED_ITEM; switch(pItem->GetProto()->SubClass) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 4b64326f4..186d53825 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -628,27 +628,20 @@ void Aura::Update(uint32 diff) return; } - // Get spell range - float radius; - SpellModOp mod; - if (m_spellProto->EffectRadiusIndex[GetEffIndex()]) + // need check distance for channeled target only + if (caster->GetChannelObjectGUID() == m_target->GetGUID()) { - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()])); - mod = SPELLMOD_RADIUS; - } - else - { - radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)); - mod = SPELLMOD_RANGE; - } + // Get spell range + float max_range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)); - if(Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod(GetId(), mod, radius, NULL); + if(Player* modOwner = caster->GetSpellModOwner()) + modOwner->ApplySpellMod(GetId(), SPELLMOD_RANGE, max_range, NULL); - if(!caster->IsWithinDistInMap(m_target, radius)) - { - m_target->RemoveAura(GetId(), GetEffIndex()); - return; + if(!caster->IsWithinDistInMap(m_target, max_range)) + { + m_target->RemoveAura(GetId(), GetEffIndex()); + return; + } } } @@ -1331,7 +1324,7 @@ bool Aura::isAffectedOnSpell(SpellEntry const *spell) const return false; } -void Aura::ReapplyAffectedPassiveAuras( Unit* target ) +void Aura::ReapplyAffectedPassiveAuras( Unit* target, bool owner_mode ) { std::set affectedSelf; std::set affectedAuraCaster; @@ -1339,16 +1332,17 @@ void Aura::ReapplyAffectedPassiveAuras( Unit* target ) for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) { // permanent passive or permanent area aura - if (itr->second->IsPermanent() && (itr->second->IsPassive() || itr->second->IsAreaAura()) && + // passive spells can be affected only by own or owner spell mods) + if (itr->second->IsPermanent() && (owner_mode && itr->second->IsPassive() || itr->second->IsAreaAura()) && // non deleted and not same aura (any with same spell id) !itr->second->IsDeleted() && itr->second->GetId() != GetId() && // and affected by aura isAffectedOnSpell(itr->second->GetSpellProto())) { // only applied by self or aura caster - if(itr->second->GetCasterGUID() == target->GetGUID()) + if (itr->second->GetCasterGUID() == target->GetGUID()) affectedSelf.insert(itr->second->GetId()); - else if(itr->second->GetCasterGUID() == GetCasterGUID()) + else if (itr->second->GetCasterGUID() == GetCasterGUID()) affectedAuraCaster.insert(itr->second->GetId()); } } @@ -1429,25 +1423,26 @@ void Aura::HandleAddModifier(bool apply, bool Real) ((Player*)m_target)->AddSpellMod(m_spellmod, apply); // reapply talents to own passive persistent auras - ReapplyAffectedPassiveAuras(m_target); + ReapplyAffectedPassiveAuras(m_target, true); // re-apply talents/passives/area auras applied to pet (it affected by player spellmods) if(Pet* pet = m_target->GetPet()) - ReapplyAffectedPassiveAuras(pet); + ReapplyAffectedPassiveAuras(pet, true); // re-apply talents/passives/area auras applied to totems (it affected by player spellmods) for(int i = 0; i < MAX_TOTEM; ++i) if(m_target->m_TotemSlot[i]) if(Creature* totem = m_target->GetMap()->GetCreature(m_target->m_TotemSlot[i])) - ReapplyAffectedPassiveAuras(totem); + ReapplyAffectedPassiveAuras(totem, true); // re-apply talents/passives/area auras applied to group members (it affected by player spellmods) if (Group* group = ((Player*)m_target)->GetGroup()) for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* member = itr->getSource()) if (member != m_target && member->IsInMap(m_target)) - ReapplyAffectedPassiveAuras(member); + ReapplyAffectedPassiveAuras(member, false); } + void Aura::HandleAddTargetTrigger(bool apply, bool /*Real*/) { // Use SpellModifier structure for check @@ -5295,7 +5290,7 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real) if(Real) { for(int i = 0; i < MAX_ATTACK; ++i) - if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) + if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i),true,false)) ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem, WeaponAttackType(i), this, apply); } @@ -5495,7 +5490,7 @@ void Aura::HandleModDamageDone(bool apply, bool Real) if(Real && m_target->GetTypeId() == TYPEID_PLAYER) { for(int i = 0; i < MAX_ATTACK; ++i) - if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) + if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i),true,false)) ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply); } @@ -5578,7 +5573,7 @@ void Aura::HandleModDamagePercentDone(bool apply, bool Real) if(Real && m_target->GetTypeId() == TYPEID_PLAYER) { for(int i = 0; i < MAX_ATTACK; ++i) - if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i))) + if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i),true,false)) ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply); } @@ -5897,7 +5892,7 @@ void Aura::HandleShapeshiftBoosts(bool apply) void Aura::HandleSpellSpecificBoosts(bool apply) { - bool cast_at_remove = false; // if spell must be casted at aura remove + bool cast_at_remove = false; // if spell must be casted at last aura from stack remove uint32 spellId1 = 0; uint32 spellId2 = 0; uint32 spellId3 = 0; @@ -5905,9 +5900,21 @@ void Aura::HandleSpellSpecificBoosts(bool apply) switch(GetSpellProto()->SpellFamilyName) { + case SPELLFAMILY_GENERIC: + { + // Illusionary Barrier + if(GetId() == 57350 && !apply && m_target->getPowerType() == POWER_MANA) + { + cast_at_remove = true; + spellId1 = 60242; // Darkmoon Card: Illusion + } + else + return; + break; + } case SPELLFAMILY_MAGE: { - // Ice Barrier + // Ice Barrier (non stacking from one caster) if (m_spellProto->SpellIconID == 32) { if (!apply && (m_removeMode == AURA_REMOVE_BY_DISPEL || (m_removeMode == AURA_REMOVE_BY_DEFAULT && !GetModifier()->m_amount))) @@ -5954,7 +5961,7 @@ void Aura::HandleSpellSpecificBoosts(bool apply) break; } case SPELLFAMILY_WARLOCK: - // Fear + // Fear (non stacking) if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { if(!apply) @@ -6632,7 +6639,11 @@ void Aura::PeriodicTick() // send critical in hit info for threat calculation if (isCrit) + { cleanDamage.hitOutCome = MELEE_HIT_CRIT; + // Resilience - reduce crit damage + pdamage -= m_target->GetSpellCritDamageReduction(pdamage); + } // only from players // FIXME: need use SpellDamageBonus instead? diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index e4a72aaab..489976a5d 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -352,7 +352,7 @@ class MANGOS_DLL_SPEC Aura void PeriodicDummyTick(); bool IsCritFromAbilityAura(Unit* caster, uint32& damage); - void ReapplyAffectedPassiveAuras(Unit* target); + void ReapplyAffectedPassiveAuras(Unit* target, bool owner_mode); Modifier m_modifier; SpellModifier *m_spellmod; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c899656aa..db710d714 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2223,10 +2223,10 @@ void Spell::EffectTriggerSpell(uint32 effIndex) // main hand weapon required if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND) { - Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK); + Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK, true, false); // skip spell if no weapon in slot or broken - if (!item || item->IsBroken() ) + if (!item) return; // skip spell if weapon not fit to triggered spell @@ -2237,10 +2237,10 @@ void Spell::EffectTriggerSpell(uint32 effIndex) // offhand hand weapon required if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND) { - Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK); + Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK, true, false); // skip spell if no weapon in slot or broken - if (!item || item->IsBroken() ) + if (!item) return; // skip spell if weapon not fit to triggered spell @@ -3442,6 +3442,7 @@ void Spell::EffectSummonType(uint32 i) break; } case SUMMON_PROP_TYPE_CRITTER: + case SUMMON_PROP_TYPE_REPAIR_BOT: { EffectSummonCritter(i, summon_prop->FactionId); break; @@ -4586,7 +4587,7 @@ void Spell::EffectWeaponDmg(uint32 i) // Whirlwind, single only spell with 2 weapon white damage apply if have if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x00000400000000))) { - if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK,true)) + if(((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK, true, true)) spell_bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized); } // Devastate bonus and sunder armor refresh @@ -4646,7 +4647,7 @@ void Spell::EffectWeaponDmg(uint32 i) // Fan of Knives else if (m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0004000000000000))) { - Item* weapon = ((Player*)m_caster)->GetWeaponForAttack(m_attackType,true); + Item* weapon = ((Player*)m_caster)->GetWeaponForAttack(m_attackType,true,true); if (weapon && weapon->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) totalDamagePercentMod *= 1.5f; // 150% to daggers } @@ -4821,13 +4822,13 @@ void Spell::EffectWeaponDmg(uint32 i) // take ammo if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) { - Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK ); + Item *pItem = ((Player*)m_caster)->GetWeaponForAttack(RANGED_ATTACK, true, false); // wands don't have ammo - if(!pItem || pItem->IsBroken() || pItem->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_WAND) + if (!pItem || pItem->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_WAND) return; - if( pItem->GetProto()->InventoryType == INVTYPE_THROWN ) + if (pItem->GetProto()->InventoryType == INVTYPE_THROWN) { if(pItem->GetMaxStackCount()==1) { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 363385e12..bc981527e 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -483,7 +483,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) break; } } break; - case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative) + case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from base point sign (negative -> negative) case SPELL_AURA_MOD_STAT: case SPELL_AURA_MOD_SKILL: case SPELL_AURA_MOD_HEALING_PCT: @@ -496,8 +496,10 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) return false; break; case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: + case SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT: + case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: if(spellproto->CalculateSimpleValue(effIndex) > 0) - return true; // some expected positive spells have SPELL_ATTR_EX_NEGATIVE + return true; // some expected positive spells have SPELL_ATTR_EX_NEGATIVE or unclear target modes break; case SPELL_AURA_ADD_TARGET_TRIGGER: return true; @@ -573,6 +575,8 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) // some spells negative switch(spellproto->Id) { + case 802: // Mutate Bug, wrongly negative by target modes + return true; case 36900: // Soul Split: Evil! case 36901: // Soul Split: Good case 36893: // Transporter Malfunction (decrease size case) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b5112b6df..5bcac4181 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -176,6 +176,7 @@ Unit::~Unit() // those should be already removed at "RemoveFromWorld()" call assert(m_gameObj.size() == 0); assert(m_dynObjGUIDs.size() == 0); + assert(m_deletedAuras.size() == 0); } void Unit::Update( uint32 p_time ) @@ -196,6 +197,8 @@ void Unit::Update( uint32 p_time ) m_Events.Update( p_time ); _UpdateSpells( p_time ); + CleanupDeletedAuars(); + if (m_lastManaUseTimer) { if (p_time >= m_lastManaUseTimer) @@ -204,11 +207,6 @@ void Unit::Update( uint32 p_time ) m_lastManaUseTimer -= p_time; } - // really delete auras "deleted" while processing its ApplyModify code - for(AuraList::const_iterator itr = m_deletedAuras.begin(); itr != m_deletedAuras.begin(); ++itr) - delete *itr; - m_deletedAuras.clear(); - if (CanHaveThreatList()) getThreatManager().UpdateForClient(p_time); @@ -246,7 +244,7 @@ void Unit::Update( uint32 p_time ) bool Unit::haveOffhandWeapon() const { if(GetTypeId() == TYPEID_PLAYER) - return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true); + return ((Player*)this)->GetWeaponForAttack(OFF_ATTACK,true,true); else return false; } @@ -764,9 +762,18 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa ((Creature*)pVictim)->AI()->AttackedBy(this); } - // polymorphed and other negative transformed cases - if(pVictim->getTransForm() && pVictim->hasUnitState(UNIT_STAT_CONFUSED)) - pVictim->RemoveAurasDueToSpell(pVictim->getTransForm()); + // polymorphed, hex and other negative transformed cases + uint32 morphSpell = pVictim->getTransForm(); + if (morphSpell && !IsPositiveSpell(morphSpell)) + { + if (SpellEntry const* morphEntry = sSpellStore.LookupEntry(morphSpell)) + { + if (IsSpellHaveAura(morphEntry, SPELL_AURA_MOD_CONFUSE)) + pVictim->RemoveAurasDueToSpell(morphSpell); + else if (IsSpellHaveAura(morphEntry, SPELL_AURA_MOD_PACIFY_SILENCE)) + pVictim->RemoveSpellbyDamageTaken(SPELL_AURA_MOD_PACIFY_SILENCE, damage); + } + } if(damagetype == DIRECT_DAMAGE || damagetype == SPELL_DIRECT_DAMAGE) { @@ -2950,9 +2957,9 @@ float Unit::GetUnitParryChance() const Player const* player = (Player const*)this; if(player->CanParry() ) { - Item *tmpitem = player->GetWeaponForAttack(BASE_ATTACK,true); + Item *tmpitem = player->GetWeaponForAttack(BASE_ATTACK,true,true); if(!tmpitem) - tmpitem = player->GetWeaponForAttack(OFF_ATTACK,true); + tmpitem = player->GetWeaponForAttack(OFF_ATTACK,true,true); if(tmpitem) chance = GetFloatValue(PLAYER_PARRY_PERCENTAGE); @@ -3056,7 +3063,7 @@ uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target) uint32 value = 0; if(GetTypeId() == TYPEID_PLAYER) { - Item* item = ((Player*)this)->GetWeaponForAttack(attType,true); + Item* item = ((Player*)this)->GetWeaponForAttack(attType,true,true); // feral or unarmed skill only for base attack if(attType != BASE_ATTACK && !item ) @@ -3962,11 +3969,11 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, // backfire damage and silence dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,casterGUID); + return; } - return; } // Flame Shock - if (spellEntry->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellEntry->SpellFamilyFlags & UI64LIT(0x10000000))) + else if (spellEntry->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellEntry->SpellFamilyFlags & UI64LIT(0x10000000))) { Unit* caster = NULL; uint32 triggeredSpell = 0; @@ -3998,6 +4005,24 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, caster->CastSpell(caster, triggeredSpell, true); return; } + // Vampiric touch (first dummy aura) + else if (spellEntry->SpellFamilyName == SPELLFAMILY_PRIEST && spellEntry->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + { + if (Aura *dot = GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, UI64LIT(0x0000040000000000), 0x00000000, casterGUID)) + { + if(Unit* caster = dot->GetCaster()) + { + int32 bp0 = dot->GetModifier()->m_amount; + bp0 = 8 * caster->SpellDamageBonus(this, spellEntry, bp0, DOT, 1); + + // Remove spell auras from stack + RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); + + CastCustomSpell(this, 64085, &bp0, NULL, NULL, true, NULL, NULL, casterGUID); + return; + } + } + } RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); } @@ -4227,19 +4252,10 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) // Statue unsummoned at aura remove Totem* statue = NULL; - bool caster_channeled = false; if(IsChanneledSpell(AurSpellInfo)) - { - Unit* caster = Aur->GetCaster(); - - if(caster) - { + if(Unit* caster = Aur->GetCaster()) if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) statue = ((Totem*)caster); - else - caster_channeled = caster==this; - } - } sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); if (mode != AURA_REMOVE_BY_DELETE) // not unapply if target will deleted @@ -4259,9 +4275,6 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) else delete Aur; - if(caster_channeled) - RemoveAurasAtChanneledTarget (AurSpellInfo); - if(statue) statue->UnSummon(); @@ -4270,6 +4283,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) i = m_Auras.end(); else i = m_Auras.begin(); + } void Unit::RemoveAllAuras(AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/) @@ -6798,51 +6812,114 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; // Try handle unknown trigger spells - if (sSpellStore.LookupEntry(trigger_spell_id)==NULL) + // Custom requirements (not listed in procEx) Warning! damage dealing after this + // Custom triggered spells + switch (auraSpellInfo->SpellFamilyName) { - switch (auraSpellInfo->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - //if (auraSpellInfo->Id==59532) // Abandon Passengers on Poly - //if (auraSpellInfo->Id==54775) // Abandon Vehicle on Poly - //if (auraSpellInfo->Id==34082) // Advantaged State (DND) - if (auraSpellInfo->Id == 23780) // Aegis of Preservation (Aegis of Preservation trinket) + case SPELLFAMILY_GENERIC: + switch(auraSpellInfo->Id) + { + //case 191: // Elemental Response + // switch (procSpell->School) + // { + // case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192; break; + // case SPELL_SCHOOL_FROST: trigger_spell_id = 34193; break; + // case SPELL_SCHOOL_ARCANE:trigger_spell_id = 34194; break; + // case SPELL_SCHOOL_NATURE:trigger_spell_id = 34195; break; + // case SPELL_SCHOOL_SHADOW:trigger_spell_id = 34196; break; + // case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197; break; + // case SPELL_SCHOOL_NORMAL:trigger_spell_id = 34198; break; + // } + // break; + //case 5301: break; // Defensive State (DND) + //case 7137: break: // Shadow Charge (Rank 1) + //case 7377: break: // Take Immune Periodic Damage + //case 13358: break; // Defensive State (DND) + //case 16092: break; // Defensive State (DND) + //case 18943: break; // Double Attack + //case 19194: break; // Double Attack + //case 19817: break; // Double Attack + //case 19818: break; // Double Attack + //case 22835: break; // Drunken Rage + // trigger_spell_id = 14822; break; + case 23780: // Aegis of Preservation (Aegis of Preservation trinket) trigger_spell_id = 23781; - //else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura - //else if (auraSpellInfo->Id == 48876) // Beast's Mark - //{ - // trigger_spell_id = 48877; - //} - //else if (auraSpellInfo->Id == 59237) // Beast's Mark - //{ - // trigger_spell_id = 59233; - //} - //else if (auraSpellInfo->Id==46939) // Black Bow of the Betrayer - //{ - // trigger_spell_id = 29471; // gain mana - // 27526; // drain mana if possible - //} - //else if (auraSpellInfo->Id==50844) // Blood Mirror - //else if (auraSpellInfo->Id==54476) // Blood Presence - //else if (auraSpellInfo->Id==50689) // Blood Presence (Rank 1) - //else if (auraSpellInfo->Id==37030) // Chaotic Temperament - //else if (auraSpellInfo->Id==52856) // Charge - else if (auraSpellInfo->Id==43820) // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket) - { + break; + //case 24949: break; // Defensive State 2 (DND) + case 27522: // Mana Drain Trigger + case 40336: // Mana Drain Trigger + // 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 (pVictim && pVictim->isAlive()) + CastSpell(pVictim, 27526, true, castItem, triggeredByAura); + return true; + case 31255: // Deadly Swiftness (Rank 1) + // whenever you deal damage to a target who is below 20% health. + if (pVictim->GetHealth() > pVictim->GetMaxHealth() / 5) + return false; + + target = this; + trigger_spell_id = 22588; + break; + //case 33207: break; // Gossip NPC Periodic - Fidget + case 33896: // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher) + trigger_spell_id = 33898; + break; + //case 34082: break; // Advantaged State (DND) + //case 34783: break: // Spell Reflection + //case 35205: break: // Vanish + //case 35321: break; // Gushing Wound + //case 36096: break: // Spell Reflection + //case 36207: break: // Steal Weapon + //case 36576: break: // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger + //case 37030: break; // Chaotic Temperament + //case 38363: break; // Gushing Wound + //case 39215: break; // Gushing Wound + //case 40250: break; // Improved Duration + //case 40329: break; // Demo Shout Sensor + //case 40364: break; // Entangling Roots Sensor + //case 41054: break; // Copy Weapon + // trigger_spell_id = 41055; break; + //case 41248: break; // Consuming Strikes + // trigger_spell_id = 41249; break; + //case 42730: break: // Woe Strike + //case 43453: break: // Rune Ward + //case 43504: break; // Alterac Valley OnKill Proc Aura + //case 44326: break: // Pure Energy Passive + //case 44526: break; // Hate Monster (Spar) (30 sec) + //case 44527: break; // Hate Monster (Spar Buddy) (30 sec) + //case 44819: break; // Hate Monster (Spar Buddy) (>30% Health) + //case 44820: break; // Hate Monster (Spar) (<30%) + case 45057: // Evasive Maneuvers (Commendation of Kael`thas trinket) + // reduce you below $s1% health + if (GetHealth() - damage > GetMaxHealth() * triggerAmount / 100) + return false; + break; + //case 45903: break: // Offensive State + //case 46146: break: // [PH] Ahune Spanky Hands + //case 46939: break; // Black Bow of the Betrayer + // trigger_spell_id = 29471; - gain mana + // 27526; - drain mana if possible + case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket) // Pct value stored in dummy basepoints[0] = pVictim->GetCreateHealth() * auraSpellInfo->EffectBasePoints[1] / 100; target = pVictim; break; - } - //else if (auraSpellInfo->Id==41248) // Consuming Strikes - // trigger_spell_id = 41249; - //else if (auraSpellInfo->Id==45205) // Copy Offhand Weapon - //else if (auraSpellInfo->Id==57594) // Copy Ranged Weapon - //else if (auraSpellInfo->Id==41054) // Copy Weapon - // trigger_spell_id = 41055; - //else if (auraSpellInfo->Id==45343) // Dark Flame Aura - //else if (auraSpellInfo->Id==47300) // Dark Flame Aura - else if (auraSpellInfo->Id==57345) // Darkmoon Card: Greatness + //case 45205: break; // Copy Offhand Weapon + //case 45343: break; // Dark Flame Aura + //case 47300: break; // Dark Flame Aura + //case 48876: break; // Beast's Mark + // trigger_spell_id = 48877; break; + //case 49059: break; // Horde, Hate Monster (Spar Buddy) (>30% Health) + //case 50051: break; // Ethereal Pet Aura + //case 50689: break; // Blood Presence (Rank 1) + //case 50844: break; // Blood Mirror + //case 52856: break; // Charge + //case 54072: break; // Knockback Ball Passive + //case 54476: break; // Blood Presence + //case 54775: break; // Abandon Vehicle on Poly + case 57345: // Darkmoon Card: Greatness { float stat = 0.0f; // strength @@ -6853,471 +6930,454 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB if (GetStat(STAT_INTELLECT)> stat) { trigger_spell_id = 60234;stat = GetStat(STAT_INTELLECT);} // spirit if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235; } + break; } - else if (auraSpellInfo->Id==67702) // Death's Choice, Item - Coliseum 25 Normal Melee Trinket + //case 55580: break: // Mana Link + //case 57587: break: // Steal Ranged () + //case 57594: break; // Copy Ranged Weapon + //case 59237: break; // Beast's Mark + // trigger_spell_id = 59233; break; + //case 59288: break; // Infra-Green Shield + //case 59532: break; // Abandon Passengers on Poly + //case 59735: break: // Woe Strike + case 67702: // Death's Choice, Item - Coliseum 25 Normal Melee Trinket { 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; } - else if (auraSpellInfo->Id==67771) // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket + case 67771: // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket { 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; } - //else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1) - //else if (auraSpellInfo->Id==5301) // Defensive State (DND) - //else if (auraSpellInfo->Id==13358) // Defensive State (DND) - //else if (auraSpellInfo->Id==16092) // Defensive State (DND) - //else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND) - //else if (auraSpellInfo->Id==40329) // Demo Shout Sensor - else if (auraSpellInfo->Id == 33896) // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher) - trigger_spell_id = 33898; - //else if (auraSpellInfo->Id==18943) // Double Attack - //else if (auraSpellInfo->Id==19194) // Double Attack - //else if (auraSpellInfo->Id==19817) // Double Attack - //else if (auraSpellInfo->Id==19818) // Double Attack - //else if (auraSpellInfo->Id==22835) // Drunken Rage - // trigger_spell_id = 14822; - /* - else if (auraSpellInfo->SpellIconID==191) // Elemental Response - { - switch (auraSpellInfo->Id && auraSpellInfo->AttributesEx==0) - { - case 34191: - case 34329: - case 34524: - case 34582: - case 36733: - break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Elemental Response",auraSpellInfo->Id); - return false; - } - //This generic aura self-triggers a different spell for each school of magic that lands on the wearer: - switch (procSpell->School) - { - case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192; break; - case SPELL_SCHOOL_FROST: trigger_spell_id = 34193; break; - case SPELL_SCHOOL_ARCANE:trigger_spell_id = 34194; break; - case SPELL_SCHOOL_NATURE:trigger_spell_id = 34195; break; - case SPELL_SCHOOL_SHADOW:trigger_spell_id = 34196; break; - case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197; break; - case SPELL_SCHOOL_NORMAL:trigger_spell_id = 34198; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u Elemental Response wrong school",auraSpellInfo->Id); - return false; - } - } - */ - //else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor - //else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget - //else if (auraSpellInfo->Id==50051) // Ethereal Pet Aura - //else if (auraSpellInfo->Id==35321) // Gushing Wound - //else if (auraSpellInfo->Id==38363) // Gushing Wound - //else if (auraSpellInfo->Id==39215) // Gushing Wound - //else if (auraSpellInfo->Id==44527) // Hate Monster (Spar Buddy) (30 sec) - //else if (auraSpellInfo->Id==44819) // Hate Monster (Spar Buddy) (>30% Health) - //else if (auraSpellInfo->Id==44526) // Hate Monster (Spar) (30 sec) - //else if (auraSpellInfo->Id==44820) // Hate Monster (Spar) (<30%) - //else if (auraSpellInfo->Id==49059) // Horde, Hate Monster (Spar Buddy) (>30% Health) - //else if (auraSpellInfo->Id==40250) // Improved Duration - //else if (auraSpellInfo->Id==59288) // Infra-Green Shield - //else if (auraSpellInfo->Id==54072) // Knockback Ball Passive - else if (auraSpellInfo->Id==27522 || auraSpellInfo->Id==40336) - // Mana Drain Trigger - { - // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target. - if (this && this->isAlive()) - CastSpell(this, 29471, true, castItem, triggeredByAura); - if (pVictim && pVictim->isAlive()) - CastSpell(pVictim, 27526, true, castItem, triggeredByAura); - return true; - } - //else if (auraSpellInfo->Id==55580) // Mana Link - //else if (auraSpellInfo->Id==45903) // Offensive State - //else if (auraSpellInfo->Id==44326) // Pure Energy Passive - //else if (auraSpellInfo->Id==43453) // Rune Ward - //else if (auraSpellInfo->Id== 7137) // Shadow Charge (Rank 1) - //else if (auraSpellInfo->Id==36576) // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger - //else if (auraSpellInfo->Id==34783) // Spell Reflection - //else if (auraSpellInfo->Id==36096) // Spell Reflection - //else if (auraSpellInfo->Id==57587) // Steal Ranged () - //else if (auraSpellInfo->Id==36207) // Steal Weapon - //else if (auraSpellInfo->Id== 7377) // Take Immune Periodic Damage - //else if (auraSpellInfo->Id==35205) // Vanish - //else if (auraSpellInfo->Id==42730) // Woe Strike - //else if (auraSpellInfo->Id==59735) // Woe Strike - //else if (auraSpellInfo->Id==46146) // [PH] Ahune Spanky Hands - 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: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id); - return false; - } - } - break; - case SPELLFAMILY_WARRIOR: - if (auraSpellInfo->Id == 50421) // Scent of Blood - trigger_spell_id = 50422; - break; - case SPELLFAMILY_WARLOCK: + } + break; + case SPELLFAMILY_MAGE: + if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed { - // Pyroclasm - if (auraSpellInfo->SpellIconID == 1137) + switch (auraSpellInfo->Id) { - if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL) + case 31641: // Rank 1 + case 31642: // Rank 2 + trigger_spell_id = 31643; + break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id); return false; - // Calculate spell tick count for spells - uint32 tick = 1; // Default tick = 1 - - // Hellfire have 15 tick - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000040)) - tick = 15; - // Rain of Fire have 4 tick - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020)) - tick = 4; - else - return false; - - // Calculate chance = baseChance / tick - float chance = 0; - switch (auraSpellInfo->Id) - { - case 18096: chance = 13.0f / tick; break; - case 18073: chance = 26.0f / tick; break; - } - // Roll chance - if (!roll_chance_f(chance)) - return false; - - trigger_spell_id = 18093; } - // Drain Soul - else if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + } + // Persistent Shield (Scarab Brooch trinket) + else if(auraSpellInfo->Id == 26467) + { + // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect) + basepoints[0] = damage * 15 / 100; + target = pVictim; + trigger_spell_id = 26470; + } + break; + case SPELLFAMILY_WARRIOR: + if (auraSpellInfo->Id == 50421) // Scent of Blood + trigger_spell_id = 50422; + break; + case SPELLFAMILY_WARLOCK: + { + // Pyroclasm + if (auraSpellInfo->SpellIconID == 1137) + { + if(!pVictim || !pVictim->isAlive() || pVictim == this || procSpell == NULL) + return false; + // Calculate spell tick count for spells + uint32 tick = 1; // Default tick = 1 + + // Hellfire have 15 tick + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000040)) + tick = 15; + // Rain of Fire have 4 tick + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020)) + tick = 4; + else + return false; + + // Calculate chance = baseChance / tick + float chance = 0; + switch (auraSpellInfo->Id) { - Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); - for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) + case 18096: chance = 13.0f / tick; break; + case 18073: chance = 26.0f / tick; break; + } + // Roll chance + if (!roll_chance_f(chance)) + return false; + + trigger_spell_id = 18093; + } + // Drain Soul + else if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + { + Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); + for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) + { + if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113) { - if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113) - { - // Drain Soul - CastCustomSpell(this, 18371, &basepoints[0], NULL, NULL, true, castItem, triggeredByAura); - break; - } + // Drain Soul + CastCustomSpell(this, 18371, &basepoints[0], NULL, NULL, true, castItem, triggeredByAura); + break; } - // Not remove charge (aura removed on death in any cases) - // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura + } + // Not remove charge (aura removed on death in any cases) + // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura + return false; + } + // Nether Protection + else if (auraSpellInfo->SpellIconID == 1985) + { + if (!procSpell) + return false; + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + 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; + } + } + // Cheat Death + else if (auraSpellInfo->Id == 28845) + { + // When your health drops below 20% .... + if (GetHealth() - damage > GetMaxHealth() / 5 || GetHealth() < GetMaxHealth() / 5) + return false; + } + // Decimation + else if (auraSpellInfo->Id == 63156 || auraSpellInfo->Id == 63158) + { + // Looking for dummy effect + Aura *aur = GetAura(auraSpellInfo->Id, 1); + if (!aur) + return false; + + // If target's health is not below equal certain value (35%) not proc + if ((pVictim->GetHealth() * 100 / pVictim->GetMaxHealth()) > aur->GetModifier()->m_amount) + return false; + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Greater Heal Refund (Avatar Raiment set) + if (auraSpellInfo->Id==37594) + { + // Not give if target already have full health + if (pVictim->GetHealth() == pVictim->GetMaxHealth()) + return false; + // If your Greater Heal brings the target to full health, you gain $37595s1 mana. + if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth()) + return false; + trigger_spell_id = 37595; + } + // Blessed Recovery + else 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: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id); return false; } - // Nether Protection - else if (auraSpellInfo->SpellIconID == 1985) - { - if (!procSpell) - return false; - switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) - { - 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; + basepoints[0] = damage * triggerAmount / 100 / 3; + target = this; } - case SPELLFAMILY_PRIEST: - { - // Greater Heal Refund - if (auraSpellInfo->Id==37594) - trigger_spell_id = 37595; - // Blessed Recovery - else 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: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id); - return false; - } - basepoints[0] = damage * triggerAmount / 100 / 3; - target = this; - } - break; - } - case SPELLFAMILY_DRUID: - { - // Druid Forms Trinket - if (auraSpellInfo->Id==37336) - { - switch(m_form) - { - 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; - } - } - // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) - else if (auraSpellInfo->Id==67353) - { - switch(m_form) - { - case FORM_CAT: trigger_spell_id = 67355; break; - case FORM_BEAR: - case FORM_DIREBEAR: trigger_spell_id = 67354; break; - default: - return false; - } - } - break; - } - case SPELLFAMILY_HUNTER: - // Piercing Shots - if (auraSpellInfo->SpellIconID == 3247 && auraSpellInfo->SpellVisual[0] == 0) - { - basepoints[0] = damage * triggerAmount / 100 / 8; - trigger_spell_id = 63468; - target = pVictim; - } - break; - case SPELLFAMILY_PALADIN: - { - /* - // Blessed Life - if (auraSpellInfo->SpellIconID == 2137) - { - switch (auraSpellInfo->Id) - { - case 31828: // Rank 1 - case 31829: // Rank 2 - case 31830: // Rank 3 - break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id); - return false; - } - } - */ - // Healing Discount - if (auraSpellInfo->Id==37705) - { - trigger_spell_id = 37706; - target = this; - } - // Soul Preserver - if (auraSpellInfo->Id==60510) - { - trigger_spell_id = 60515; - target = this; - } - // Illumination - else 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 & UI64LIT(0x0001000000000000)) - { - 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: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id); - return false; - } - } - SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); - if(!originalSpell) - { - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId); - return false; - } - // percent stored in effect 1 (class scripts) base points - int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost*auraSpellInfo->CalculateSimpleValue(1)/100; - trigger_spell_id = 20272; - target = this; - } - // Lightning Capacitor - else if (auraSpellInfo->Id==37657) - { - if(!pVictim || !pVictim->isAlive()) - return false; - // stacking - CastSpell(this, 37658, true, NULL, triggeredByAura); - - Aura * dummy = GetDummyAura(37658); - // release at 3 aura in stack (cont contain in basepoint of trigger aura) - if(!dummy || dummy->GetStackAmount() < triggerAmount) - return false; - - RemoveAurasDueToSpell(37658); - trigger_spell_id = 37661; - target = pVictim; - } - // Thunder Capacitor - else if (auraSpellInfo->Id == 54841) - { - if(!pVictim || !pVictim->isAlive()) - return false; - // stacking - CastSpell(this, 54842, true, NULL, triggeredByAura); - - // counting - Aura * dummy = GetDummyAura(54842); - // release at 3 aura in stack (cont contain in basepoint of trigger aura) - if(!dummy || dummy->GetStackAmount() < triggerAmount) - return false; - - RemoveAurasDueToSpell(54842); - trigger_spell_id = 54843; - target = pVictim; - } - break; - } - case SPELLFAMILY_SHAMAN: - { - // Lightning Shield (overwrite non existing triggered spell call in spell.dbc - if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) - { - switch(auraSpellInfo->Id) - { - case 324: // Rank 1 - trigger_spell_id = 26364; break; - case 325: // Rank 2 - trigger_spell_id = 26365; break; - case 905: // Rank 3 - trigger_spell_id = 26366; break; - case 945: // Rank 4 - trigger_spell_id = 26367; break; - case 8134: // Rank 5 - trigger_spell_id = 26369; break; - case 10431: // Rank 6 - trigger_spell_id = 26370; break; - case 10432: // Rank 7 - trigger_spell_id = 26363; break; - case 25469: // Rank 8 - trigger_spell_id = 26371; break; - case 25472: // Rank 9 - trigger_spell_id = 26372; break; - case 49280: // Rank 10 - trigger_spell_id = 49278; break; - case 49281: // Rank 11 - trigger_spell_id = 49279; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id); - return false; - } - } - // Lightning Shield (The Ten Storms set) - else if (auraSpellInfo->Id == 23551) - { - trigger_spell_id = 23552; - target = pVictim; - } - // Damage from Lightning Shield (The Ten Storms set) - else if (auraSpellInfo->Id == 23552) - trigger_spell_id = 27635; - // Mana Surge (The Earthfury set) - else if (auraSpellInfo->Id == 23572) - { - if(!procSpell) - return false; - basepoints[0] = procSpell->manaCost * 35 / 100; - trigger_spell_id = 23571; - target = this; - } - // Nature's Guardian - else if (auraSpellInfo->SpellIconID == 2013) - { - // Check health condition - should drop to less 30% (damage deal after this!) - if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth())) - return false; - - if(pVictim && pVictim->isAlive()) - pVictim->getThreatManager().modifyThreatPercent(this,-10); - - basepoints[0] = triggerAmount * GetMaxHealth() / 100; - trigger_spell_id = 31616; - target = this; - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Acclimation - if (auraSpellInfo->SpellIconID == 1930) - { - if (!procSpell) - return false; - switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) - { - 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 - else if (auraSpellInfo->Id == 48266) - { - if (GetTypeId() != TYPEID_PLAYER) - return false; - if (!((Player*)this)->isHonorOrXPTarget(pVictim)) - return false; - trigger_spell_id = 50475; - basepoints[0] = damage * triggerAmount / 100; - } - break; - } - default: - break; + break; } + case SPELLFAMILY_DRUID: + { + // Druid Forms Trinket + if (auraSpellInfo->Id==37336) + { + switch(m_form) + { + 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; + } + } + // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) + else if (auraSpellInfo->Id==67353) + { + switch(m_form) + { + case FORM_CAT: trigger_spell_id = 67355; break; + case FORM_BEAR: + case FORM_DIREBEAR: trigger_spell_id = 67354; break; + default: + return false; + } + } + break; + } + case SPELLFAMILY_HUNTER: + // Piercing Shots + if (auraSpellInfo->SpellIconID == 3247 && auraSpellInfo->SpellVisual[0] == 0) + { + basepoints[0] = damage * triggerAmount / 100 / 8; + trigger_spell_id = 63468; + target = pVictim; + } + // Rapid Recuperation + else if (auraSpellInfo->Id == 53228 || auraSpellInfo->Id == 53232) + { + // This effect only from Rapid Fire (ability cast) + if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020))) + return false; + } + break; + case SPELLFAMILY_PALADIN: + { + /* + // Blessed Life + if (auraSpellInfo->SpellIconID == 2137) + { + switch (auraSpellInfo->Id) + { + case 31828: // Rank 1 + case 31829: // Rank 2 + case 31830: // Rank 3 + break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id); + return false; + } + } + */ + // Healing Discount + if (auraSpellInfo->Id==37705) + { + trigger_spell_id = 37706; + target = this; + } + // Soul Preserver + if (auraSpellInfo->Id==60510) + { + trigger_spell_id = 60515; + target = this; + } + // Illumination + else 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 & UI64LIT(0x0001000000000000)) + { + 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: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id); + return false; + } + } + SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); + if(!originalSpell) + { + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId); + return false; + } + // percent stored in effect 1 (class scripts) base points + int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100; + basepoints[0] = cost*auraSpellInfo->CalculateSimpleValue(1)/100; + trigger_spell_id = 20272; + target = this; + } + // Lightning Capacitor + else if (auraSpellInfo->Id==37657) + { + if(!pVictim || !pVictim->isAlive()) + return false; + // stacking + CastSpell(this, 37658, true, NULL, triggeredByAura); + + Aura * dummy = GetDummyAura(37658); + // release at 3 aura in stack (cont contain in basepoint of trigger aura) + if(!dummy || dummy->GetStackAmount() < triggerAmount) + return false; + + RemoveAurasDueToSpell(37658); + trigger_spell_id = 37661; + target = pVictim; + } + // Bonus Healing (Crystal Spire of Karabor mace) + else if (auraSpellInfo->Id == 40971) + { + // If your target is below $s1% health + if (pVictim->GetHealth() > pVictim->GetMaxHealth() * triggerAmount / 100) + return false; + } + // Thunder Capacitor + else if (auraSpellInfo->Id == 54841) + { + if(!pVictim || !pVictim->isAlive()) + return false; + // stacking + CastSpell(this, 54842, true, NULL, triggeredByAura); + + // counting + Aura * dummy = GetDummyAura(54842); + // release at 3 aura in stack (cont contain in basepoint of trigger aura) + if(!dummy || dummy->GetStackAmount() < triggerAmount) + return false; + + RemoveAurasDueToSpell(54842); + trigger_spell_id = 54843; + target = pVictim; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + // Lightning Shield (overwrite non existing triggered spell call in spell.dbc + if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) + { + switch(auraSpellInfo->Id) + { + case 324: // Rank 1 + trigger_spell_id = 26364; break; + case 325: // Rank 2 + trigger_spell_id = 26365; break; + case 905: // Rank 3 + trigger_spell_id = 26366; break; + case 945: // Rank 4 + trigger_spell_id = 26367; break; + case 8134: // Rank 5 + trigger_spell_id = 26369; break; + case 10431: // Rank 6 + trigger_spell_id = 26370; break; + case 10432: // Rank 7 + trigger_spell_id = 26363; break; + case 25469: // Rank 8 + trigger_spell_id = 26371; break; + case 25472: // Rank 9 + trigger_spell_id = 26372; break; + case 49280: // Rank 10 + trigger_spell_id = 49278; break; + case 49281: // Rank 11 + trigger_spell_id = 49279; break; + default: + sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id); + return false; + } + } + // Lightning Shield (The Ten Storms set) + else if (auraSpellInfo->Id == 23551) + { + trigger_spell_id = 23552; + target = pVictim; + } + // Damage from Lightning Shield (The Ten Storms set) + else if (auraSpellInfo->Id == 23552) + trigger_spell_id = 27635; + // Mana Surge (The Earthfury set) + else if (auraSpellInfo->Id == 23572) + { + if(!procSpell) + return false; + basepoints[0] = procSpell->manaCost * 35 / 100; + trigger_spell_id = 23571; + target = this; + } + // Nature's Guardian + else if (auraSpellInfo->SpellIconID == 2013) + { + // Check health condition - should drop to less 30% (damage deal after this!) + if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth())) + return false; + + if(pVictim && pVictim->isAlive()) + pVictim->getThreatManager().modifyThreatPercent(this,-10); + + basepoints[0] = triggerAmount * GetMaxHealth() / 100; + trigger_spell_id = 31616; + target = this; + } + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Acclimation + if (auraSpellInfo->SpellIconID == 1930) + { + if (!procSpell) + return false; + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + 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 + else if (auraSpellInfo->Id == 48266) + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + if (!((Player*)this)->isHonorOrXPTarget(pVictim)) + return false; + trigger_spell_id = 50475; + basepoints[0] = damage * triggerAmount / 100; + } + // Blade Barrier + else if (auraSpellInfo->SpellIconID == 85) + { + if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT || + !((Player*)this)->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) + return false; + } + break; + } + default: + break; } // All ok. Check current trigger spell SpellEntry const* triggerEntry = sSpellStore.LookupEntry(trigger_spell_id); - if ( triggerEntry == NULL ) + if (!triggerEntry) { // Not cast unknown spell // sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex()); @@ -7325,100 +7385,9 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB } // not allow proc extra attack spell at extra attack - if( m_extraAttacks && IsSpellHaveEffect(triggerEntry, SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) + if (m_extraAttacks && IsSpellHaveEffect(triggerEntry, SPELL_EFFECT_ADD_EXTRA_ATTACKS)) return false; - // Custom requirements (not listed in procEx) Warning! damage dealing after this - // Custom triggered spells - switch (auraSpellInfo->Id) - { - // Persistent Shield (Scarab Brooch trinket) - // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect) - case 26467: - { - basepoints[0] = damage * 15 / 100; - target = pVictim; - trigger_spell_id = 26470; - break; - } - // Cheat Death - case 28845: - { - // When your health drops below 20% .... - if (GetHealth() - damage > GetMaxHealth() / 5 || GetHealth() < GetMaxHealth() / 5) - return false; - break; - } - // Deadly Swiftness (Rank 1) - case 31255: - { - // whenever you deal damage to a target who is below 20% health. - if (pVictim->GetHealth() > pVictim->GetMaxHealth() / 5) - return false; - - target = this; - trigger_spell_id = 22588; - } - // Greater Heal Refund (Avatar Raiment set) - case 37594: - { - // Not give if target already have full health - if (pVictim->GetHealth() == pVictim->GetMaxHealth()) - return false; - // If your Greater Heal brings the target to full health, you gain $37595s1 mana. - if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth()) - return false; - break; - } - // Bonus Healing (Crystal Spire of Karabor mace) - case 40971: - { - // If your target is below $s1% health - if (pVictim->GetHealth() > pVictim->GetMaxHealth() * triggerAmount / 100) - return false; - break; - } - // Evasive Maneuvers (Commendation of Kael`thas trinket) - case 45057: - { - // reduce you below $s1% health - if (GetHealth() - damage > GetMaxHealth() * triggerAmount / 100) - return false; - break; - } - // Rapid Recuperation - case 53228: - case 53232: - { - // This effect only from Rapid Fire (ability cast) - if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020))) - return false; - break; - } - // Decimation - case 63156: - case 63158: - { - // Looking for dummy effect - Aura *aur = GetAura(auraSpellInfo->Id, 1); - if (!aur) - return false; - - // If target's health is not below equal certain value (35%) not proc - if ((pVictim->GetHealth() * 100 / pVictim->GetMaxHealth()) > aur->GetModifier()->m_amount) - return false; - - break; - } - } - // Blade Barrier - if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 85) - { - if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT || - !((Player*)this)->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) - return false; - } - // Custom basepoints/target for exist spell // dummy basepoints or other customs switch(trigger_spell_id) @@ -9492,7 +9461,7 @@ uint32 Unit::MeleeDamageBonus(Unit *pVictim, uint32 pdamage,WeaponAttackType att // differentiate for weapon damage based spells bool isWeaponDamageBasedSpell = !(spellProto && (damagetype == DOT || IsSpellHaveEffect(spellProto, SPELL_EFFECT_SCHOOL_DAMAGE))); - Item* pWeapon = GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetWeaponForAttack(attType) : NULL; + Item* pWeapon = GetTypeId() == TYPEID_PLAYER ? ((Player*)this)->GetWeaponForAttack(attType,true,false) : NULL; uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); uint32 schoolMask = spellProto ? spellProto->SchoolMask : GetMeleeDamageSchoolMask(); uint32 mechanicMask = spellProto ? GetAllSpellMechanicMask(spellProto) : 0; @@ -11435,6 +11404,7 @@ void Unit::RemoveFromWorld() RemoveGuardians(); RemoveAllGameObjects(); RemoveAllDynObjects(); + CleanupDeletedAuars(); } Object::RemoveFromWorld(); @@ -11631,12 +11601,12 @@ void CharmInfo::LoadPetActionBar(const std::string& data ) Tokens tokens = StrSplit(data, " "); - if (tokens.size() != (ACTION_BAR_INDEX_PET_SPELL_END-ACTION_BAR_INDEX_PET_SPELL_START)*2) + if (tokens.size() != (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START)*2) return; // non critical, will reset to default int index; Tokens::iterator iter; - for(iter = tokens.begin(), index = ACTION_BAR_INDEX_PET_SPELL_START; index < ACTION_BAR_INDEX_PET_SPELL_END; ++iter, ++index ) + for(iter = tokens.begin(), index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++iter, ++index ) { // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion uint8 type = atol((*iter).c_str()); @@ -12593,7 +12563,7 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) if (!normalized || GetTypeId() != TYPEID_PLAYER) return float(GetAttackTime(attType))/1000.0f; - Item *Weapon = ((Player*)this)->GetWeaponForAttack(attType); + Item *Weapon = ((Player*)this)->GetWeaponForAttack(attType, true, false); if (!Weapon) return 2.4; // fist attack @@ -12846,26 +12816,6 @@ bool Unit::HandleMendingAuraProc( Aura* triggeredByAura ) return true; } -void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo) -{ - uint64 target_guid = GetChannelObjectGUID(); - - if(!IS_UNIT_GUID(target_guid)) - return; - - Unit* target = ObjectAccessor::GetUnit(*this, target_guid); - if(!target) - return; - - for (AuraMap::iterator iter = target->GetAuras().begin(); iter != target->GetAuras().end(); ) - { - if (iter->second->GetId() == spellInfo->Id && iter->second->GetCasterGUID()==GetGUID()) - target->RemoveAura(iter); - else - ++iter; - } -} - void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive /*= false*/) { Unit::AuraMap& auras = GetAuras(); @@ -13098,3 +13048,11 @@ void Unit::StopAttackFaction(uint32 faction_id) if(Unit* guardian = Unit::GetUnit(*this,*itr)) guardian->StopAttackFaction(faction_id); } + +void Unit::CleanupDeletedAuars() +{ + // really delete auras "deleted" while processing its ApplyModify code + for(AuraList::const_iterator itr = m_deletedAuras.begin(); itr != m_deletedAuras.end(); ++itr) + delete *itr; + m_deletedAuras.clear(); +} \ No newline at end of file diff --git a/src/game/Unit.h b/src/game/Unit.h index cec3d61a8..3f942586e 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1247,7 +1247,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID); void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToSpellByCancel(uint32 spellId); - void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo); // removing unknown aura stacks by diff reasons and selections void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); @@ -1618,6 +1617,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject uint32 m_lastManaUseTimer; private: + void CleanupDeletedAuars(); + bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ); bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 60f8b5477..02add44f4 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -45,18 +45,20 @@ alter table creature_movement add `wpguid` int(11) default '0'; //-----------------------------------------------// void WaypointMovementGenerator::LoadPath(Creature &c) { - sLog.outDetail("LoadPath: loading waypoint path for creature %d,%d", c.GetGUIDLow(), c.GetDBTableGUIDLow()); + sLog.outDetail("LoadPath: loading waypoint path for creature %u, %u", c.GetGUIDLow(), c.GetDBTableGUIDLow()); i_path = sWaypointMgr.GetPath(c.GetDBTableGUIDLow()); - if(!i_path) + + if (!i_path) { - sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %d) doesn't have waypoint path", + sLog.outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path", c.GetName(), c.GetEntry(), c.GetDBTableGUIDLow()); return; } uint32 node_count = i_path->size(); i_hasDone.resize(node_count); + for(uint32 i = 0; i < node_count-1; ++i) i_hasDone[i] = false; @@ -78,22 +80,23 @@ void WaypointMovementGenerator::Initialize() bool WaypointMovementGenerator::Update(Creature &creature, const uint32 &diff) { - if(!&creature) + if (!&creature) return true; // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff - if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED)) + if (creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED | UNIT_STAT_DIED)) return true; // prevent a crash at empty waypoint path. - if(!i_path || i_path->empty()) + if (!i_path || i_path->empty()) return true; // i_path was modified by chat commands for example - if(i_path->size() != i_hasDone.size()) + if (i_path->size() != i_hasDone.size()) i_hasDone.resize(i_path->size()); - if(i_currentNode >= i_path->size()) + + if (i_currentNode >= i_path->size()) i_currentNode = 0; CreatureTraveller traveller(creature); @@ -104,56 +107,67 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 // creature has been stopped in middle of the waypoint segment if (!i_destinationHolder.HasArrived() && creature.IsStopped()) { - if( i_nextMoveTime.Passed()) // Timer has elapsed, meaning this part controlled it + // Timer has elapsed, meaning this part controlled it + if (i_nextMoveTime.Passed()) { SetStoppedByPlayer(false); - // Now we re-set destination to same node and start travel + creature.addUnitState(UNIT_STAT_ROAMING); + if (creature.canFly()) creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); + + // Now we re-set destination to same node and start travel const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); } else // if( !i_nextMoveTime.Passed()) - { // unexpected end of timer && creature stopped && not at end of segment + { + // unexpected end of timer && creature stopped && not at end of segment if (!IsStoppedByPlayer()) - { // Put 30 seconds delay + { + // Put 30 seconds delay i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER); i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER); - SetStoppedByPlayer(true); // Mark we did it + SetStoppedByPlayer(true); // Mark we did it } } - return true; // Abort here this update + return true; // Abort here this update } - if( creature.IsStopped()) + if (creature.IsStopped()) { uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; if (!i_hasDone[idx]) { - if (i_path->at(idx).orientation !=100) + if (i_path->at(idx).orientation != 100) creature.SetOrientation(i_path->at(idx).orientation); - if(WaypointBehavior *behavior = i_path->at(idx).behavior) + if (WaypointBehavior *behavior = i_path->at(idx).behavior) { - if(behavior->emote != 0) - creature.SetUInt32Value(UNIT_NPC_EMOTESTATE,behavior->emote); - if(behavior->spell != 0) - creature.CastSpell(&creature,behavior->spell, false); - if(behavior->model1 != 0) + if (behavior->emote != 0) + creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, behavior->emote); + + if (behavior->spell != 0) + creature.CastSpell(&creature, behavior->spell, false); + + if (behavior->model1 != 0) creature.SetDisplayId(behavior->model1); - if(behavior->textid[0]) + + if (behavior->textid[0]) { // Not only one text is set - if( behavior->textid[1] ) + if (behavior->textid[1]) { - // Select one from max 5 texts (0 and 1 laready checked) + // Select one from max 5 texts (0 and 1 already checked) int i = 2; - for( ; i < MAX_WAYPOINT_TEXT; ++i ) - if( !behavior->textid[i] ) + for(; i < MAX_WAYPOINT_TEXT; ++i) + { + if (!behavior->textid[i]) break; + } creature.Say(behavior->textid[rand() % i], 0, 0); } @@ -167,37 +181,46 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 } // HasDone == false } // i_creature.IsStopped() - if( i_nextMoveTime.Passed() ) // This is at the end of waypoint segment or has been stopped by player + // This is at the end of waypoint segment or has been stopped by player + if (i_nextMoveTime.Passed()) { - if( creature.IsStopped() ) // If stopped then begin a new move segment + // If stopped then begin a new move segment + if (creature.IsStopped()) { creature.addUnitState(UNIT_STAT_ROAMING); + if (creature.canFly()) creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); + const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); + uint32 idx = i_currentNode > 0 ? i_currentNode-1 : i_path->size()-1; - if (i_path->at(idx).orientation !=100) + if (i_path->at(idx).orientation != 100) creature.SetOrientation(i_path->at(idx).orientation); - if(WaypointBehavior *behavior = i_path->at(idx).behavior ) + if (WaypointBehavior *behavior = i_path->at(idx).behavior) { i_hasDone[idx] = false; - if(behavior->model2 != 0) + + if (behavior->model2 != 0) creature.SetDisplayId(behavior->model2); creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); } } - else // If not stopped then stop it and set the reset of TimeTracker to waittime + else { + // If not stopped then stop it and set the reset of TimeTracker to waittime creature.StopMoving(); SetStoppedByPlayer(false); + i_nextMoveTime.Reset(i_path->at(i_currentNode).delay); ++i_currentNode; - if( i_currentNode >= i_path->size() ) + + if (i_currentNode >= i_path->size()) i_currentNode = 0; } } @@ -206,7 +229,7 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 void WaypointMovementGenerator::MovementInform(Creature &unit) { - if(unit.AI()) + if (unit.AI()) unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 063790663..221acd420 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8971" + #define REVISION_NR "8997" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 21a7eef2a..ac8865c84 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8965_02_mangos_command" + #define REVISION_DB_MANGOS "required_8996_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__