Merge remote branch 'origin/master' into 330

This commit is contained in:
tomrus88 2009-12-16 02:45:05 +03:00
commit c745c5072f
31 changed files with 1000 additions and 760 deletions

View file

@ -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),

View file

@ -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');

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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
{

View file

@ -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()) << " ";

View file

@ -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));
}
}
}

View file

@ -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)

View file

@ -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<Item *> &GetItemUpdateQueue() { return m_itemUpdateQueue; }

View file

@ -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)

View file

@ -628,29 +628,22 @@ void Aura::Update(uint32 diff)
return;
}
// need check distance for channeled target only
if (caster->GetChannelObjectGUID() == m_target->GetGUID())
{
// Get spell range
float radius;
SpellModOp mod;
if (m_spellProto->EffectRadiusIndex[GetEffIndex()])
{
radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[GetEffIndex()]));
mod = SPELLMOD_RADIUS;
}
else
{
radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex));
mod = SPELLMOD_RANGE;
}
float max_range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex));
if(Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(GetId(), mod, radius, NULL);
modOwner->ApplySpellMod(GetId(), SPELLMOD_RANGE, max_range, NULL);
if(!caster->IsWithinDistInMap(m_target, radius))
if(!caster->IsWithinDistInMap(m_target, max_range))
{
m_target->RemoveAura(GetId(), GetEffIndex());
return;
}
}
}
if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent))
{
@ -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<uint32> affectedSelf;
std::set<uint32> 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?

View file

@ -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;

View file

@ -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)
{

View file

@ -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)

View file

@ -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;
}
}
// 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)
{
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)
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)
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 <Not Working>
//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;
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,107 +6930,35 @@ 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; }
}
//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 <Not Working>
//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
@ -6969,6 +6974,14 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
return false;
}
}
// 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
@ -7042,13 +7055,40 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
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
// 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)
{
@ -7105,6 +7145,13 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
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:
{
@ -7189,6 +7236,13 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
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)
{
@ -7308,16 +7362,22 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
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();
}

View file

@ -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);

View file

@ -45,18 +45,20 @@ alter table creature_movement add `wpguid` int(11) default '0';
//-----------------------------------------------//
void WaypointMovementGenerator<Creature>::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<Creature>::Initialize()
bool WaypointMovementGenerator<Creature>::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,21 +107,27 @@ bool WaypointMovementGenerator<Creature>::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
@ -127,33 +136,38 @@ bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint3
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<Creature>::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<Creature>::Update(Creature &creature, const uint3
void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
{
if(unit.AI())
if (unit.AI())
unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8971"
#define REVISION_NR "8997"
#endif // __REVISION_NR_H__

View file

@ -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__