Just merge commit 'origin/master' into 320

Conflicts:
	src/game/MiscHandler.cpp
This commit is contained in:
tomrus88 2009-07-28 17:05:38 +04:00
commit be8eaf4e46
33 changed files with 1089 additions and 863 deletions

View file

@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` ( CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`required_8251_03_mangos_spell_proc_event` bit(1) default NULL `required_8254_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -15649,7 +15649,7 @@ INSERT INTO spell_chain VALUES
(27219,11700,689,7,0), (27219,11700,689,7,0),
(27220,27219,689,8,0), (27220,27219,689,8,0),
(47857,27220,689,9,0), (47857,27220,689,9,0),
/*DrainSoul*/ /*Drain Soul*/
(1120,0,1120,1,0), (1120,0,1120,1,0),
(8288,1120,1120,2,0), (8288,1120,1120,2,0),
(8289,8288,1120,3,0), (8289,8288,1120,3,0),
@ -15665,14 +15665,20 @@ INSERT INTO spell_chain VALUES
(59161,48181,48181,2,0), (59161,48181,48181,2,0),
(59163,59161,48181,3,0), (59163,59161,48181,3,0),
(59164,59163,48181,4,0), (59164,59163,48181,4,0),
/*HowlofTerror*/ /*Howl of Terror*/
(5484,0,5484,1,0), (5484,0,5484,1,0),
(17928,5484,5484,2,0), (17928,5484,5484,2,0),
/*SeedofCorruption*/ /*Seed of Corruption*/
(27243,0,27243,1,0), (27243,0,27243,1,0),
(47835,27243,27243,2,0), (47835,27243,27243,2,0),
(47836,47835,27243,3,0), (47836,47835,27243,3,0),
/*UnstableAffliction*/ /* Shadow embrace */
(32385,0,32385,1,0),
(32387,32385,32385,2,0),
(32392,32387,32385,3,0),
(32393,32392,32385,4,0),
(32394,32393,32385,5,0),
/*Unstable Affliction*/
(30108,0,30108,1,0), (30108,0,30108,1,0),
(30404,30108,30108,2,0), (30404,30108,30108,2,0),
(30405,30404,30108,3,0), (30405,30404,30108,3,0),
@ -15771,6 +15777,12 @@ INSERT INTO spell_chain VALUES
(26372,26371,26364,9,0), (26372,26371,26364,9,0),
(49278,26372,26364,10,0), (49278,26372,26364,10,0),
(49279,49278,26364,11,0), (49279,49278,26364,11,0),
/*Maelstrom Weapon*/
(51528,0,51528,1,0),
(51529,51528,51528,2,0),
(51530,51529,51528,3,0),
(51531,51530,51528,4,0),
(51532,51531,51528,5,0),
/*Nature Resistance Totem*/ /*Nature Resistance Totem*/
(10595,0,10595,1,0), (10595,0,10595,1,0),
(10600,10595,10595,2,0), (10600,10595,10595,2,0),
@ -17239,7 +17251,7 @@ INSERT INTO `spell_proc_event` VALUES
(12999, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), (12999, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0),
(13000, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), (13000, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0),
(13001, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 8.000000, 0.000000, 0), (13001, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 8.000000, 0.000000, 0),
(13002, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 10.000000, 0.000000, 0), (13002, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,10.000000, 0.000000, 0),
(13045, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (13045, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(13046, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (13046, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(13047, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (13047, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@ -17333,8 +17345,8 @@ INSERT INTO `spell_proc_event` VALUES
(20131, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (20131, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(20132, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (20132, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(20164, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), (20164, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0),
(20165, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 20.000000, 0.000000, 0), (20165, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0),
(20166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 20.000000, 0.000000, 0), (20166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0),
(20182, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (20182, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(20210, 0x00000000, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (20210, 0x00000000, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(20212, 0x00000000, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (20212, 0x00000000, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@ -17372,7 +17384,7 @@ INSERT INTO `spell_proc_event` VALUES
(24353, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (24353, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(24389, 0x00000000, 3, 0x00C00017, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (24389, 0x00000000, 3, 0x00C00017, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(24658, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00014110, 0x00000000, 0.000000, 0.000000, 0), (24658, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00014110, 0x00000000, 0.000000, 0.000000, 0),
(24905, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 15.000000, 0.000000, 0), (24905, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,15.000000, 0.000000, 0),
(24932, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), (24932, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6),
(25050, 0x00000004, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (25050, 0x00000004, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(25669, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), (25669, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0),
@ -17468,7 +17480,7 @@ INSERT INTO `spell_proc_event` VALUES
(31570, 0x00000000, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31570, 0x00000000, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(31785, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0), (31785, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0),
(31794, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (31794, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(31801, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 20.000000, 0.000000, 0), (31801, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0),
(31833, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31833, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(31835, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31835, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(31836, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31836, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@ -17478,11 +17490,7 @@ INSERT INTO `spell_proc_event` VALUES
(31877, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0), (31877, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0),
(31878, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0), (31878, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0),
(31904, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (31904, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(32385, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (32385, 0x00000000, 5, 0x00000001, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32387, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32392, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32393, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32394, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32409, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (32409, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32587, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (32587, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(32642, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), (32642, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
@ -17758,6 +17766,7 @@ INSERT INTO `spell_proc_event` VALUES
(51483, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (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), (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), (51486, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(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), (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), (51557, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51558, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (51558, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@ -17787,12 +17796,12 @@ INSERT INTO `spell_proc_event` VALUES
(51698, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1), (51698, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51700, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1), (51700, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51701, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1), (51701, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51940, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0), (51940, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(51989, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0), (51989, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52004, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0), (52004, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52005, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0), (52005, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52007, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0), (52007, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52008, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0), (52008, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52020, 0x00000000, 7, 0x00008000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (52020, 0x00000000, 7, 0x00008000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(52127, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), (52127, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(52420, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), (52420, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30),
@ -17863,6 +17872,7 @@ INSERT INTO `spell_proc_event` VALUES
(55677, 0x00000000, 6, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (55677, 0x00000000, 6, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(55680, 0x00000000, 6, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (55680, 0x00000000, 6, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(55689, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (55689, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(55747, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(55768, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), (55768, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(55776, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), (55776, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(56218, 0x00000000, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (56218, 0x00000000, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@ -17910,6 +17920,8 @@ INSERT INTO `spell_proc_event` VALUES
(60132, 0x00000000, 15, 0x00000000, 0x08020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (60132, 0x00000000, 15, 0x00000000, 0x08020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(60170, 0x00000000, 5, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (60170, 0x00000000, 5, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(60172, 0x00000000, 5, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (60172, 0x00000000, 5, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(60436, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60442, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60493, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), (60493, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60503, 0x00000000, 4, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (60503, 0x00000000, 4, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(60537, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (60537, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),

View file

@ -229,6 +229,8 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(45030, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Impale Emissary', 'Spell::EffectDummy'), (45030, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Impale Emissary', 'Spell::EffectDummy'),
(45088,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Emissary of Hate Credit', 'Spell::EffectDummy'), (45088,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Emissary of Hate Credit', 'Spell::EffectDummy'),
(45150, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'), (45150, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(64422, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(64688, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(45182,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Cheat Death', 'Spell::EffectDummy'), (45182,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Cheat Death', 'Spell::EffectDummy'),
(46014,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Knocked Up', 'Spell::EffectDummy'), (46014,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Knocked Up', 'Spell::EffectDummy'),
(47540, 6,0x0080000000000000,0x00000000, -1, -1, -1, 3, -1,-1,'Penance', 'Spell::EffectDummy'), (47540, 6,0x0080000000000000,0x00000000, -1, -1, -1, 3, -1,-1,'Penance', 'Spell::EffectDummy'),

View file

@ -0,0 +1,16 @@
ALTER TABLE db_version CHANGE COLUMN required_8251_03_mangos_spell_proc_event required_8253_01_mangos_spell_chain bit;
DELETE FROM `spell_chain` WHERE `spell_id` IN (32385,32387,32392,32393,32394,51528,51529,51530,51531,51532);
INSERT INTO `spell_chain` (`spell_id`, `prev_spell`, `first_spell`, `rank`, `req_spell`) VALUES
/*Shadow embrace*/
(32385,0,32385,1,0),
(32387,32385,32385,2,0),
(32392,32387,32385,3,0),
(32393,32392,32385,4,0),
(32394,32393,32385,5,0),
/*Maelstrom Weapon*/
(51528,0,51528,1,0),
(51529,51528,51528,2,0),
(51530,51529,51528,3,0),
(51531,51530,51528,4,0),
(51532,51531,51528,5,0);

View file

@ -0,0 +1,21 @@
ALTER TABLE db_version CHANGE COLUMN required_8253_01_mangos_spell_chain required_8253_02_mangos_spell_proc_event bit;
/*Bandit's Insignia*/
DELETE FROM `spell_proc_event` WHERE entry IN (60442);
INSERT INTO spell_proc_event VALUES
(60442, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);
/*Seal of wisdom*/
DELETE FROM `spell_proc_event` WHERE `entry` IN (20166);
INSERT INTO `spell_proc_event` VALUES
(20166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0);
/*Shadow embrace*/
DELETE FROM `spell_proc_event` WHERE `entry` IN (32385);
INSERT INTO `spell_proc_event` VALUES
(32385, 0x00000000, 5, 0x00000001, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0);
/*Maelstrom Weapon*/
DELETE FROM `spell_proc_event` WHERE `entry` IN (51528);
INSERT INTO `spell_proc_event` VALUES
(51528, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0);

View file

@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_8253_02_mangos_spell_proc_event required_8254_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (55747,60436);
INSERT INTO `spell_proc_event` VALUES
(55747, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60436, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);

View file

@ -258,6 +258,9 @@ pkgdata_DATA = \
8251_01_mangos_spell_chain.sql \ 8251_01_mangos_spell_chain.sql \
8251_02_mangos_spell_bonus_data.sql \ 8251_02_mangos_spell_bonus_data.sql \
8251_03_mangos_spell_proc_event.sql \ 8251_03_mangos_spell_proc_event.sql \
8253_01_mangos_spell_chain.sql \
8253_02_mangos_spell_proc_event.sql \
8254_01_mangos_spell_proc_event.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -496,4 +499,7 @@ EXTRA_DIST = \
8251_01_mangos_spell_chain.sql \ 8251_01_mangos_spell_chain.sql \
8251_02_mangos_spell_bonus_data.sql \ 8251_02_mangos_spell_bonus_data.sql \
8251_03_mangos_spell_proc_event.sql \ 8251_03_mangos_spell_proc_event.sql \
8253_01_mangos_spell_chain.sql \
8253_02_mangos_spell_proc_event.sql \
8254_01_mangos_spell_proc_event.sql \
README README

View file

@ -18,10 +18,6 @@
#include "ObjectMgr.h" // for normalizePlayerName #include "ObjectMgr.h" // for normalizePlayerName
#include "ChannelMgr.h" #include "ChannelMgr.h"
#include "Policies/SingletonImp.h"
INSTANTIATE_SINGLETON_1( AllianceChannelMgr );
INSTANTIATE_SINGLETON_1( HordeChannelMgr );
void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
{ {

97
src/game/ChannelMgr.cpp Normal file
View file

@ -0,0 +1,97 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ChannelMgr.h"
#include "Policies/SingletonImp.h"
#include "World.h"
INSTANTIATE_SINGLETON_1( AllianceChannelMgr );
INSTANTIATE_SINGLETON_1( HordeChannelMgr );
ChannelMgr* channelMgr(uint32 team)
{
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance(); // cross-faction
if(team == ALLIANCE)
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance();
if(team == HORDE)
return &MaNGOS::Singleton<HordeChannelMgr>::Instance();
return NULL;
}
ChannelMgr::~ChannelMgr()
{
for(ChannelMap::iterator itr = channels.begin();itr!=channels.end(); ++itr)
delete itr->second;
channels.clear();
}
Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id)
{
if (channels.find(name) == channels.end())
{
Channel *nchan = new Channel(name,channel_id);
channels[name] = nchan;
}
return channels[name];
}
Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
{
if(pkt)
{
WorldPacket data;
MakeNotOnPacket(&data,name);
p->GetSession()->SendPacket(&data);
}
return NULL;
}
else
return i->second;
}
void ChannelMgr::LeftChannel(std::string name)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
return;
Channel* channel = i->second;
if(channel->GetNumPlayers() == 0 && !channel->IsConstant())
{
channels.erase(name);
delete channel;
}
}
void ChannelMgr::MakeNotOnPacket(WorldPacket *data, std::string name)
{
data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
(*data) << (uint8)0x05 << name;
}

View file

@ -18,9 +18,9 @@
#ifndef MANGOSSERVER_CHANNELMGR_H #ifndef MANGOSSERVER_CHANNELMGR_H
#define MANGOSSERVER_CHANNELMGR_H #define MANGOSSERVER_CHANNELMGR_H
#include "Common.h"
#include "Channel.h" #include "Channel.h"
#include "Policies/Singleton.h" #include "Policies/Singleton.h"
#include "World.h"
#include <map> #include <map>
#include <string> #include <string>
@ -30,72 +30,19 @@ class ChannelMgr
public: public:
typedef std::map<std::string,Channel *> ChannelMap; typedef std::map<std::string,Channel *> ChannelMap;
ChannelMgr() {} ChannelMgr() {}
~ChannelMgr() ~ChannelMgr();
{
for(ChannelMap::const_iterator itr = channels.begin();itr!=channels.end(); ++itr)
delete itr->second;
channels.clear();
}
Channel *GetJoinChannel(const std::string& name, uint32 channel_id)
{
if (channels.find(name) == channels.end())
{
Channel *nchan = new Channel(name,channel_id);
channels[name] = nchan;
}
return channels[name];
}
Channel *GetChannel(const std::string& name, Player *p)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end()) Channel *GetJoinChannel(std::string name, uint32 channel_id);
{ Channel *GetChannel(std::string name, Player *p, bool pkt = true);
WorldPacket data; void LeftChannel(std::string name);
MakeNotOnPacket(&data,name);
p->GetSession()->SendPacket(&data);
return NULL;
}
else
return i->second;
}
void LeftChannel(const std::string& name)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
return;
Channel* channel = i->second;
if(channel->GetNumPlayers() == 0 && !channel->IsConstant())
{
channels.erase(name);
delete channel;
}
}
private: private:
ChannelMap channels; ChannelMap channels;
void MakeNotOnPacket(WorldPacket *data, const std::string& name) void MakeNotOnPacket(WorldPacket *data, std::string name);
{
data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
(*data) << (uint8)0x05 << name;
}
}; };
class AllianceChannelMgr : public ChannelMgr {}; class AllianceChannelMgr : public ChannelMgr {};
class HordeChannelMgr : public ChannelMgr {}; class HordeChannelMgr : public ChannelMgr {};
inline ChannelMgr* channelMgr(uint32 team) ChannelMgr* channelMgr(uint32 team);
{
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
//For Test,No Seprate Faction
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance();
if(team==ALLIANCE)
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance();
if(team==HORDE)
return &MaNGOS::Singleton<HordeChannelMgr>::Instance();
return NULL;
}
#endif #endif

View file

@ -39,7 +39,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
objmgr.LoadMangosStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID); objmgr.LoadMangosStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID);
// Gather Additional data from EventAI Texts // Gather Additional data from EventAI Texts
QueryResult *result = WorldDatabase.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts"); QueryResult *result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
sLog.outString("Loading EventAI Texts additional data..."); sLog.outString("Loading EventAI Texts additional data...");
if (result) if (result)
@ -117,8 +117,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
//Drop Existing EventSummon Map //Drop Existing EventSummon Map
m_CreatureEventAI_Summon_Map.clear(); m_CreatureEventAI_Summon_Map.clear();
//Gather additional data for EventAI // Gather additional data for EventAI
QueryResult *result = WorldDatabase.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons"); QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
if (result) if (result)
{ {
barGoLink bar(result->GetRowCount()); barGoLink bar(result->GetRowCount());
@ -169,8 +169,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
//Drop Existing EventAI List //Drop Existing EventAI List
m_CreatureEventAI_Event_Map.clear(); m_CreatureEventAI_Event_Map.clear();
//Gather event data // Gather event data
QueryResult *result = WorldDatabase.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, " QueryResult *result = WorldDatabase.Query("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
"event_param1, event_param2, event_param3, event_param4, " "event_param1, event_param2, event_param3, event_param4, "
"action1_type, action1_param1, action1_param2, action1_param3, " "action1_type, action1_param1, action1_param2, action1_param3, "
"action2_type, action2_param1, action2_param2, action2_param3, " "action2_type, action2_param1, action2_param2, action2_param3, "

View file

@ -865,7 +865,7 @@ void GameObject::Use(Unit* user)
UseDoorOrButton(); UseDoorOrButton();
// activate script // activate script
sWorld.ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this); GetMap()->ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this);
return; return;
case GAMEOBJECT_TYPE_QUESTGIVER: //2 case GAMEOBJECT_TYPE_QUESTGIVER: //2
@ -961,7 +961,7 @@ void GameObject::Use(Unit* user)
player->CastedCreatureOrGO(info->id, GetGUID(), 0); player->CastedCreatureOrGO(info->id, GetGUID(), 0);
if (info->goober.eventId) if (info->goober.eventId)
sWorld.ScriptsStart(sEventScripts, info->goober.eventId, player, this); GetMap()->ScriptsStart(sEventScripts, info->goober.eventId, player, this);
} }
// cast this spell later if provided // cast this spell later if provided
@ -984,7 +984,7 @@ void GameObject::Use(Unit* user)
player->SendCinematicStart(info->camera.cinematicId); player->SendCinematicStart(info->camera.cinematicId);
if (info->camera.eventID) if (info->camera.eventID)
sWorld.ScriptsStart(sEventScripts, info->camera.eventID, player, this); GetMap()->ScriptsStart(sEventScripts, info->camera.eventID, player, this);
return; return;
} }

View file

@ -82,6 +82,7 @@ libmangosgame_a_SOURCES = \
Channel.cpp \ Channel.cpp \
Channel.h \ Channel.h \
ChannelHandler.cpp \ ChannelHandler.cpp \
ChannelMgr.cpp \
ChannelMgr.h \ ChannelMgr.h \
CharacterHandler.cpp \ CharacterHandler.cpp \
Chat.cpp \ Chat.cpp \
@ -298,7 +299,12 @@ libmangosgame_a_SOURCES = \
GroupRefManager.h GroupRefManager.h
## Link against shared library ## Link against shared library
libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a libmangosgame_a_LIBADD = \
../shared/libmangosshared.a \
../shared/Auth/libmangosauth.a \
../shared/Config/libmangosconfig.a \
../shared/Database/libmangosdatabase.a \
../shared/vmap/libmangosvmaps.a
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
# Precompiled Headers for WIN # Precompiled Headers for WIN

View file

@ -18,6 +18,7 @@
#include "MapManager.h" #include "MapManager.h"
#include "Player.h" #include "Player.h"
#include "Vehicle.h"
#include "GridNotifiers.h" #include "GridNotifiers.h"
#include "Log.h" #include "Log.h"
#include "GridStates.h" #include "GridStates.h"
@ -43,9 +44,20 @@
GridState* si_GridStates[MAX_GRID_STATE]; GridState* si_GridStates[MAX_GRID_STATE];
struct ScriptAction
{
uint64 sourceGUID;
uint64 targetGUID;
uint64 ownerGUID; // owner of source if source is item
ScriptInfo const* script; // pointer to static script data
};
Map::~Map() Map::~Map()
{ {
UnloadAll(true); UnloadAll(true);
if(!m_scriptSchedule.empty())
sWorld.DecreaseScheduledScriptCount(m_scriptSchedule.size());
} }
bool Map::ExistMap(uint32 mapid,int gx,int gy) bool Map::ExistMap(uint32 mapid,int gx,int gy)
@ -668,17 +680,21 @@ void Map::Update(const uint32 &t_diff)
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load ! // Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended // This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
if (IsBattleGroundOrArena()) if (!IsBattleGroundOrArena())
return;
for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); )
{ {
NGridType *grid = i->getSource(); for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); )
GridInfo *info = i->getSource()->getGridInfoRef(); {
++i; // The update might delete the map and we need the next map before the iterator gets invalid NGridType *grid = i->getSource();
assert(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE); GridInfo *info = i->getSource()->getGridInfoRef();
si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, grid->getX(), grid->getY(), t_diff); ++i; // The update might delete the map and we need the next map before the iterator gets invalid
assert(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE);
si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, grid->getX(), grid->getY(), t_diff);
}
} }
///- Process necessary scripts
if (!m_scriptSchedule.empty())
ScriptsProcess();
} }
void Map::Remove(Player *player, bool remove) void Map::Remove(Player *player, bool remove)
@ -2615,6 +2631,713 @@ void BattleGroundMap::UnloadAll(bool pForce)
Map::UnloadAll(pForce); Map::UnloadAll(pForce);
} }
/// Put scripts in the execution queue
void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
{
///- Find the script map
ScriptMapMap::const_iterator s = scripts.find(id);
if (s == scripts.end())
return;
// prepare static data
uint64 sourceGUID = source->GetGUID();
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
///- Schedule script execution for all scripts in the script map
ScriptMap const *s2 = &(s->second);
bool immedScript = false;
for (ScriptMap::const_iterator iter = s2->begin(); iter != s2->end(); ++iter)
{
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &iter->second;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(time_t(sWorld.GetGameTime() + iter->first), sa));
if (iter->first == 0)
immedScript = true;
sWorld.IncreaseScheduledScriptsCount();
}
///- If one of the effects should be immediate, launch the script execution
if (immedScript)
ScriptsProcess();
}
void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target)
{
// NOTE: script record _must_ exist until command executed
// prepare static data
uint64 sourceGUID = source->GetGUID();
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &script;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(time_t(sWorld.GetGameTime() + delay), sa));
sWorld.IncreaseScheduledScriptsCount();
///- If effects should be immediate, launch the script execution
if(delay == 0)
ScriptsProcess();
}
/// Process queued scripts
void Map::ScriptsProcess()
{
if (m_scriptSchedule.empty())
return;
///- Process overdue queued scripts
std::multimap<time_t, ScriptAction>::iterator iter = m_scriptSchedule.begin();
// ok as multimap is a *sorted* associative container
while (!m_scriptSchedule.empty() && (iter->first <= sWorld.GetGameTime()))
{
ScriptAction const& step = iter->second;
Object* source = NULL;
if(step.sourceGUID)
{
switch(GUID_HIPART(step.sourceGUID))
{
case HIGHGUID_ITEM:
// case HIGHGUID_CONTAINER: ==HIGHGUID_ITEM
{
Player* player = HashMapHolder<Player>::Find(step.ownerGUID);
if(player)
source = player->GetItemByGuid(step.sourceGUID);
break;
}
case HIGHGUID_UNIT:
source = HashMapHolder<Creature>::Find(step.sourceGUID);
break;
case HIGHGUID_PET:
source = HashMapHolder<Pet>::Find(step.sourceGUID);
break;
case HIGHGUID_VEHICLE:
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
break;
case HIGHGUID_PLAYER:
source = HashMapHolder<Player>::Find(step.sourceGUID);
break;
case HIGHGUID_GAMEOBJECT:
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
break;
case HIGHGUID_CORPSE:
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.sourceGUID));
break;
}
}
if(source && !source->IsInWorld()) source = NULL;
Object* target = NULL;
if(step.targetGUID)
{
switch(GUID_HIPART(step.targetGUID))
{
case HIGHGUID_UNIT:
target = HashMapHolder<Creature>::Find(step.targetGUID);
break;
case HIGHGUID_PET:
target = HashMapHolder<Pet>::Find(step.targetGUID);
break;
case HIGHGUID_VEHICLE:
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
break;
case HIGHGUID_PLAYER: // empty GUID case also
target = HashMapHolder<Player>::Find(step.targetGUID);
break;
case HIGHGUID_GAMEOBJECT:
target = HashMapHolder<GameObject>::Find(step.targetGUID);
break;
case HIGHGUID_CORPSE:
target = HashMapHolder<Corpse>::Find(step.targetGUID);
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.targetGUID));
break;
}
}
if(target && !target->IsInWorld()) target = NULL;
switch (step.script->command)
{
case SCRIPT_COMMAND_TALK:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TALK call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
uint64 unit_target = target ? target->GetGUID() : 0;
//datalong 0=normal say, 1=whisper, 2=yell, 3=emote text
switch(step.script->datalong)
{
case 0: // Say
((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 1: // Whisper
if(!unit_target)
{
sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong);
break;
}
((Creature *)source)->Whisper(step.script->dataint,unit_target);
break;
case 2: // Yell
((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 3: // Emote text
((Creature *)source)->TextEmote(step.script->dataint, unit_target);
break;
default:
break; // must be already checked at load
}
break;
}
case SCRIPT_COMMAND_EMOTE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature *)source)->HandleEmoteCommand(step.script->datalong);
break;
case SCRIPT_COMMAND_FIELD_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetUInt32Value(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_MOVE_TO:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature*)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 );
((Creature*)source)->GetMap()->CreatureRelocation(((Creature*)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_FLAG_REMOVE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->RemoveFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_TELEPORT_TO:
{
// accept player in any one from target/source arg
if (!target && !source)
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for NULL object.");
break;
}
// must be only Player
if((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER))
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
break;
}
Player* pSource = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source;
pSource->TeleportTo(step.script->datalong, step.script->x, step.script->y, step.script->z, step.script->o);
break;
}
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
{
if(!step.script->datalong) // creature not specified
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL creature.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
float x = step.script->x;
float y = step.script->y;
float z = step.script->z;
float o = step.script->o;
Creature* pCreature = summoner->SummonCreature(step.script->datalong, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,step.script->datalong2);
if (!pCreature)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON failed for creature (entry: %u).",step.script->datalong);
break;
}
break;
}
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
{
if(!step.script->datalong) // gameobject not specified
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL gameobject.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
GameObject *go = NULL;
int32 time_to_despawn = step.script->datalong2<5 ? 5 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(summoner->GetPositionX(), summoner->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(summoner, go,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *summoner->GetMap());
if ( !go )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if( go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE ||
go->GetGoType()==GAMEOBJECT_TYPE_DOOR ||
go->GetGoType()==GAMEOBJECT_TYPE_BUTTON ||
go->GetGoType()==GAMEOBJECT_TYPE_TRAP )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT can not be used with gameobject of type %u (guid: %u).", uint32(go->GetGoType()), step.script->datalong);
break;
}
if( go->isSpawned() )
break; //gameobject already spawned
go->SetLootState(GO_READY);
go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds
go->GetMap()->Add(go);
break;
}
case SCRIPT_COMMAND_OPEN_DOOR:
{
if(!step.script->datalong) // door not specified
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_close = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if (!door)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if (door->GetGoType() != GAMEOBJECT_TYPE_DOOR)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if (door->GetGoState() != GO_STATE_READY)
break; //door already open
door->UseDoorOrButton(time_to_close);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_close);
break;
}
case SCRIPT_COMMAND_CLOSE_DOOR:
{
if(!step.script->datalong) // guid for door not specified
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_open = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if ( !door )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if( door->GetGoState() == GO_STATE_READY )
break; //door already closed
door->UseDoorOrButton(time_to_open);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_open);
break;
}
case SCRIPT_COMMAND_QUEST_EXPLORED:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL source.");
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL target.");
break;
}
// when script called for item spell casting then target == (unit or GO) and source is player
WorldObject* worldObject;
Player* player;
if(target->GetTypeId()==TYPEID_PLAYER)
{
if(source->GetTypeId()!=TYPEID_UNIT && source->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)source;
player = (Player*)target;
}
else
{
if(target->GetTypeId()!=TYPEID_UNIT && target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
if(source->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-player(TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)target;
player = (Player*)source;
}
// quest id and flags checked at script loading
if( (worldObject->GetTypeId()!=TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) &&
(step.script->datalong2==0 || worldObject->IsWithinDistInMap(player,float(step.script->datalong2))) )
player->AreaExploredOrEventHappens(step.script->datalong);
else
player->FailQuest(step.script->datalong);
break;
}
case SCRIPT_COMMAND_ACTIVATE_OBJECT:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT must have source caster.");
break;
}
if(!source->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT source caster isn't unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for NULL gameobject.");
break;
}
if(target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *go = (GameObject*)target;
go->Use(caster);
break;
}
case SCRIPT_COMMAND_REMOVE_AURA:
{
Object* cmdTarget = step.script->datalong2 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA call for NULL %s.",step.script->datalong2 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
((Unit*)cmdTarget)->RemoveAurasDueToSpell(step.script->datalong);
break;
}
case SCRIPT_COMMAND_CAST_SPELL:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL must have source caster.");
break;
}
Object* cmdTarget = step.script->datalong2 & 0x01 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x01 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x01 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
Unit* spellTarget = (Unit*)cmdTarget;
Object* cmdSource = step.script->datalong2 & 0x02 ? target : source;
if(!cmdSource)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x02 ? "target" : "source");
break;
}
if(!cmdSource->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x02 ? "target" : "source", cmdSource->GetTypeId());
break;
}
Unit* spellSource = (Unit*)cmdSource;
//TODO: when GO cast implemented, code below must be updated accordingly to also allow GO spell cast
spellSource->CastSpell(spellTarget,step.script->datalong,false);
break;
}
case SCRIPT_COMMAND_PLAY_SOUND:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for NULL creature.");
break;
}
WorldObject* pSource = dynamic_cast<WorldObject*>(source);
if(!pSource)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for non-world object (TypeId: %u), skipping.",source->GetTypeId());
break;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
Player* pTarget = NULL;
if(step.script->datalong2 & 1)
{
if(!target)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for NULL target.");
break;
}
if(target->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for non-player (TypeId: %u), skipping.",target->GetTypeId());
break;
}
pTarget = (Player*)target;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
if(step.script->datalong2 & 2)
pSource->PlayDistanceSound(step.script->datalong,pTarget);
else
pSource->PlayDirectSound(step.script->datalong,pTarget);
break;
}
default:
sLog.outError("Unknown script command %u called.",step.script->command);
break;
}
m_scriptSchedule.erase(iter);
sWorld.DecreaseScheduledScriptCount();
iter = m_scriptSchedule.begin();
}
return;
}
Creature* Creature*
Map::GetCreature(uint64 guid) Map::GetCreature(uint64 guid)
{ {

View file

@ -41,6 +41,8 @@ class WorldPacket;
class InstanceData; class InstanceData;
class Group; class Group;
class InstanceSave; class InstanceSave;
struct ScriptInfo;
struct ScriptAction;
typedef ACE_RW_Thread_Mutex GridRWLock; typedef ACE_RW_Thread_Mutex GridRWLock;
@ -388,6 +390,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
typedef MapRefManager PlayerList; typedef MapRefManager PlayerList;
PlayerList const& GetPlayers() const { return m_mapRefManager; } PlayerList const& GetPlayers() const { return m_mapRefManager; }
//per-map script storage
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
// must called with AddToWorld // must called with AddToWorld
template<class T> template<class T>
void AddToActive(T* obj) { AddToActiveHelper(obj); } void AddToActive(T* obj) { AddToActiveHelper(obj); }
@ -444,6 +450,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); } void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); }
void setNGrid(NGridType* grid, uint32 x, uint32 y); void setNGrid(NGridType* grid, uint32 x, uint32 y);
void ScriptsProcess();
protected: protected:
void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
@ -477,6 +484,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
time_t i_gridExpiry; time_t i_gridExpiry;
std::set<WorldObject *> i_objectsToRemove; std::set<WorldObject *> i_objectsToRemove;
std::multimap<time_t, ScriptAction> m_scriptSchedule;
// Type specific code for add/remove to/from grid // Type specific code for add/remove to/from grid
template<class T> template<class T>

View file

@ -12513,7 +12513,7 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
//starting initial quest script //starting initial quest script
if(questGiver && pQuest->GetQuestStartScript()!=0) if(questGiver && pQuest->GetQuestStartScript()!=0)
sWorld.ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this); GetMap()->ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
// Some spells applied at quest activation // Some spells applied at quest activation
SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true); SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true);
@ -13771,7 +13771,7 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
GetSession()->SendPacket( &data ); GetSession()->SendPacket( &data );
if (pQuest->GetQuestCompleteScript() != 0) if (pQuest->GetQuestCompleteScript() != 0)
sWorld.ScriptsStart(sQuestEndScripts, pQuest->GetQuestCompleteScript(), questGiver, this); GetMap()->ScriptsStart(sQuestEndScripts, pQuest->GetQuestCompleteScript(), questGiver, this);
} }
void Player::SendQuestFailed( uint32 quest_id ) void Player::SendQuestFailed( uint32 quest_id )

View file

@ -955,6 +955,12 @@ enum Mechanics
(1<<MECHANIC_SHACKLE )|(1<<MECHANIC_TURN )|(1<<MECHANIC_HORROR)| \ (1<<MECHANIC_SHACKLE )|(1<<MECHANIC_TURN )|(1<<MECHANIC_HORROR)| \
(1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) ) (1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) )
// Daze and all croud control spells except polymorph are not removed
#define MECHANIC_NOT_REMOVED_BY_SHAPESHIFT ( \
(1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED)|(1<<MECHANIC_FEAR )|(1<<MECHANIC_PACIFY )| \
(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE )|(1<<MECHANIC_BANISH)|(1<<MECHANIC_SHACKLE)| \
(1<<MECHANIC_HORROR)|(1<<MECHANIC_TURN )|(1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) )
// Spell dispell type // Spell dispell type
enum DispelType enum DispelType
{ {
@ -1042,6 +1048,7 @@ enum Targets
TARGET_SELF2 = 87, TARGET_SELF2 = 87,
TARGET_DIRECTLY_FORWARD = 89, TARGET_DIRECTLY_FORWARD = 89,
TARGET_NONCOMBAT_PET = 90, TARGET_NONCOMBAT_PET = 90,
TARGET_IN_FRONT_OF_CASTER_30 = 104,
}; };
enum SpellMissInfo enum SpellMissInfo

View file

@ -1812,6 +1812,9 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap)
FillAreaTargets(TagUnitMap,m_caster->GetPositionX(), m_caster->GetPositionY(),radius,inFront ? PUSH_IN_FRONT : PUSH_IN_BACK,SPELL_TARGETS_AOE_DAMAGE); FillAreaTargets(TagUnitMap,m_caster->GetPositionX(), m_caster->GetPositionY(),radius,inFront ? PUSH_IN_FRONT : PUSH_IN_BACK,SPELL_TARGETS_AOE_DAMAGE);
break; break;
} }
case TARGET_IN_FRONT_OF_CASTER_30:
FillAreaTargets(TagUnitMap,m_caster->GetPositionX(), m_caster->GetPositionY(), radius, PUSH_IN_FRONT_30, SPELL_TARGETS_AOE_DAMAGE);
break;
case TARGET_DUELVSPLAYER: case TARGET_DUELVSPLAYER:
{ {
Unit *target = m_targets.getUnitTarget(); Unit *target = m_targets.getUnitTarget();

View file

@ -83,6 +83,7 @@ enum SpellCastFlags
enum SpellNotifyPushType enum SpellNotifyPushType
{ {
PUSH_IN_FRONT, PUSH_IN_FRONT,
PUSH_IN_FRONT_30,
PUSH_IN_BACK, PUSH_IN_BACK,
PUSH_SELF_CENTER, PUSH_SELF_CENTER,
PUSH_DEST_CENTER, PUSH_DEST_CENTER,
@ -706,6 +707,10 @@ namespace MaNGOS
if(i_spell.GetCaster()->isInFrontInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) if(i_spell.GetCaster()->isInFrontInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 ))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());
break; break;
case PUSH_IN_FRONT_30:
if(i_spell.GetCaster()->isInFrontInMap((Unit*)(itr->getSource()), i_radius, M_PI/6 ))
i_data->push_back(itr->getSource());
break;
case PUSH_IN_BACK: case PUSH_IN_BACK:
if(i_spell.GetCaster()->isInBackInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) if(i_spell.GetCaster()->isInBackInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 ))
i_data->push_back(itr->getSource()); i_data->push_back(itr->getSource());

View file

@ -2721,14 +2721,34 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
case FORM_FLIGHT_EPIC: case FORM_FLIGHT_EPIC:
case FORM_FLIGHT: case FORM_FLIGHT:
case FORM_MOONKIN: case FORM_MOONKIN:
{
// remove movement affects // remove movement affects
m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED); Unit::AuraList const& slowingAuras = m_target->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
for (Unit::AuraList::const_iterator iter = slowingAuras.begin(); iter != slowingAuras.end();)
{
SpellEntry const* aurSpellInfo = (*iter)->GetSpellProto();
// If spell that caused this aura has Croud Control or Daze effect
if((GetAllSpellMechanicMask(aurSpellInfo) & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) ||
// some Daze spells have these parameters instead of MECHANIC_DAZE
(aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0))
{
++iter;
continue;
}
// All OK, remove aura now
m_target->RemoveAurasDueToSpellByCancel(aurSpellInfo->Id);
iter = slowingAuras.begin();
}
// and polymorphic affects // and polymorphic affects
if(m_target->IsPolymorphed()) if(m_target->IsPolymorphed())
m_target->RemoveAurasDueToSpell(m_target->getTransForm()); m_target->RemoveAurasDueToSpell(m_target->getTransForm());
break; break;
}
default: default:
break; break;
} }
@ -5375,16 +5395,19 @@ void Aura::HandleShapeshiftBoosts(bool apply)
uint32 spellId = 0; uint32 spellId = 0;
uint32 spellId2 = 0; uint32 spellId2 = 0;
uint32 HotWSpellId = 0; uint32 HotWSpellId = 0;
uint32 MasterShaperSpellId = 0;
switch(GetModifier()->m_miscvalue) switch(GetModifier()->m_miscvalue)
{ {
case FORM_CAT: case FORM_CAT:
spellId = 3025; spellId = 3025;
HotWSpellId = 24900; HotWSpellId = 24900;
MasterShaperSpellId = 48420;
break; break;
case FORM_TREE: case FORM_TREE:
spellId = 5420; spellId = 5420;
spellId2 = 34123; spellId2 = 34123;
MasterShaperSpellId = 48422;
break; break;
case FORM_TRAVEL: case FORM_TRAVEL:
spellId = 5419; spellId = 5419;
@ -5396,11 +5419,13 @@ void Aura::HandleShapeshiftBoosts(bool apply)
spellId = 1178; spellId = 1178;
spellId2 = 21178; spellId2 = 21178;
HotWSpellId = 24899; HotWSpellId = 24899;
MasterShaperSpellId = 48418;
break; break;
case FORM_DIREBEAR: case FORM_DIREBEAR:
spellId = 9635; spellId = 9635;
spellId2 = 21178; spellId2 = 21178;
HotWSpellId = 24899; HotWSpellId = 24899;
MasterShaperSpellId = 48418;
break; break;
case FORM_BATTLESTANCE: case FORM_BATTLESTANCE:
spellId = 21156; spellId = 21156;
@ -5415,6 +5440,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
spellId = 24905; spellId = 24905;
// aura from effect trigger spell // aura from effect trigger spell
spellId2 = 24907; spellId2 = 24907;
MasterShaperSpellId = 48421;
break; break;
case FORM_FLIGHT: case FORM_FLIGHT:
spellId = 33948; spellId = 33948;
@ -5463,14 +5489,31 @@ void Aura::HandleShapeshiftBoosts(bool apply)
if (spellInfo->Stances & (1<<form)) if (spellInfo->Stances & (1<<form))
m_target->CastSpell(m_target, itr->first, true, NULL, this); m_target->CastSpell(m_target, itr->first, true, NULL, this);
} }
//LotP
// Master Shapeshifter
if (MasterShaperSpellId)
{
Unit::AuraList const& ShapeShifterAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator i = ShapeShifterAuras.begin(); i != ShapeShifterAuras.end(); i++)
{
if ((*i)->GetSpellProto()->SpellIconID == 2851)
{
int32 ShiftMod = (*i)->GetModifier()->m_amount;
m_target->CastCustomSpell(m_target, MasterShaperSpellId, &ShiftMod, NULL, NULL, true);
break;
}
}
}
// Leader of the Pack
if (((Player*)m_target)->HasSpell(17007)) if (((Player*)m_target)->HasSpell(17007))
{ {
SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932); SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
if (spellInfo && spellInfo->Stances & (1<<form)) if (spellInfo && spellInfo->Stances & (1<<form))
m_target->CastSpell(m_target, 24932, true, NULL, this); m_target->CastSpell(m_target, 24932, true, NULL, this);
} }
// HotW
// Heart of the Wild
if (HotWSpellId) if (HotWSpellId)
{ {
Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE); Unit::AuraList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
@ -5493,6 +5536,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
{ {
m_target->RemoveAurasDueToSpell(spellId); m_target->RemoveAurasDueToSpell(spellId);
m_target->RemoveAurasDueToSpell(spellId2); m_target->RemoveAurasDueToSpell(spellId2);
m_target->RemoveAurasDueToSpell(MasterShaperSpellId);
Unit::AuraMap& tAuras = m_target->GetAuras(); Unit::AuraMap& tAuras = m_target->GetAuras();
for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
@ -5503,9 +5547,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
itr = tAuras.begin(); itr = tAuras.begin();
} }
else else
{
++itr; ++itr;
}
} }
} }

View file

@ -321,6 +321,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
case 40810: case 43267: case 43268: // Saber Lash case 40810: case 43267: case 43268: // Saber Lash
case 42384: // Brutal Swipe case 42384: // Brutal Swipe
case 45150: // Meteor Slash case 45150: // Meteor Slash
case 64422: case 64688: // Sonic Screech
{ {
uint32 count = 0; uint32 count = 0;
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
@ -2462,7 +2463,7 @@ void Spell::EffectSendEvent(uint32 EffectIndex)
we do not handle a flag dropping or clicking on flag in battleground by sendevent system we do not handle a flag dropping or clicking on flag in battleground by sendevent system
*/ */
sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id); sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id);
sWorld.ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject); m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject);
} }
void Spell::EffectPowerBurn(uint32 i) void Spell::EffectPowerBurn(uint32 i)
@ -2852,31 +2853,31 @@ void Spell::EffectEnergize(uint32 i)
Powers power = Powers(m_spellInfo->EffectMiscValue[i]); Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
// Some level depends spells // Some level depends spells
int multiplier = 0; int level_multiplier = 0;
int level_diff = 0; int level_diff = 0;
switch (m_spellInfo->Id) switch (m_spellInfo->Id)
{ {
// Restore Energy case 9512: // Restore Energy
case 9512:
level_diff = m_caster->getLevel() - 40; level_diff = m_caster->getLevel() - 40;
multiplier = 2; level_multiplier = 2;
break; break;
// Blood Fury case 24571: // Blood Fury
case 24571:
level_diff = m_caster->getLevel() - 60; level_diff = m_caster->getLevel() - 60;
multiplier = 10; level_multiplier = 10;
break; break;
// Burst of Energy case 24532: // Burst of Energy
case 24532:
level_diff = m_caster->getLevel() - 60; level_diff = m_caster->getLevel() - 60;
multiplier = 4; level_multiplier = 4;
break; break;
case 31930: // Judgements of the Wise
case 63375: // Improved Stormstrike
damage = damage * unitTarget->GetCreateMana() / 100;
default: default:
break; break;
} }
if (level_diff > 0) if (level_diff > 0)
damage -= multiplier * level_diff; damage -= level_multiplier * level_diff;
if(damage < 0) if(damage < 0)
return; return;
@ -2965,7 +2966,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON: case GAMEOBJECT_TYPE_BUTTON:
gameObjTarget->UseDoorOrButton(); gameObjTarget->UseDoorOrButton();
sWorld.ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget); player->GetMap()->ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
return; return;
case GAMEOBJECT_TYPE_QUESTGIVER: case GAMEOBJECT_TYPE_QUESTGIVER:
@ -2985,7 +2986,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if (gameObjTarget->GetGOInfo()->goober.eventId) if (gameObjTarget->GetGOInfo()->goober.eventId)
{ {
sLog.outDebug("Goober ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->goober.eventId,gameObjTarget->GetDBTableGUIDLow()); sLog.outDebug("Goober ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->goober.eventId,gameObjTarget->GetDBTableGUIDLow());
sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->goober.eventId, player, gameObjTarget); player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->goober.eventId, player, gameObjTarget);
} }
// cast goober spell // cast goober spell
@ -3014,7 +3015,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if (gameObjTarget->GetGOInfo()->chest.eventId) if (gameObjTarget->GetGOInfo()->chest.eventId)
{ {
sLog.outDebug("Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId,gameObjTarget->GetDBTableGUIDLow()); sLog.outDebug("Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId,gameObjTarget->GetDBTableGUIDLow());
sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget); player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget);
} }
// triggering linked GO // triggering linked GO
@ -5312,7 +5313,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
return; return;
sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id); sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id);
sWorld.ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget); m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
} }
void Spell::EffectSanctuary(uint32 /*i*/) void Spell::EffectSanctuary(uint32 /*i*/)
@ -5496,7 +5497,7 @@ void Spell::EffectActivateObject(uint32 effect_idx)
int32 delay_secs = m_spellInfo->EffectMiscValue[effect_idx]; int32 delay_secs = m_spellInfo->EffectMiscValue[effect_idx];
sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget); gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
} }
void Spell::EffectApplyGlyph(uint32 i) void Spell::EffectApplyGlyph(uint32 i)

View file

@ -281,6 +281,7 @@ bool IsPositiveTarget(uint32 targetA, uint32 targetB)
case TARGET_ALL_ENEMY_IN_AREA_CHANNELED: case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:
case TARGET_CURRENT_ENEMY_COORDINATES: case TARGET_CURRENT_ENEMY_COORDINATES:
case TARGET_SINGLE_ENEMY: case TARGET_SINGLE_ENEMY:
case TARGET_IN_FRONT_OF_CASTER_30:
return false; return false;
case TARGET_CASTER_COORDINATES: case TARGET_CASTER_COORDINATES:
return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER); return (targetB == TARGET_ALL_PARTY || targetB == TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER);

View file

@ -233,6 +233,7 @@ inline bool IsAreaEffectTarget( Targets target )
case TARGET_AREAEFFECT_CUSTOM_2: case TARGET_AREAEFFECT_CUSTOM_2:
case TARGET_ALL_RAID_AROUND_CASTER: case TARGET_ALL_RAID_AROUND_CASTER:
case TARGET_AREAEFFECT_PARTY_AND_CLASS: case TARGET_AREAEFFECT_PARTY_AND_CLASS:
case TARGET_IN_FRONT_OF_CASTER_30:
return true; return true;
default: default:
break; break;

View file

@ -43,18 +43,18 @@ template<class T>
void void
TargetedMovementGenerator<T>::_setTargetLocation(T &owner) TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
{ {
if( !i_target.isValid() || !&owner ) if (!i_target.isValid() || !i_target->IsInWorld())
return; return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) ) if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
return; return;
// prevent redundant micro-movement for pets, other followers. // prevent redundant micro-movement for pets, other followers.
if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset)) if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
return; return;
float x, y, z; float x, y, z;
if(!i_offset) if (!i_offset)
{ {
// to nearest contact position // to nearest contact position
i_target->GetContactPoint( &owner, x, y, z ); i_target->GetContactPoint( &owner, x, y, z );
@ -126,13 +126,13 @@ template<class T>
bool bool
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff) TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{ {
if(!i_target.isValid()) if (!i_target.isValid() || !i_target->IsInWorld())
return false; return false;
if( !&owner || !owner.isAlive()) if (!owner.isAlive())
return true; return true;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) ) if (owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED))
return true; return true;
// prevent movement while casting spells with cast time or channel time // prevent movement while casting spells with cast time or channel time

View file

@ -5555,7 +5555,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
case 31877: case 31877:
case 31878: case 31878:
target = this; target = this;
basepoints0 = GetCreatePowers(POWER_MANA) * 25 / 100;
triggered_spell_id = 31930; triggered_spell_id = 31930;
// Replenishment // Replenishment
@ -6170,7 +6169,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
// Try handle uncnown trigger spells // Try handle unknown trigger spells
if (sSpellStore.LookupEntry(trigger_spell_id)==NULL) if (sSpellStore.LookupEntry(trigger_spell_id)==NULL)
{ {
switch (auraSpellInfo->SpellFamilyName) switch (auraSpellInfo->SpellFamilyName)
@ -6815,6 +6814,17 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
((Player*)this)->RemoveSpellCategoryCooldown(1209, true); ((Player*)this)->RemoveSpellCategoryCooldown(1209, true);
break; break;
} }
// Maelstrom Weapon
case 53817:
{
// have rank dependent proc chance, ignore too often cases
// PPM = 2.5 * (rank of talent),
uint32 rank = spellmgr.GetSpellRank(auraSpellInfo->Id);
// 5 rank -> 100% 4 rank -> 80% and etc from full rate
if(!roll_chance_i(20*rank))
return false;
break;
}
// Brain Freeze // Brain Freeze
case 57761: case 57761:
{ {

View file

@ -76,14 +76,6 @@ float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
float World::m_VisibleUnitGreyDistance = 0; float World::m_VisibleUnitGreyDistance = 0;
float World::m_VisibleObjectGreyDistance = 0; float World::m_VisibleObjectGreyDistance = 0;
struct ScriptAction
{
uint64 sourceGUID;
uint64 targetGUID;
uint64 ownerGUID; // owner of source if source is item
ScriptInfo const* script; // pointer to static script data
};
/// World constructor /// World constructor
World::World() World::World()
{ {
@ -97,6 +89,7 @@ World::World()
m_maxQueuedSessionCount = 0; m_maxQueuedSessionCount = 0;
m_resultQueue = NULL; m_resultQueue = NULL;
m_NextDailyQuestReset = 0; m_NextDailyQuestReset = 0;
m_scheduledScripts = 0;
m_defaultDbcLocale = LOCALE_enUS; m_defaultDbcLocale = LOCALE_enUS;
m_availableDbcLocaleMask = 0; m_availableDbcLocaleMask = 0;
@ -1578,10 +1571,6 @@ void World::Update(uint32 diff)
///- Update objects when the timer has passed (maps, transport, creatures,...) ///- Update objects when the timer has passed (maps, transport, creatures,...)
MapManager::Instance().Update(diff); // As interval = 0 MapManager::Instance().Update(diff); // As interval = 0
///- Process necessary scripts
if (!m_scriptSchedule.empty())
ScriptsProcess();
sBattleGroundMgr.Update(diff); sBattleGroundMgr.Update(diff);
} }
@ -1616,708 +1605,6 @@ void World::Update(uint32 diff)
ProcessCliCommands(); ProcessCliCommands();
} }
/// Put scripts in the execution queue
void World::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
{
///- Find the script map
ScriptMapMap::const_iterator s = scripts.find(id);
if (s == scripts.end())
return;
// prepare static data
uint64 sourceGUID = source->GetGUID();
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
///- Schedule script execution for all scripts in the script map
ScriptMap const *s2 = &(s->second);
bool immedScript = false;
for (ScriptMap::const_iterator iter = s2->begin(); iter != s2->end(); ++iter)
{
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &iter->second;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(m_gameTime + iter->first, sa));
if (iter->first == 0)
immedScript = true;
}
///- If one of the effects should be immediate, launch the script execution
if (immedScript)
ScriptsProcess();
}
void World::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target)
{
// NOTE: script record _must_ exist until command executed
// prepare static data
uint64 sourceGUID = source->GetGUID();
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &script;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(m_gameTime + delay, sa));
///- If effects should be immediate, launch the script execution
if(delay == 0)
ScriptsProcess();
}
/// Process queued scripts
void World::ScriptsProcess()
{
if (m_scriptSchedule.empty())
return;
///- Process overdue queued scripts
std::multimap<time_t, ScriptAction>::iterator iter = m_scriptSchedule.begin();
// ok as multimap is a *sorted* associative container
while (!m_scriptSchedule.empty() && (iter->first <= m_gameTime))
{
ScriptAction const& step = iter->second;
Object* source = NULL;
if(step.sourceGUID)
{
switch(GUID_HIPART(step.sourceGUID))
{
case HIGHGUID_ITEM:
// case HIGHGUID_CONTAINER: ==HIGHGUID_ITEM
{
Player* player = HashMapHolder<Player>::Find(step.ownerGUID);
if(player)
source = player->GetItemByGuid(step.sourceGUID);
break;
}
case HIGHGUID_UNIT:
source = HashMapHolder<Creature>::Find(step.sourceGUID);
break;
case HIGHGUID_PET:
source = HashMapHolder<Pet>::Find(step.sourceGUID);
break;
case HIGHGUID_VEHICLE:
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
break;
case HIGHGUID_PLAYER:
source = HashMapHolder<Player>::Find(step.sourceGUID);
break;
case HIGHGUID_GAMEOBJECT:
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
break;
case HIGHGUID_CORPSE:
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.sourceGUID));
break;
}
}
if(source && !source->IsInWorld()) source = NULL;
Object* target = NULL;
if(step.targetGUID)
{
switch(GUID_HIPART(step.targetGUID))
{
case HIGHGUID_UNIT:
target = HashMapHolder<Creature>::Find(step.targetGUID);
break;
case HIGHGUID_PET:
target = HashMapHolder<Pet>::Find(step.targetGUID);
break;
case HIGHGUID_VEHICLE:
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
break;
case HIGHGUID_PLAYER: // empty GUID case also
target = HashMapHolder<Player>::Find(step.targetGUID);
break;
case HIGHGUID_GAMEOBJECT:
target = HashMapHolder<GameObject>::Find(step.targetGUID);
break;
case HIGHGUID_CORPSE:
target = HashMapHolder<Corpse>::Find(step.targetGUID);
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.targetGUID));
break;
}
}
if(target && !target->IsInWorld()) target = NULL;
switch (step.script->command)
{
case SCRIPT_COMMAND_TALK:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TALK call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
uint64 unit_target = target ? target->GetGUID() : 0;
//datalong 0=normal say, 1=whisper, 2=yell, 3=emote text
switch(step.script->datalong)
{
case 0: // Say
((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 1: // Whisper
if(!unit_target)
{
sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong);
break;
}
((Creature *)source)->Whisper(step.script->dataint,unit_target);
break;
case 2: // Yell
((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 3: // Emote text
((Creature *)source)->TextEmote(step.script->dataint, unit_target);
break;
default:
break; // must be already checked at load
}
break;
}
case SCRIPT_COMMAND_EMOTE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature *)source)->HandleEmoteCommand(step.script->datalong);
break;
case SCRIPT_COMMAND_FIELD_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetUInt32Value(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_MOVE_TO:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature*)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 );
((Creature*)source)->GetMap()->CreatureRelocation(((Creature*)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_FLAG_REMOVE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->RemoveFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_TELEPORT_TO:
{
// accept player in any one from target/source arg
if (!target && !source)
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for NULL object.");
break;
}
// must be only Player
if((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER))
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
break;
}
Player* pSource = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source;
pSource->TeleportTo(step.script->datalong, step.script->x, step.script->y, step.script->z, step.script->o);
break;
}
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
{
if(!step.script->datalong) // creature not specified
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL creature.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
float x = step.script->x;
float y = step.script->y;
float z = step.script->z;
float o = step.script->o;
Creature* pCreature = summoner->SummonCreature(step.script->datalong, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,step.script->datalong2);
if (!pCreature)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON failed for creature (entry: %u).",step.script->datalong);
break;
}
break;
}
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
{
if(!step.script->datalong) // gameobject not specified
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL gameobject.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
GameObject *go = NULL;
int32 time_to_despawn = step.script->datalong2<5 ? 5 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(summoner->GetPositionX(), summoner->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(summoner, go,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *summoner->GetMap());
if ( !go )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if( go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE ||
go->GetGoType()==GAMEOBJECT_TYPE_DOOR ||
go->GetGoType()==GAMEOBJECT_TYPE_BUTTON ||
go->GetGoType()==GAMEOBJECT_TYPE_TRAP )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT can not be used with gameobject of type %u (guid: %u).", uint32(go->GetGoType()), step.script->datalong);
break;
}
if( go->isSpawned() )
break; //gameobject already spawned
go->SetLootState(GO_READY);
go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds
go->GetMap()->Add(go);
break;
}
case SCRIPT_COMMAND_OPEN_DOOR:
{
if(!step.script->datalong) // door not specified
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_close = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if (!door)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if (door->GetGoType() != GAMEOBJECT_TYPE_DOOR)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if (door->GetGoState() != GO_STATE_READY)
break; //door already open
door->UseDoorOrButton(time_to_close);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_close);
break;
}
case SCRIPT_COMMAND_CLOSE_DOOR:
{
if(!step.script->datalong) // guid for door not specified
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_open = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if ( !door )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if( door->GetGoState() == GO_STATE_READY )
break; //door already closed
door->UseDoorOrButton(time_to_open);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_open);
break;
}
case SCRIPT_COMMAND_QUEST_EXPLORED:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL source.");
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL target.");
break;
}
// when script called for item spell casting then target == (unit or GO) and source is player
WorldObject* worldObject;
Player* player;
if(target->GetTypeId()==TYPEID_PLAYER)
{
if(source->GetTypeId()!=TYPEID_UNIT && source->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)source;
player = (Player*)target;
}
else
{
if(target->GetTypeId()!=TYPEID_UNIT && target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
if(source->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-player(TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)target;
player = (Player*)source;
}
// quest id and flags checked at script loading
if( (worldObject->GetTypeId()!=TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) &&
(step.script->datalong2==0 || worldObject->IsWithinDistInMap(player,float(step.script->datalong2))) )
player->AreaExploredOrEventHappens(step.script->datalong);
else
player->FailQuest(step.script->datalong);
break;
}
case SCRIPT_COMMAND_ACTIVATE_OBJECT:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT must have source caster.");
break;
}
if(!source->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT source caster isn't unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for NULL gameobject.");
break;
}
if(target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *go = (GameObject*)target;
go->Use(caster);
break;
}
case SCRIPT_COMMAND_REMOVE_AURA:
{
Object* cmdTarget = step.script->datalong2 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA call for NULL %s.",step.script->datalong2 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
((Unit*)cmdTarget)->RemoveAurasDueToSpell(step.script->datalong);
break;
}
case SCRIPT_COMMAND_CAST_SPELL:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL must have source caster.");
break;
}
Object* cmdTarget = step.script->datalong2 & 0x01 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x01 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x01 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
Unit* spellTarget = (Unit*)cmdTarget;
Object* cmdSource = step.script->datalong2 & 0x02 ? target : source;
if(!cmdSource)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x02 ? "target" : "source");
break;
}
if(!cmdSource->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x02 ? "target" : "source", cmdSource->GetTypeId());
break;
}
Unit* spellSource = (Unit*)cmdSource;
//TODO: when GO cast implemented, code below must be updated accordingly to also allow GO spell cast
spellSource->CastSpell(spellTarget,step.script->datalong,false);
break;
}
case SCRIPT_COMMAND_PLAY_SOUND:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for NULL creature.");
break;
}
WorldObject* pSource = dynamic_cast<WorldObject*>(source);
if(!pSource)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for non-world object (TypeId: %u), skipping.",source->GetTypeId());
break;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
Player* pTarget = NULL;
if(step.script->datalong2 & 1)
{
if(!target)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for NULL target.");
break;
}
if(target->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for non-player (TypeId: %u), skipping.",target->GetTypeId());
break;
}
pTarget = (Player*)target;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
if(step.script->datalong2 & 2)
pSource->PlayDistanceSound(step.script->datalong,pTarget);
else
pSource->PlayDirectSound(step.script->datalong,pTarget);
break;
}
default:
sLog.outError("Unknown script command %u called.",step.script->command);
break;
}
m_scriptSchedule.erase(iter);
iter = m_scriptSchedule.begin();
}
return;
}
/// Send a packet to all players (except self if mentioned) /// Send a packet to all players (except self if mentioned)
void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team) void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team)
{ {

View file

@ -27,6 +27,7 @@
#include "Timer.h" #include "Timer.h"
#include "Policies/Singleton.h" #include "Policies/Singleton.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "ace/Atomic_Op.h"
#include <map> #include <map>
#include <set> #include <set>
@ -482,9 +483,10 @@ class World
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author); BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
bool RemoveBanAccount(BanMode mode, std::string nameOrIP); bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target); uint32 IncreaseScheduledScriptsCount() { return (uint32)++m_scheduledScripts; }
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target); uint32 DecreaseScheduledScriptCount() { return (uint32)--m_scheduledScripts; }
bool IsScriptScheduled() const { return !m_scriptSchedule.empty(); } uint32 DecreaseScheduledScriptCount(size_t count) { return (uint32)(m_scheduledScripts -= count); }
bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
// for max speed access // for max speed access
static float GetMaxVisibleDistanceForCreature() { return m_MaxVisibleDistanceForCreature; } static float GetMaxVisibleDistanceForCreature() { return m_MaxVisibleDistanceForCreature; }
@ -515,7 +517,6 @@ class World
protected: protected:
void _UpdateGameTime(); void _UpdateGameTime();
void ScriptsProcess();
// callback for UpdateRealmCharacters // callback for UpdateRealmCharacters
void _UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId); void _UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId);
@ -527,6 +528,9 @@ class World
uint32 m_ShutdownTimer; uint32 m_ShutdownTimer;
uint32 m_ShutdownMask; uint32 m_ShutdownMask;
//atomic op counter for active scripts amount
ACE_Atomic_Op<ACE_Thread_Mutex, long> m_scheduledScripts;
time_t m_startTime; time_t m_startTime;
time_t m_gameTime; time_t m_gameTime;
IntervalTimer m_timers[WUPDATE_COUNT]; IntervalTimer m_timers[WUPDATE_COUNT];
@ -540,8 +544,6 @@ class World
uint32 m_maxActiveSessionCount; uint32 m_maxActiveSessionCount;
uint32 m_maxQueuedSessionCount; uint32 m_maxQueuedSessionCount;
std::multimap<time_t, ScriptAction> m_scriptSchedule;
float rate_values[MAX_RATES]; float rate_values[MAX_RATES];
uint32 m_configs[CONFIG_VALUE_COUNT]; uint32 m_configs[CONFIG_VALUE_COUNT];
int32 m_playerLimit; int32 m_playerLimit;

View file

@ -19,7 +19,7 @@
## CPP flags for includes, defines, etc. ## CPP flags for includes, defines, etc.
AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../game -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\" AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../game -I$(srcdir) -DSYSCONFDIR=\"$(sysconfdir)/\"
## Build world list daemon as standalone program ## Build world daemon as standalone program
bin_PROGRAMS = mangos-worldd bin_PROGRAMS = mangos-worldd
mangos_worldd_SOURCES = \ mangos_worldd_SOURCES = \
CliRunnable.cpp \ CliRunnable.cpp \
@ -33,7 +33,18 @@ mangos_worldd_SOURCES = \
WorldRunnable.h WorldRunnable.h
## Link world daemon against the shared library ## Link world daemon against the shared library
mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/g3dlite/libg3dlite.a mangos_worldd_LDADD = \
../bindings/universal/libmangosscript.la \
../game/libmangosgame.a \
../shared/Database/libmangosdatabase.a \
../shared/Config/libmangosconfig.a \
../shared/Auth/libmangosauth.a \
../shared/libmangosshared.a \
../shared/vmap/libmangosvmaps.a \
../framework/libmangosframework.a \
../../dep/src/sockets/libmangossockets.a \
../../dep/src/g3dlite/libg3dlite.a
mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/g3dlite -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/g3dlite -L../bindings/universal/ -L$(libdir) $(MANGOS_LIBS) -export-dynamic
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'

View file

@ -30,7 +30,14 @@ mangos_realmd_SOURCES = \
RealmList.h RealmList.h
## Link realm list daemon against the shared library ## Link realm list daemon against the shared library
mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a mangos_realmd_LDADD = \
../shared/Database/libmangosdatabase.a \
../shared/Config/libmangosconfig.a \
../shared/Auth/libmangosauth.a \
../shared/libmangosshared.a \
../framework/libmangosframework.a \
../../dep/src/sockets/libmangossockets.a
mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L$(libdir) $(MANGOS_LIBS) mangos_realmd_LDFLAGS = -L../../dep/src/sockets -L$(libdir) $(MANGOS_LIBS)
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8251" #define REVISION_NR "8266"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -19,12 +19,12 @@
## CPP flags for includes, defines, etc. ## CPP flags for includes, defines, etc.
AM_CPPFLAGS = -I$(srcdir) AM_CPPFLAGS = -I$(srcdir)
## Build world list daemon as standalone program ## Build as standalone program
bin_PROGRAMS = genrevision bin_PROGRAMS = genrevision
genrevision_SOURCES = \ genrevision_SOURCES = \
genrevision.cpp genrevision.cpp
## Link world daemon against the shared library ## Link against the shared library
genrevision_LDADD = genrevision_LDADD =
genrevision_LDFLAGS = -L$(libdir) genrevision_LDFLAGS = -L$(libdir)

View file

@ -372,6 +372,7 @@
<ClCompile Include="..\..\src\game\CalendarHandler.cpp" /> <ClCompile Include="..\..\src\game\CalendarHandler.cpp" />
<ClCompile Include="..\..\src\game\Channel.cpp" /> <ClCompile Include="..\..\src\game\Channel.cpp" />
<ClCompile Include="..\..\src\game\ChannelHandler.cpp" /> <ClCompile Include="..\..\src\game\ChannelHandler.cpp" />
<ClCompile Include="..\..\src\game\ChannelMgr.cpp" />
<ClCompile Include="..\..\src\game\CharacterHandler.cpp" /> <ClCompile Include="..\..\src\game\CharacterHandler.cpp" />
<ClCompile Include="..\..\src\game\Chat.cpp" /> <ClCompile Include="..\..\src\game\Chat.cpp" />
<ClCompile Include="..\..\src\game\ChatHandler.cpp" /> <ClCompile Include="..\..\src\game\ChatHandler.cpp" />

View file

@ -689,6 +689,10 @@
RelativePath="..\..\src\game\ChannelHandler.cpp" RelativePath="..\..\src\game\ChannelHandler.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\game\ChannelMgr.cpp"
>
</File>
<File <File
RelativePath="..\..\src\game\ChannelMgr.h" RelativePath="..\..\src\game\ChannelMgr.h"
> >

View file

@ -690,6 +690,10 @@
RelativePath="..\..\src\game\ChannelHandler.cpp" RelativePath="..\..\src\game\ChannelHandler.cpp"
> >
</File> </File>
<File
RelativePath="..\..\src\game\ChannelMgr.cpp"
>
</File>
<File <File
RelativePath="..\..\src\game\ChannelMgr.h" RelativePath="..\..\src\game\ChannelMgr.h"
> >