From a32b3063a2582734204bc20b797eb62ea85f417a Mon Sep 17 00:00:00 2001 From: Laise Date: Wed, 7 Jul 2010 19:07:53 +0300 Subject: [PATCH] [10156] Add shared object for auras of same spell and move spell proc code to its own file, also spread procs by auras and effect indexes. --- sql/characters.sql | 30 +- sql/mangos.sql | 1162 ++--- .../10156_01_characters_character_aura.sql | 16 + sql/updates/10156_02_characters_pet_aura.sql | 16 + .../10156_03_mangos_spell_proc_event.sql | 589 +++ sql/updates/Makefile.am | 6 + src/game/CharacterHandler.cpp | 2 +- src/game/Creature.cpp | 24 +- src/game/CreatureEventAI.cpp | 12 +- src/game/DynamicObject.cpp | 2 +- src/game/GridNotifiersImpl.h | 24 +- src/game/Level3.cpp | 61 +- src/game/ObjectMgr.cpp | 4 +- src/game/Pet.cpp | 160 +- src/game/Player.cpp | 269 +- src/game/Spell.cpp | 100 +- src/game/Spell.h | 1 + src/game/SpellAuras.cpp | 2459 +++++----- src/game/SpellAuras.h | 276 +- src/game/SpellEffects.cpp | 162 +- src/game/SpellHandler.cpp | 6 + src/game/SpellMgr.cpp | 112 +- src/game/SpellMgr.h | 56 +- src/game/Unit.cpp | 4248 ++--------------- src/game/Unit.h | 101 +- src/game/UnitAuraProcHandler.cpp | 3664 ++++++++++++++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 4 +- win/VC100/game.vcxproj | 4 +- win/VC100/game.vcxproj.filters | 3 + win/VC80/game.vcproj | 4 + win/VC90/game.vcproj | 4 + 32 files changed, 7507 insertions(+), 6076 deletions(-) create mode 100644 sql/updates/10156_01_characters_character_aura.sql create mode 100644 sql/updates/10156_02_characters_pet_aura.sql create mode 100644 sql/updates/10156_03_mangos_spell_proc_event.sql create mode 100644 src/game/UnitAuraProcHandler.cpp diff --git a/sql/characters.sql b/sql/characters.sql index b07245fef..3d4c1a910 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_10051_01_characters_character_aura` bit(1) default NULL + `required_10156_02_characters_pet_aura` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- @@ -371,12 +371,18 @@ CREATE TABLE `character_aura` ( `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', `spell` int(11) unsigned NOT NULL default '0', - `effect_index` int(11) unsigned NOT NULL default '0', `stackcount` int(11) NOT NULL default '1', - `amount` int(11) NOT NULL default '0', - `maxduration` int(11) NOT NULL default '0', - `remaintime` int(11) NOT NULL default '0', `remaincharges` int(11) NOT NULL default '0', + `basepoints0` INT(11) NOT NULL DEFAULT '0', + `basepoints1` INT(11) NOT NULL DEFAULT '0', + `basepoints2` INT(11) NOT NULL DEFAULT '0', + `maxduration0` INT(11) NOT NULL DEFAULT '0', + `maxduration1` INT(11) NOT NULL DEFAULT '0', + `maxduration2` INT(11) NOT NULL DEFAULT '0', + `remaintime0` INT(11) NOT NULL DEFAULT '0', + `remaintime1` INT(11) NOT NULL DEFAULT '0', + `remaintime2` INT(11) NOT NULL DEFAULT '0', + `effIndexMask` INT(11) NOT NULL DEFAULT '0', PRIMARY KEY (`guid`,`spell`,`effect_index`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; @@ -1450,12 +1456,18 @@ CREATE TABLE `pet_aura` ( `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', `spell` int(11) unsigned NOT NULL default '0', - `effect_index` int(11) unsigned NOT NULL default '0', `stackcount` int(11) NOT NULL default '1', - `amount` int(11) NOT NULL default '0', - `maxduration` int(11) NOT NULL default '0', - `remaintime` int(11) NOT NULL default '0', `remaincharges` int(11) NOT NULL default '0', + `basepoints0` INT(11) NOT NULL DEFAULT '0', + `basepoints1` INT(11) NOT NULL DEFAULT '0', + `basepoints2` INT(11) NOT NULL DEFAULT '0', + `maxduration0` INT(11) NOT NULL DEFAULT '0', + `maxduration1` INT(11) NOT NULL DEFAULT '0', + `maxduration2` INT(11) NOT NULL DEFAULT '0', + `remaintime0` INT(11) NOT NULL DEFAULT '0', + `remaintime1` INT(11) NOT NULL DEFAULT '0', + `remaintime2` INT(11) NOT NULL DEFAULT '0', + `effIndexMask` INT(11) NOT NULL DEFAULT '0', PRIMARY KEY (`guid`,`spell`,`effect_index`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; diff --git a/sql/mangos.sql b/sql/mangos.sql index c487d60b7..8d33e0ee6 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_10148_01_mangos_mangos_string` bit(1) default NULL + `required_10156_03_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -17736,21 +17736,26 @@ UNLOCK TABLES; -- -- Table structure for table `spell_proc_event` -- - DROP TABLE IF EXISTS `spell_proc_event`; CREATE TABLE `spell_proc_event` ( - `entry` mediumint(8) unsigned NOT NULL default '0', - `SchoolMask` tinyint(4) unsigned NOT NULL default '0', - `SpellFamilyName` smallint(5) unsigned NOT NULL default '0', - `SpellFamilyMask0` int(10) unsigned NOT NULL default '0', - `SpellFamilyMask1` int(10) unsigned NOT NULL default '0', - `SpellFamilyMask2` int(10) unsigned NOT NULL default '0', - `procFlags` int(10) unsigned NOT NULL default '0', - `procEx` int(10) unsigned NOT NULL default '0', - `ppmRate` float NOT NULL default '0', - `CustomChance` float NOT NULL default '0', - `Cooldown` int(10) unsigned NOT NULL default '0', - PRIMARY KEY (`entry`) + `entry` mediumint(8) unsigned NOT NULL DEFAULT '0', + `SchoolMask` tinyint(4) unsigned NOT NULL DEFAULT '0', + `SpellFamilyName` smallint(5) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskA0` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskA1` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskA2` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskB0` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskB1` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskB2` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskC0` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskC1` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskC2` int(10) unsigned NOT NULL DEFAULT '0', + `procFlags` int(10) unsigned NOT NULL DEFAULT '0', + `procEx` int(10) unsigned NOT NULL DEFAULT '0', + `ppmRate` float NOT NULL DEFAULT '0', + `CustomChance` float NOT NULL DEFAULT '0', + `Cooldown` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- @@ -17760,571 +17765,570 @@ CREATE TABLE `spell_proc_event` ( LOCK TABLES `spell_proc_event` WRITE; /*!40000 ALTER TABLE `spell_proc_event` DISABLE KEYS */; INSERT INTO `spell_proc_event` VALUES -( 324, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -( 974, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -( 3232, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -( 5952, 0x00, 8, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -( 6346, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), -( 7383, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), -( 7434, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -( 8178, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -( 9452, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -( 9782, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -( 9784, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -( 9799, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(11095, 0x00, 3, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(11119, 0x04, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(11129, 0x04, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(11180, 0x10, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(11185, 0x00, 3, 0x00000080, 0x00000000, 0x00000000, 0x00050000, 0x00000000, 0.000000, 0.000000, 0), -(11255, 0x00, 3, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(12169, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(12281, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), -(12289, 0x00, 4, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(12298, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(12311, 0x00, 4, 0x00000800, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(12317, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(12319, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(12322, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), -(12797, 0x00, 4, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(12834, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(12966, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(12967, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(12968, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(12969, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(12970, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(12999, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), -(13000, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), -(13001, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 8.000000, 0.000000, 0), -(13002, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,10.000000, 0.000000, 0), -(13165, 0x00, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(13754, 0x00, 8, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(13983, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000018, 0.000000, 0.000000, 0), -(14156, 0x00, 8, 0x003E0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(14186, 0x00, 8, 0x40800508, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(14531, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(14892, 0x00, 6, 0x10001E00, 0x00010004, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(15088, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(15128, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(15277, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), -(15286, 0x20, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(15337, 0x00, 6, 0x00002000, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(15346, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), -(15600, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), -(16164, 0x1C, 11, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000002, 0.000000, 0.000000, 0), -(16176, 0x00, 11, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16180, 0x00, 11, 0x000001C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16246, 0x00, 11, 0x981001C3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(16256, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16257, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(16277, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(16278, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(16279, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(16280, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(16487, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16550, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16620, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(16624, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(16850, 0x00, 7, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(16864, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), -(16880, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16952, 0x00, 7, 0x00039000, 0x00000400, 0x00040000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16954, 0x00, 7, 0x00039000, 0x00000400, 0x00040000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16958, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(16961, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(17106, 0x00, 7, 0x00080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(17364, 0x08, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(17495, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(17793, 0x00, 5, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(18094, 0x00, 5, 0x0000000A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(18096, 0x00, 5, 0x00000100, 0x00800000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(18119, 0x00, 5, 0x00000000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(18820, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(19184, 0x00, 9, 0x00000010, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(19572, 0x00, 9, 0x00800000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(20049, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(20128, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(20131, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(20132, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(20164, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), -(20165, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0), -(20166, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0), -(20210, 0x00, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(20234, 0x00, 10, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(20335, 0x00, 10, 0x00800000, 0x00000000, 0x00000008, 0x00000100, 0x00000000, 0.000000, 100.000000,0), -(20375, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), -(20500, 0x00, 4, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(20705, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(20784, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(20911, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), -(20925, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(21084, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(21185, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(21882, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(21890, 0x00, 4, 0x2A764EEF, 0x0000036C, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(22007, 0x00, 3, 0x00200021, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(22618, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(22648, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(23547, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), -(23548, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(23551, 0x00, 11, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(23552, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(23572, 0x00, 11, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(23578, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), -(23581, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), -(23602, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(23686, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), -(23688, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(23689, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), -(23721, 0x00, 9, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(23920, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(24353, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(24389, 0x00, 3, 0x00C00017, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(24658, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00014110, 0x00000000, 0.000000, 0.000000, 0), -(24905, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,15.000000, 0.000000, 0), -(24932, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), -(25050, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(25669, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), -(26107, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000064, 0.000000, 0.000000, 0), -(26119, 0x00, 10, 0x90100003, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(26128, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), -(26135, 0x00, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(26480, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(26605, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(27419, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(27498, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(27521, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(27656, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(27774, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(27787, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(27811, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(28716, 0x00, 7, 0x00000010, 0x00000000, 0x00000000, 0x00048000, 0x00000000, 0.000000, 0.000000, 0), -(28719, 0x00, 7, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(28744, 0x00, 7, 0x00000040, 0x00000000, 0x00000000, 0x00044000, 0x00000000, 0.000000, 0.000000, 0), -(28752, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(28789, 0x00, 10, 0xC0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(28802, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(28809, 0x00, 6, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(28812, 0x00, 8, 0x02000006, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(28816, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(28823, 0x00, 11, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(28847, 0x00, 7, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(28849, 0x00, 11, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(29074, 0x14, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(29150, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29385, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), -(29441, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 1), -(29455, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(29501, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29593, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), -(29624, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29625, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29626, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29632, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29633, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29634, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29635, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29636, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29637, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(29834, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(29977, 0x00, 3, 0x00C00017, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30003, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(30160, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(30293, 0x00, 5, 0x00000181, 0x008200C0, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30299, 0x7E, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30675, 0x00, 11, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30701, 0x1C, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30705, 0x1C, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30823, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 10.500000, 0.000000, 0), -(30881, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(30937, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(31124, 0x00, 8, 0x2000000E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(31244, 0x00, 8, 0x003E0000, 0x00000009, 0x00000000, 0x00000000, 0x00002034, 0.000000, 0.000000, 0), -(31394, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(31569, 0x00, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000008, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(31785, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0), -(31794, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(31801, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(31833, 0x00, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(31871, 0x00, 10, 0x00000010, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(31876, 0x00, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0), -(31904, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(32385, 0x00, 5, 0x00000001, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(32587, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(32642, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(32734, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(32748, 0x00, 8, 0x00000000, 0x00000001, 0x00000000, 0x00000140, 0x00000000, 0.000000, 0.000000, 0), -(32776, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(32777, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(32837, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), -(32844, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), -(32885, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(33076, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), -(33089, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(33127, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), -(33142, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(33150, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(33151, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(33191, 0x00, 6, 0x00808000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(33297, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(33299, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(33510, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), -(33648, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(33719, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(33746, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(33757, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(33759, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(33881, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(33953, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), -(34074, 0x00, 9, 0x0007FA43, 0x00881081, 0x00000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(34080, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), -(34138, 0x00, 11, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(34139, 0x00, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(34258, 0x00, 10, 0x00000400, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(34262, 0x00, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(34320, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), -(34355, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(34497, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(34500, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(34506, 0x00, 9, 0x0007FA01, 0x00801081, 0x08000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(34584, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(34586, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 0), -(34598, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(34749, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), -(34753, 0x00, 6, 0x00001800, 0x00000004, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(34774, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 20), -(34783, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(34827, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(34914, 0x00, 6, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(34935, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 8), -(34950, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(35077, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(35080, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 60), -(35083, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(35086, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(35100, 0x00, 9, 0x00001000, 0x00000000, 0x00000001, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), -(35121, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(36096, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(36541, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37165, 0x00, 8, 0x00200400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37168, 0x00, 8, 0x003E0000, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37170, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), -(37173, 0x00, 8, 0x2CBC0598, 0x00000106, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(37189, 0x00, 10, 0xC0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 60), -(37193, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(37195, 0x00, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37197, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), -(37213, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(37214, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(37227, 0x00, 11, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 60), -(37237, 0x00, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(37247, 0x08, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), -(37377, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(37379, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37384, 0x00, 5, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37443, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(37514, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), -(37516, 0x00, 4, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37519, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000030, 0.000000, 0.000000, 0), -(37523, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(37528, 0x00, 4, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37536, 0x00, 4, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37568, 0x00, 6, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37594, 0x00, 6, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37600, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(37601, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(37603, 0x00, 6, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(37655, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(37657, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 3), -(38026, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), -(38031, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(38290, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.600000, 0.000000, 0), -(38299, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 12), -(38326, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(38327, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(38334, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(38347, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), -(38350, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(38394, 0x00, 5, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(38857, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(39027, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(39372, 0x30, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(39437, 0x04, 5, 0x00001364, 0x000000C0, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(39442, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0.000000, 0.000000, 0), -(39443, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(39530, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(39958, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.700000, 0.000000, 40), -(40407, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), -(40438, 0x00, 6, 0x00008040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40442, 0x00, 7, 0x00000014, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40444, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(40458, 0x00, 4, 0x02000000, 0x00000601, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40463, 0x00, 11, 0x00000081, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40470, 0x00, 10, 0xC0800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40475, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), -(40478, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40482, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(40485, 0x00, 9, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(40899, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(41034, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), -(41260, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(41262, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(41381, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), -(41393, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), -(41434, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 45), -(41469, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), -(41635, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), -(41989, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.500000, 0.000000, 0), -(42083, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), -(42135, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), -(42136, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), -(42368, 0x00, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(42370, 0x00, 11, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(42770, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(43338, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(43443, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(43726, 0x00, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43728, 0x00, 11, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43737, 0x00, 7, 0x00000000, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(43739, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43741, 0x00, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43745, 0x00, 10, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43748, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43750, 0x00, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(43819, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(44404, 0x00, 3, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(44442, 0x00, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1), -(44445, 0x00, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(44449, 0x00, 3, 0x20E21277, 0x00019048, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(44546, 0x00, 3, 0x020002A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(44835, 0x00, 7, 0x00000000, 0x00000080, 0x00000000, 0x00000010, 0x00000000, 0.000000, 0.000000, 0), -(45054, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), -(45057, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(45234, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(45354, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(45355, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(45481, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(45482, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(45483, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(45484, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), -(46025, 0x20, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(46092, 0x00, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(46098, 0x00, 11, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(46569, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(46662, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 20), -(46832, 0x00, 7, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(46854, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(46867, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(46913, 0x00, 4, 0x00000040, 0x00000404, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(46916, 0x00, 4, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(46951, 0x00, 4, 0x00000400, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47195, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(47201, 0x00, 5, 0x00000008, 0x00040000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(47245, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47258, 0x00, 5, 0x00000000, 0x00800000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(47263, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), -(47264, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), -(47265, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), -(47509, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(47516, 0x00, 6, 0x00001800, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47569, 0x00, 6, 0x00004000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(47580, 0x00, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(48110, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), -(48111, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), -(48483, 0x00, 7, 0x00008800, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(48496, 0x00, 7, 0x00000060, 0x02000002, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(48506, 0x00, 7, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(48516, 0x00, 7, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 30), -(48539, 0x00, 7, 0x00000010, 0x04000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), -(48833, 0x00, 7, 0x00000000, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(48835, 0x00, 10, 0x00000000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(48837, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(48988, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(49018, 0x00, 15, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(49188, 0x00, 15, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(49208, 0x00, 15, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(49222, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(49622, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(50781, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), -(50880, 0x10, 15, 0x00000000, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(51123, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(51346, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(51349, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(51352, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(51359, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), -(51414, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(51474, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(51483, 0x01, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(51521, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), -(51528, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0), -(51556, 0x00, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(51562, 0x00, 11, 0x00000100, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(51625, 0x00, 8, 0x1000A000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(51627, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), -(51634, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(51664, 0x00, 8, 0x00020000, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(51672, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 1), -(51692, 0x00, 8, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(51698, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1), -(51940, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), -(51989, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), -(52004, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), -(52005, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), -(52007, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), -(52008, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), -(52020, 0x00, 7, 0x00008000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(52127, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(52420, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), -(52423, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), -(53527, 0x00, 10, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(52795, 0x00, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(52898, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53215, 0x00, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(53221, 0x00, 9, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(53228, 0x00, 9, 0x00000020, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(53234, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53256, 0x00, 9, 0x00000800, 0x00800001, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53290, 0x00, 9, 0x00000800, 0x00000001, 0x00000200, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53380, 0x00, 10, 0x00800000, 0x00028000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53397, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53486, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53501, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53551, 0x00, 10, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(53569, 0x00, 10, 0x00200000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53601, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 6), -(53646, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(53671, 0x00, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(53709, 0x00, 10, 0x00004000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), -(53817, 0x00, 11, 0x000001C3, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(54149, 0x00, 10, 0x00200000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(54278, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(54646, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(54695, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(54707, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(54738, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), -(54747, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(54754, 0x00, 7, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(54808, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(54838, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(54841, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 3), -(54937, 0x00, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(54939, 0x00, 10, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(55166, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(55380, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(55440, 0x00, 11, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(55640, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(55666, 0x00, 15, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(55677, 0x00, 6, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(55680, 0x00, 6, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(55689, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(55747, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(55768, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(55776, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(56218, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(56342, 0x00, 9, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(56355, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(56364, 0x00, 3, 0x00000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(56372, 0x00, 3, 0x00000000, 0x00000080, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(56375, 0x00, 3, 0x01000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), -(56451, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), -(56636, 0x00, 4, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), -(56816, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000030, 0.000000, 0.000000, 0), -(56821, 0x00, 8, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(57345, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(57352, 0x00, 0, 0x00000001, 0x00000040, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), -(57470, 0x00, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(57499, 0x00, 4, 0x40000001, 0x00010000, 0x00000000, 0x00014000, 0x00000000, 0.000000, 0.000000, 0), -(57870, 0x00, 9, 0x00800000, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), -(57878, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), -(57989, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0.000000, 0.000000, 0), -(58357, 0x00, 4, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(58364, 0x00, 4, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58372, 0x00, 4, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58386, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), -(58442, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), -(58444, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 5), -(58597, 0x00, 10, 0x40000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,6), -(58616, 0x00, 15, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58620, 0x00, 15, 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58626, 0x00, 15, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58644, 0x00, 15, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58647, 0x00, 15, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(58677, 0x00, 15, 0x00002000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(58872, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), -(58901, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), -(59176, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(59327, 0x00, 15, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(59345, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(59630, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(59725, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), -(60061, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60063, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60066, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60132, 0x00, 15, 0x00000000, 0x08020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60170, 0x00, 5, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60172, 0x00, 5, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(60221, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60301, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60306, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60317, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60436, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60442, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60473, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60482, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60487, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), -(60490, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60493, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60503, 0x00, 4, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60519, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60529, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(60537, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), -(60564, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60571, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60572, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60573, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60574, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60575, 0x00, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60617, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), -(60710, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60717, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60719, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60722, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60724, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60726, 0x00, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60770, 0x00, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60818, 0x00, 10, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(60826, 0x00, 15, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(61062, 0x00, 3, 0x00000000, 0x00000100, 0x00000000, 0x00004000, 0x00010000, 0.000000, 0.000000, 0), -(61188, 0x00, 5, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(61257, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0), -(61324, 0x00, 10, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(61356, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000002A8, 0x00000002, 0.000000, 0.000000, 45), -(61618, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(61846, 0x00, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(62600, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(63108, 0x00, 5, 0x00000002, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), -(63156, 0x00, 0, 0x00000001, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(63280, 0x00, 11, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(63320, 0x00, 5, 0x00040000, 0x00000000, 0x00008000, 0x00004000, 0x00000001, 0.000000, 0.000000, 0), -(63373, 0x00, 11, 0x80000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), -(63534, 0x00, 6, 0x00000040, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), -(63611, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00050014, 0x00000000, 0.000000, 0.000000, 0), -(63625, 0x00, 6, 0x02000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), -(63730, 0x00, 6, 0x00000800, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(64928, 0x00, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), -(64976, 0x00, 4, 0x00000001, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), -(65661, 0x00, 15, 0x00400011 ,0x20020004 ,0x00000000, 0x00000010, 0x00000000, 0.000000, 100.000000,0), -(64127, 0x00, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(67228, 0x04, 11, 0x00000000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(67353, 0x00, 7, 0x00008000, 0x00100500, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(67361, 0x40, 7, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), -(67667, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(67672, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 50), -(67702, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(67771, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), -(70664, 0x00, 7, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(70748, 0x00, 3, 0x00000000, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); +( 324, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +( 974, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +( 3232, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +( 5952, 0x00, 8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +( 6346, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +( 7383, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +( 7434, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +( 8178, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +( 9452, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +( 9782, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +( 9784, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +( 9799, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(11095, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(11119, 0x04, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(11129, 0x04, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(11180, 0x10, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(11185, 0x00, 3, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050000, 0x00000000, 0.000000, 0.000000, 0), +(11255, 0x00, 3, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(12169, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(12281, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), +(12289, 0x00, 4, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(12298, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(12311, 0x00, 4, 0x00000800, 0x00000800, 0x00000800, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(12317, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(12319, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(12322, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(12834, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(12966, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12967, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12968, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12969, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12970, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12999, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), +(13000, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(13001, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 8.000000, 0.000000, 0), +(13002, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,10.000000, 0.000000, 0), +(13165, 0x00, 9, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(13754, 0x00, 8, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(13983, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000018, 0.000000, 0.000000, 0), +(14156, 0x00, 8, 0x003E0000, 0x003E0000, 0x003E0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(14186, 0x00, 8, 0x40800508, 0x40800508, 0x40800508, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(14531, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(14892, 0x00, 6, 0x10001E00, 0x10001E00, 0x10001E00, 0x00010004, 0x00010004, 0x00010004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(15088, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(15128, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(15277, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(15286, 0x20, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(15337, 0x00, 6, 0x00002000, 0x00002000, 0x00002000, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(15346, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(15600, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), +(16164, 0x1C, 11, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000002, 0.000000, 0.000000, 0), +(16176, 0x00, 11, 0x000001C0, 0x000001C0, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16180, 0x00, 11, 0x000001C0, 0x000001C0, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16246, 0x00, 11, 0x981001C3, 0x981001C3, 0x981001C3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(16256, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16257, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16277, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16278, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16279, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16280, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16487, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16550, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16620, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(16624, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(16850, 0x00, 7, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(16864, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(16880, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16952, 0x00, 7, 0x00039000, 0x00039000, 0x00039000, 0x00000400, 0x00000400, 0x00000400, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16954, 0x00, 7, 0x00039000, 0x00039000, 0x00039000, 0x00000400, 0x00000400, 0x00000400, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16958, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16961, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(17106, 0x00, 7, 0x00080000, 0x00080000, 0x00080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(17364, 0x08, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(17495, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(17793, 0x00, 5, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(18094, 0x00, 5, 0x0000000A, 0x0000000A, 0x0000000A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(18096, 0x00, 5, 0x00000100, 0x00000100, 0x00000100, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(18119, 0x00, 5, 0x00000000, 0x00000000, 0x00000000, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(18820, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(19184, 0x00, 9, 0x00000010, 0x00000010, 0x00000010, 0x00002000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(19572, 0x00, 9, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(20049, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20128, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(20131, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(20132, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(20164, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), +(20165, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0), +(20166, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0), +(20210, 0x00, 10, 0xC0000000, 0xC0000000, 0xC0000000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20234, 0x00, 10, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(20335, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00000100, 0x00000000, 0.000000, 100.000000,0), +(20375, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), +(20500, 0x00, 4, 0x10000000, 0x10000000, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(20705, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20784, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20911, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), +(20925, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(21084, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(21185, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(21882, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(21890, 0x00, 4, 0x2A764EEF, 0x2A764EEF, 0x2A764EEF, 0x0000036C, 0x0000036C, 0x0000036C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(22007, 0x00, 3, 0x00200021, 0x00200021, 0x00200021, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(22618, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(22648, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(23547, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(23548, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(23551, 0x00, 11, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(23552, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(23572, 0x00, 11, 0x000000C0, 0x000000C0, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(23578, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(23581, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(23602, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(23686, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(23688, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(23689, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), +(23721, 0x00, 9, 0x00000800, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(23920, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(24353, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(24389, 0x00, 3, 0x00C00017, 0x00C00017, 0x00C00017, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(24658, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00014110, 0x00000000, 0.000000, 0.000000, 0), +(24905, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,15.000000, 0.000000, 0), +(24932, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), +(25050, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(25669, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), +(26107, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000064, 0.000000, 0.000000, 0), +(26119, 0x00, 10, 0x90100003, 0x90100003, 0x90100003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(26128, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), +(26135, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(26480, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(26605, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(27419, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27498, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27521, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(27656, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27774, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(27787, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27811, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28716, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00048000, 0x00000000, 0.000000, 0.000000, 0), +(28719, 0x00, 7, 0x00000020, 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28744, 0x00, 7, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00044000, 0x00000000, 0.000000, 0.000000, 0), +(28752, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28789, 0x00, 10, 0xC0000000, 0xC0000000, 0xC0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(28802, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(28809, 0x00, 6, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28812, 0x00, 8, 0x02000006, 0x02000006, 0x02000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28816, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(28823, 0x00, 11, 0x000000C0, 0x000000C0, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(28847, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(28849, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(29074, 0x14, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(29150, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29385, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), +(29441, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 1), +(29455, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(29501, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29593, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), +(29624, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29625, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29626, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29632, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29633, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29634, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29635, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29636, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29637, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29834, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(29977, 0x00, 3, 0x00C00017, 0x00C00017, 0x00C00017, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30003, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(30160, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(30293, 0x00, 5, 0x00000181, 0x00000181, 0x00000181, 0x008200C0, 0x008200C0, 0x008200C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30299, 0x7E, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30675, 0x00, 11, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30701, 0x1C, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30705, 0x1C, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30823, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 10.500000, 0.000000, 0), +(30881, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(30937, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31124, 0x00, 8, 0x2000000E, 0x2000000E, 0x2000000E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31244, 0x00, 8, 0x003E0000, 0x003E0000, 0x003E0000, 0x00000009, 0x00000009, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00002034, 0.000000, 0.000000, 0), +(31394, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31569, 0x00, 3, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(31785, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0), +(31794, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(31801, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31833, 0x00, 10, 0x80000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31871, 0x00, 10, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(31876, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0), +(31904, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32385, 0x00, 5, 0x00000001, 0x00000001, 0x00000001, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(32587, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32642, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32734, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(32748, 0x00, 8, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000140, 0x00000000, 0.000000, 0.000000, 0), +(32776, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32777, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32837, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), +(32844, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(32885, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33076, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(33089, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(33127, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), +(33142, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33150, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33151, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33191, 0x00, 6, 0x00808000, 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(33297, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(33299, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(33510, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), +(33648, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33719, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(33746, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(33757, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(33759, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(33881, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33953, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), +(34074, 0x00, 9, 0x0007FA43, 0x0007FA43, 0x0007FA43, 0x00881081, 0x00881081, 0x00881081, 0x00000201, 0x00000201, 0x00000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34080, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), +(34138, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34139, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34258, 0x00, 10, 0x00000400, 0x00000400, 0x00000400, 0x00000008, 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34262, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(34320, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(34355, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(34497, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34500, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34506, 0x00, 9, 0x0007FA01, 0x0007FA01, 0x0007FA01, 0x00801081, 0x00801081, 0x00801081, 0x08000201, 0x08000201, 0x08000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34584, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(34586, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 0), +(34598, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(34749, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), +(34753, 0x00, 6, 0x00001800, 0x00001800, 0x00001800, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34774, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 20), +(34783, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(34827, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(34914, 0x00, 6, 0x00002000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34935, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 8), +(34950, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(35077, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(35080, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 60), +(35083, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(35086, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(35100, 0x00, 9, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), +(35121, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(36096, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(36541, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37165, 0x00, 8, 0x00200400, 0x00200400, 0x00200400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37168, 0x00, 8, 0x003E0000, 0x003E0000, 0x003E0000, 0x00000009, 0x00000009, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37170, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), +(37173, 0x00, 8, 0x2CBC0598, 0x2CBC0598, 0x2CBC0598, 0x00000106, 0x00000106, 0x00000106, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(37189, 0x00, 10, 0xC0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 60), +(37193, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(37195, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37197, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), +(37213, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(37214, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37227, 0x00, 11, 0x000001C0, 0x000001C0, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 60), +(37237, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(37247, 0x08, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), +(37377, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37379, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37384, 0x00, 5, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37443, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(37514, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(37516, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37519, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000030, 0.000000, 0.000000, 0), +(37523, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(37528, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37536, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37568, 0x00, 6, 0x00000800, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37594, 0x00, 6, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37600, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37601, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37603, 0x00, 6, 0x00008000, 0x00008000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37655, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(37657, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 3), +(38026, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +(38031, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(38290, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.600000, 0.000000, 0), +(38299, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 12), +(38326, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(38327, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(38334, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(38347, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(38350, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(38394, 0x00, 5, 0x00000006, 0x00000006, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(38857, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(39027, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(39372, 0x30, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(39437, 0x04, 5, 0x00001364, 0x00001364, 0x00001364, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(39442, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0.000000, 0.000000, 0), +(39443, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(39530, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(39958, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.700000, 0.000000, 40), +(40407, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(40438, 0x00, 6, 0x00008040, 0x00008040, 0x00008040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40442, 0x00, 7, 0x00000014, 0x00000014, 0x00000014, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40444, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(40458, 0x00, 4, 0x02000000, 0x02000000, 0x02000000, 0x00000601, 0x00000601, 0x00000601, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40463, 0x00, 11, 0x00000081, 0x00000081, 0x00000081, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40470, 0x00, 10, 0xC0800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40475, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(40478, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40482, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(40485, 0x00, 9, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40899, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(41034, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), +(41260, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(41262, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(41381, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +(41393, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(41434, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 45), +(41469, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), +(41635, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(41989, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.500000, 0.000000, 0), +(42083, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(42135, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), +(42136, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), +(42368, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(42370, 0x00, 11, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(42770, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(43338, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(43443, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(43726, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43728, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43737, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(43739, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43741, 0x00, 10, 0x80000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43745, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43748, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43750, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43819, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(44404, 0x00, 3, 0x20000021, 0x20000021, 0x20000021, 0x00009000, 0x00009000, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(44442, 0x00, 3, 0x00800000, 0x00800000, 0x00800000, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1), +(44445, 0x00, 3, 0x00000013, 0x00000013, 0x00000013, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(44449, 0x00, 3, 0x20E21277, 0x20E21277, 0x20E21277, 0x00019048, 0x00019048, 0x00019048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(44546, 0x00, 3, 0x020002A0, 0x020002A0, 0x020002A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(44835, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0.000000, 0.000000, 0), +(45054, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), +(45057, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(45234, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(45354, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45355, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45481, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45482, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45483, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45484, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), +(46025, 0x20, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46092, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46098, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46569, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(46662, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 20), +(46832, 0x00, 7, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(46854, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46867, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46913, 0x00, 4, 0x00000040, 0x00000040, 0x00000040, 0x00000404, 0x00000404, 0x00000404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46916, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46951, 0x00, 4, 0x00000400, 0x00000400, 0x00000400, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47195, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(47201, 0x00, 5, 0x00000008, 0x00000008, 0x00000008, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47245, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47258, 0x00, 5, 0x00000000, 0x00000000, 0x00000000, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47263, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), +(47264, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), +(47265, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), +(47509, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(47516, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47569, 0x00, 6, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(47580, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(48110, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(48111, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(48483, 0x00, 7, 0x00008800, 0x00008800, 0x00008800, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48496, 0x00, 7, 0x00000060, 0x00000060, 0x00000060, 0x02000002, 0x02000002, 0x02000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(48506, 0x00, 7, 0x00000005, 0x00000005, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48516, 0x00, 7, 0x00000005, 0x00000005, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 30), +(48539, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x04000000, 0x04000000, 0x04000000, 0x00000000, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), +(48833, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48835, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48837, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48988, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(49018, 0x00, 15, 0x01400000, 0x01400000, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(49188, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(49208, 0x00, 15, 0x00440000, 0x00440000, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(49222, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(49622, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(50781, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), +(50880, 0x10, 15, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51123, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51346, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51349, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51352, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51359, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51414, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(51474, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(51483, 0x01, 11, 0x20000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(51521, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), +(51528, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0), +(51556, 0x00, 11, 0x000000C0, 0x000000C0, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51562, 0x00, 11, 0x00000100, 0x00000100, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51625, 0x00, 8, 0x1000A000, 0x1000A000, 0x1000A000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51627, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), +(51634, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51664, 0x00, 8, 0x00020000, 0x00020000, 0x00020000, 0x00000008, 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51672, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 1), +(51692, 0x00, 8, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51698, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1), +(51940, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(51989, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52004, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52005, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52007, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52008, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52020, 0x00, 7, 0x00008000, 0x00008000, 0x00008000, 0x00100000, 0x00100000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(52127, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(52420, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(52423, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(53527, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(52795, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(52898, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53215, 0x00, 9, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53221, 0x00, 9, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53228, 0x00, 9, 0x00000020, 0x00000020, 0x00000020, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53234, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53256, 0x00, 9, 0x00000800, 0x00000800, 0x00000800, 0x00800001, 0x00800001, 0x00800001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53290, 0x00, 9, 0x00000800, 0x00000800, 0x00000800, 0x00000001, 0x00000001, 0x00000001, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53380, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00028000, 0x00028000, 0x00028000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53397, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53486, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53501, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53551, 0x00, 10, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53569, 0x00, 10, 0x00200000, 0x00200000, 0x00200000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53601, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 6), +(53646, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53671, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53709, 0x00, 10, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), +(53817, 0x00, 11, 0x00000000, 0x000001C3, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54149, 0x00, 10, 0x00200000, 0x00200000, 0x00200000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(54278, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(54646, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(54695, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(54707, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(54738, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(54747, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(54754, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54808, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(54838, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(54841, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 3), +(54937, 0x00, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54939, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55166, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(55380, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55440, 0x00, 11, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55640, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55666, 0x00, 15, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55677, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55680, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55689, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(55747, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55768, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55776, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(56218, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(56342, 0x00, 9, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(56355, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(56364, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(56372, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(56375, 0x00, 3, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(56451, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(56636, 0x00, 4, 0x00000020, 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), +(56816, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000030, 0.000000, 0.000000, 0), +(56821, 0x00, 8, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(57345, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(57352, 0x00, 0, 0x00000001, 0x00000001, 0x00000001, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), +(57470, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(57499, 0x00, 4, 0x40000001, 0x40000001, 0x40000001, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00014000, 0x00000000, 0.000000, 0.000000, 0), +(57870, 0x00, 9, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), +(57878, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), +(57989, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0.000000, 0.000000, 0), +(58357, 0x00, 4, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(58364, 0x00, 4, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58372, 0x00, 4, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58386, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(58442, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), +(58444, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 5), +(58597, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,6), +(58616, 0x00, 15, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58620, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58626, 0x00, 15, 0x00000000, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58644, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58647, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58677, 0x00, 15, 0x00002000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(58872, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(58901, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(59176, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(59327, 0x00, 15, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(59345, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(59630, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(59725, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(60061, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60063, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60066, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60132, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x08020000, 0x08020000, 0x08020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60170, 0x00, 5, 0x00000006, 0x00000006, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60172, 0x00, 5, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(60221, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60301, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60306, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60317, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60436, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60442, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60473, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60482, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60487, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), +(60490, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60493, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60503, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60519, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60529, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60537, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(60564, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60571, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60572, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60573, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60574, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60575, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60617, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(60710, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60717, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60719, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60722, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60724, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60726, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60770, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60818, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60826, 0x00, 15, 0x01400000, 0x01400000, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61062, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00010000, 0.000000, 0.000000, 0), +(61188, 0x00, 5, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61257, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0), +(61324, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61356, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000002A8, 0x00000002, 0.000000, 0.000000, 45), +(61618, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(61846, 0x00, 9, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(62600, 0x7F, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(63108, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63156, 0x00, 0, 0x00000001, 0x00000001, 0x00000001, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63280, 0x00, 11, 0x20000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63320, 0x00, 5, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00008000, 0x00004000, 0x00000001, 0.000000, 0.000000, 0), +(63373, 0x00, 11, 0x80000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(63534, 0x00, 6, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(63611, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050014, 0x00000000, 0.000000, 0.000000, 0), +(63625, 0x00, 6, 0x02000000, 0x02000000, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(63730, 0x00, 6, 0x00000800, 0x00000800, 0x00000800, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(64928, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(64976, 0x00, 4, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(65661, 0x00, 15, 0x00400011 ,0x00400011, 0x00400011, 0x20020004, 0x20020004, 0x20020004, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0.000000, 100.000000,0), +(64127, 0x00, 6, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(67228, 0x04, 11, 0x00000000, 0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(67353, 0x00, 7, 0x00008000, 0x00008000, 0x00008000, 0x00100500, 0x00100500, 0x00100500, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(67361, 0x40, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), +(67667, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(67672, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 50), +(67702, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(67771, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(70664, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(70748, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00200000, 0x00200000, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); /*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/10156_01_characters_character_aura.sql b/sql/updates/10156_01_characters_character_aura.sql new file mode 100644 index 000000000..73ae864c7 --- /dev/null +++ b/sql/updates/10156_01_characters_character_aura.sql @@ -0,0 +1,16 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_10051_01_characters_character_aura required_10156_01_characters_character_aura bit; + +DELETE FROM `character_aura`; +ALTER TABLE `character_aura` + DROP COLUMN `effect_index`, DROP COLUMN `amount`, DROP COLUMN `maxduration`, DROP COLUMN `remaintime`; +ALTER TABLE `character_aura` + ADD COLUMN `basepoints0` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `basepoints1` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `basepoints2` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `maxduration0` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `maxduration1` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `maxduration2` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `remaintime0` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `remaintime1` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `remaintime2` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `effIndexMask` INT(11) NOT NULL DEFAULT '0'; \ No newline at end of file diff --git a/sql/updates/10156_02_characters_pet_aura.sql b/sql/updates/10156_02_characters_pet_aura.sql new file mode 100644 index 000000000..b7f9c5fcb --- /dev/null +++ b/sql/updates/10156_02_characters_pet_aura.sql @@ -0,0 +1,16 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_10156_01_characters_character_aura required_10156_02_characters_pet_aura bit; + +DELETE FROM `pet_aura`; +ALTER TABLE `pet_aura` + DROP COLUMN `effect_index`, DROP COLUMN `amount`, DROP COLUMN `maxduration`, DROP COLUMN `remaintime`; +ALTER TABLE `pet_aura` + ADD COLUMN `basepoints0` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `basepoints1` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `basepoints2` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `maxduration0` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `maxduration1` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `maxduration2` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `remaintime0` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `remaintime1` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `remaintime2` INT(11) NOT NULL DEFAULT '0', + ADD COLUMN `effIndexMask` INT(11) NOT NULL DEFAULT '0'; \ No newline at end of file diff --git a/sql/updates/10156_03_mangos_spell_proc_event.sql b/sql/updates/10156_03_mangos_spell_proc_event.sql new file mode 100644 index 000000000..1321a124d --- /dev/null +++ b/sql/updates/10156_03_mangos_spell_proc_event.sql @@ -0,0 +1,589 @@ +ALTER TABLE db_version CHANGE COLUMN required_10148_01_mangos_mangos_string required_10156_03_mangos_spell_proc_event bit; + +DROP TABLE IF EXISTS `spell_proc_event`; +CREATE TABLE `spell_proc_event` ( + `entry` mediumint(8) unsigned NOT NULL DEFAULT '0', + `SchoolMask` tinyint(4) unsigned NOT NULL DEFAULT '0', + `SpellFamilyName` smallint(5) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskA0` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskA1` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskA2` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskB0` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskB1` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskB2` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskC0` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskC1` int(10) unsigned NOT NULL DEFAULT '0', + `SpellFamilyMaskC2` int(10) unsigned NOT NULL DEFAULT '0', + `procFlags` int(10) unsigned NOT NULL DEFAULT '0', + `procEx` int(10) unsigned NOT NULL DEFAULT '0', + `ppmRate` float NOT NULL DEFAULT '0', + `CustomChance` float NOT NULL DEFAULT '0', + `Cooldown` int(10) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `spell_proc_event` VALUES +( 324, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +( 974, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +( 3232, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +( 5952, 0x00, 8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +( 6346, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +( 7383, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +( 7434, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +( 8178, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +( 9452, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +( 9782, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +( 9784, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +( 9799, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(11095, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(11119, 0x04, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(11129, 0x04, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(11180, 0x10, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(11185, 0x00, 3, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050000, 0x00000000, 0.000000, 0.000000, 0), +(11255, 0x00, 3, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(12169, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(12281, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), +(12289, 0x00, 4, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(12298, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(12311, 0x00, 4, 0x00000800, 0x00000800, 0x00000800, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(12317, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(12319, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(12322, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(12834, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(12966, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12967, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12968, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12969, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12970, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(12999, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), +(13000, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(13001, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 8.000000, 0.000000, 0), +(13002, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,10.000000, 0.000000, 0), +(13165, 0x00, 9, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(13754, 0x00, 8, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(13983, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000018, 0.000000, 0.000000, 0), +(14156, 0x00, 8, 0x003E0000, 0x003E0000, 0x003E0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(14186, 0x00, 8, 0x40800508, 0x40800508, 0x40800508, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(14531, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(14892, 0x00, 6, 0x10001E00, 0x10001E00, 0x10001E00, 0x00010004, 0x00010004, 0x00010004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(15088, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(15128, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(15277, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(15286, 0x20, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(15337, 0x00, 6, 0x00002000, 0x00002000, 0x00002000, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(15346, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(15600, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), +(16164, 0x1C, 11, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000002, 0.000000, 0.000000, 0), +(16176, 0x00, 11, 0x000001C0, 0x000001C0, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16180, 0x00, 11, 0x000001C0, 0x000001C0, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16246, 0x00, 11, 0x981001C3, 0x981001C3, 0x981001C3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(16256, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16257, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16277, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16278, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16279, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16280, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(16487, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16550, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16620, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(16624, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(16850, 0x00, 7, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(16864, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(16880, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16952, 0x00, 7, 0x00039000, 0x00039000, 0x00039000, 0x00000400, 0x00000400, 0x00000400, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16954, 0x00, 7, 0x00039000, 0x00039000, 0x00039000, 0x00000400, 0x00000400, 0x00000400, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16958, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16961, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(17106, 0x00, 7, 0x00080000, 0x00080000, 0x00080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(17364, 0x08, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(17495, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(17793, 0x00, 5, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(18094, 0x00, 5, 0x0000000A, 0x0000000A, 0x0000000A, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(18096, 0x00, 5, 0x00000100, 0x00000100, 0x00000100, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(18119, 0x00, 5, 0x00000000, 0x00000000, 0x00000000, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(18820, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(19184, 0x00, 9, 0x00000010, 0x00000010, 0x00000010, 0x00002000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(19572, 0x00, 9, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(20049, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20128, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(20131, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(20132, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(20164, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), +(20165, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0), +(20166, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0), +(20210, 0x00, 10, 0xC0000000, 0xC0000000, 0xC0000000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20234, 0x00, 10, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(20335, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00000100, 0x00000000, 0.000000, 100.000000,0), +(20375, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), +(20500, 0x00, 4, 0x10000000, 0x10000000, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(20705, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20784, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(20911, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), +(20925, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(21084, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(21185, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(21882, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(21890, 0x00, 4, 0x2A764EEF, 0x2A764EEF, 0x2A764EEF, 0x0000036C, 0x0000036C, 0x0000036C, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(22007, 0x00, 3, 0x00200021, 0x00200021, 0x00200021, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(22618, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(22648, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(23547, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(23548, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(23551, 0x00, 11, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(23552, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(23572, 0x00, 11, 0x000000C0, 0x000000C0, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(23578, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(23581, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(23602, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(23686, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(23688, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(23689, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0), +(23721, 0x00, 9, 0x00000800, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(23920, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(24353, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(24389, 0x00, 3, 0x00C00017, 0x00C00017, 0x00C00017, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(24658, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00014110, 0x00000000, 0.000000, 0.000000, 0), +(24905, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,15.000000, 0.000000, 0), +(24932, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), +(25050, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(25669, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), +(26107, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000064, 0.000000, 0.000000, 0), +(26119, 0x00, 10, 0x90100003, 0x90100003, 0x90100003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(26128, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), +(26135, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(26480, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(26605, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(27419, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27498, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27521, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(27656, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27774, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(27787, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(27811, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28716, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00048000, 0x00000000, 0.000000, 0.000000, 0), +(28719, 0x00, 7, 0x00000020, 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28744, 0x00, 7, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00044000, 0x00000000, 0.000000, 0.000000, 0), +(28752, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28789, 0x00, 10, 0xC0000000, 0xC0000000, 0xC0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(28802, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(28809, 0x00, 6, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28812, 0x00, 8, 0x02000006, 0x02000006, 0x02000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(28816, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(28823, 0x00, 11, 0x000000C0, 0x000000C0, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(28847, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(28849, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(29074, 0x14, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(29150, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29385, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), +(29441, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 1), +(29455, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(29501, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29593, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), +(29624, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29625, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29626, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29632, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29633, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29634, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29635, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29636, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29637, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(29834, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(29977, 0x00, 3, 0x00C00017, 0x00C00017, 0x00C00017, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30003, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(30160, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(30293, 0x00, 5, 0x00000181, 0x00000181, 0x00000181, 0x008200C0, 0x008200C0, 0x008200C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30299, 0x7E, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30675, 0x00, 11, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30701, 0x1C, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30705, 0x1C, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30823, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 10.500000, 0.000000, 0), +(30881, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(30937, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31124, 0x00, 8, 0x2000000E, 0x2000000E, 0x2000000E, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31244, 0x00, 8, 0x003E0000, 0x003E0000, 0x003E0000, 0x00000009, 0x00000009, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00002034, 0.000000, 0.000000, 0), +(31394, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31569, 0x00, 3, 0x00000000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31571, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(31785, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0), +(31794, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(31801, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31833, 0x00, 10, 0x80000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31871, 0x00, 10, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(31876, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0), +(31904, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32385, 0x00, 5, 0x00000001, 0x00000001, 0x00000001, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(32587, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32642, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32734, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(32748, 0x00, 8, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000140, 0x00000000, 0.000000, 0.000000, 0), +(32776, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32777, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(32837, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), +(32844, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 0), +(32885, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33076, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(33089, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(33127, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), +(33142, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33150, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33151, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33191, 0x00, 6, 0x00808000, 0x00000000, 0x00000000, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(33297, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(33299, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(33510, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0), +(33648, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33719, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(33746, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(33757, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(33759, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(33881, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(33953, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), +(34074, 0x00, 9, 0x0007FA43, 0x0007FA43, 0x0007FA43, 0x00881081, 0x00881081, 0x00881081, 0x00000201, 0x00000201, 0x00000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34080, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), +(34138, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34139, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34258, 0x00, 10, 0x00000400, 0x00000400, 0x00000400, 0x00000008, 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34262, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(34320, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(34355, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(34497, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34500, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34506, 0x00, 9, 0x0007FA01, 0x0007FA01, 0x0007FA01, 0x00801081, 0x00801081, 0x00801081, 0x08000201, 0x08000201, 0x08000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34584, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(34586, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 0), +(34598, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(34749, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), +(34753, 0x00, 6, 0x00001800, 0x00001800, 0x00001800, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(34774, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.500000, 0.000000, 20), +(34783, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(34827, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(34914, 0x00, 6, 0x00002000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(34935, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 8), +(34950, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(35077, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(35080, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 60), +(35083, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(35086, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(35100, 0x00, 9, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), +(35121, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(36096, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(36541, 0x04, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37165, 0x00, 8, 0x00200400, 0x00200400, 0x00200400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37168, 0x00, 8, 0x003E0000, 0x003E0000, 0x003E0000, 0x00000009, 0x00000009, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37170, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), +(37173, 0x00, 8, 0x2CBC0598, 0x2CBC0598, 0x2CBC0598, 0x00000106, 0x00000106, 0x00000106, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(37189, 0x00, 10, 0xC0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 60), +(37193, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(37195, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37197, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), +(37213, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(37214, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37227, 0x00, 11, 0x000001C0, 0x000001C0, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 60), +(37237, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(37247, 0x08, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 45), +(37377, 0x20, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37379, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37384, 0x00, 5, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37443, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(37514, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(37516, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37519, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000030, 0.000000, 0.000000, 0), +(37523, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(37528, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37536, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37568, 0x00, 6, 0x00000800, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37594, 0x00, 6, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37600, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37601, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(37603, 0x00, 6, 0x00008000, 0x00008000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(37655, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(37657, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 3), +(38026, 0x01, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +(38031, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(38290, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.600000, 0.000000, 0), +(38299, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 12), +(38326, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(38327, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(38334, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(38347, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(38350, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(38394, 0x00, 5, 0x00000006, 0x00000006, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(38857, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(39027, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(39372, 0x30, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(39437, 0x04, 5, 0x00001364, 0x00001364, 0x00001364, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(39442, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0.000000, 0.000000, 0), +(39443, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(39530, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(39958, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.700000, 0.000000, 40), +(40407, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0), +(40438, 0x00, 6, 0x00008040, 0x00008040, 0x00008040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40442, 0x00, 7, 0x00000014, 0x00000014, 0x00000014, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40444, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(40458, 0x00, 4, 0x02000000, 0x02000000, 0x02000000, 0x00000601, 0x00000601, 0x00000601, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40463, 0x00, 11, 0x00000081, 0x00000081, 0x00000081, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40470, 0x00, 10, 0xC0800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40475, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3.000000, 0.000000, 0), +(40478, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40482, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(40485, 0x00, 9, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(40899, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(41034, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), +(41260, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(41262, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(41381, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0.000000, 0.000000, 0), +(41393, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(41434, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2.000000, 0.000000, 45), +(41469, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 7.000000, 0.000000, 0), +(41635, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(41989, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.500000, 0.000000, 0), +(42083, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(42135, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), +(42136, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), +(42368, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(42370, 0x00, 11, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(42770, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(43338, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(43443, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(43726, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43728, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43737, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(43739, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43741, 0x00, 10, 0x80000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43745, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43748, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43750, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(43819, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(44404, 0x00, 3, 0x20000021, 0x20000021, 0x20000021, 0x00009000, 0x00009000, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(44442, 0x00, 3, 0x00800000, 0x00800000, 0x00800000, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1), +(44445, 0x00, 3, 0x00000013, 0x00000013, 0x00000013, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(44449, 0x00, 3, 0x20E21277, 0x20E21277, 0x20E21277, 0x00019048, 0x00019048, 0x00019048, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(44546, 0x00, 3, 0x020002A0, 0x020002A0, 0x020002A0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(44835, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0.000000, 0.000000, 0), +(45054, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), +(45057, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(45234, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(45354, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45355, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45481, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45482, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45483, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(45484, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), +(46025, 0x20, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46092, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46098, 0x00, 11, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46569, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(46662, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 20), +(46832, 0x00, 7, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(46854, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46867, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46913, 0x00, 4, 0x00000040, 0x00000040, 0x00000040, 0x00000404, 0x00000404, 0x00000404, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(46916, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(46951, 0x00, 4, 0x00000400, 0x00000400, 0x00000400, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47195, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(47201, 0x00, 5, 0x00000008, 0x00000008, 0x00000008, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47245, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47258, 0x00, 5, 0x00000000, 0x00000000, 0x00000000, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47263, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), +(47264, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), +(47265, 0x20, 5, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 20), +(47509, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(47516, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47569, 0x00, 6, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(47580, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(48110, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(48111, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), +(48483, 0x00, 7, 0x00008800, 0x00008800, 0x00008800, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48496, 0x00, 7, 0x00000060, 0x00000060, 0x00000060, 0x02000002, 0x02000002, 0x02000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(48506, 0x00, 7, 0x00000005, 0x00000005, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48516, 0x00, 7, 0x00000005, 0x00000005, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 30), +(48539, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x04000000, 0x04000000, 0x04000000, 0x00000000, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), +(48833, 0x00, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000440, 0x00000440, 0x00000440, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48835, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48837, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(48988, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(49018, 0x00, 15, 0x01400000, 0x01400000, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(49188, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(49208, 0x00, 15, 0x00440000, 0x00440000, 0x00440000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(49222, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(49622, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(50781, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6), +(50880, 0x10, 15, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51123, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51346, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51349, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51352, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51359, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 10), +(51414, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(51474, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(51483, 0x01, 11, 0x20000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(51521, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 1), +(51528, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0), +(51556, 0x00, 11, 0x000000C0, 0x000000C0, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51562, 0x00, 11, 0x00000100, 0x00000100, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51625, 0x00, 8, 0x1000A000, 0x1000A000, 0x1000A000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51627, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000070, 0.000000, 0.000000, 0), +(51634, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51664, 0x00, 8, 0x00020000, 0x00020000, 0x00020000, 0x00000008, 0x00000008, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(51672, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 1), +(51692, 0x00, 8, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(51698, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1), +(51940, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(51989, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52004, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52005, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52007, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52008, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0), +(52020, 0x00, 7, 0x00008000, 0x00008000, 0x00008000, 0x00100000, 0x00100000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(52127, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(52420, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30), +(52423, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(53527, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(52795, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(52898, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53215, 0x00, 9, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53221, 0x00, 9, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53228, 0x00, 9, 0x00000020, 0x00000020, 0x00000020, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53234, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53256, 0x00, 9, 0x00000800, 0x00000800, 0x00000800, 0x00800001, 0x00800001, 0x00800001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53290, 0x00, 9, 0x00000800, 0x00000800, 0x00000800, 0x00000001, 0x00000001, 0x00000001, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53380, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00028000, 0x00028000, 0x00028000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53397, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53486, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53501, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53551, 0x00, 10, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53569, 0x00, 10, 0x00200000, 0x00200000, 0x00200000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53601, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 6), +(53646, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(53671, 0x00, 10, 0x00800000, 0x00800000, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(53709, 0x00, 10, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000000, 0.000000, 0.000000, 0), +(53817, 0x00, 11, 0x00000000, 0x000001C3, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54149, 0x00, 10, 0x00200000, 0x00200000, 0x00200000, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(54278, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(54646, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(54695, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(54707, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(54738, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(54747, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(54754, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54808, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), +(54838, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(54841, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 3), +(54937, 0x00, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54939, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55166, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(55380, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55440, 0x00, 11, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55640, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55666, 0x00, 15, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55677, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55680, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55689, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(55747, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55768, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(55776, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(56218, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(56342, 0x00, 9, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(56355, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(56364, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(56372, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x00000080, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(56375, 0x00, 3, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(56451, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3), +(56636, 0x00, 4, 0x00000020, 0x00000020, 0x00000020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), +(56816, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000030, 0.000000, 0.000000, 0), +(56821, 0x00, 8, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(57345, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(57352, 0x00, 0, 0x00000001, 0x00000001, 0x00000001, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), +(57470, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(57499, 0x00, 4, 0x40000001, 0x40000001, 0x40000001, 0x00010000, 0x00010000, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00014000, 0x00000000, 0.000000, 0.000000, 0), +(57870, 0x00, 9, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00040000, 0x00000000, 0.000000, 0.000000, 0), +(57878, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), +(57989, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0.000000, 0.000000, 0), +(58357, 0x00, 4, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(58364, 0x00, 4, 0x00000400, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58372, 0x00, 4, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58386, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(58442, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), +(58444, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 5), +(58597, 0x00, 10, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,6), +(58616, 0x00, 15, 0x01000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58620, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58626, 0x00, 15, 0x00000000, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58644, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58647, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(58677, 0x00, 15, 0x00002000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(58872, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0), +(58901, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(59176, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(59327, 0x00, 15, 0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(59345, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(59630, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(59725, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), +(60061, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60063, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60066, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60132, 0x00, 15, 0x00000000, 0x00000000, 0x00000000, 0x08020000, 0x08020000, 0x08020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60170, 0x00, 5, 0x00000006, 0x00000006, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60172, 0x00, 5, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(60221, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60301, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60306, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60317, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60436, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60442, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60473, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60482, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60487, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 15), +(60490, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60493, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60503, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60519, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60529, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(60537, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 45), +(60564, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60571, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60572, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60573, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60574, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60575, 0x00, 11, 0x90100000, 0x90100000, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60617, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(60710, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60717, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60719, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60722, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60724, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60726, 0x00, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60770, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60818, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(60826, 0x00, 15, 0x01400000, 0x01400000, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61062, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00010000, 0.000000, 0.000000, 0), +(61188, 0x00, 5, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61257, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0), +(61324, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00020000, 0x00020000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61356, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000002A8, 0x00000002, 0.000000, 0.000000, 45), +(61618, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(61846, 0x00, 9, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(62600, 0x7F, 7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(63108, 0x00, 5, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63156, 0x00, 0, 0x00000001, 0x00000001, 0x00000001, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63280, 0x00, 11, 0x20000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(63320, 0x00, 5, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00008000, 0x00004000, 0x00000001, 0.000000, 0.000000, 0), +(63373, 0x00, 11, 0x80000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(63534, 0x00, 6, 0x00000040, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(63611, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00050014, 0x00000000, 0.000000, 0.000000, 0), +(63625, 0x00, 6, 0x02000000, 0x02000000, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(63730, 0x00, 6, 0x00000800, 0x00000800, 0x00000800, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(64928, 0x00, 11, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(64976, 0x00, 4, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), +(65661, 0x00, 15, 0x00400011 ,0x00400011, 0x00400011, 0x20020004, 0x20020004, 0x20020004, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0.000000, 100.000000,0), +(64127, 0x00, 6, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(67228, 0x04, 11, 0x00000000, 0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(67353, 0x00, 7, 0x00008000, 0x00008000, 0x00008000, 0x00100500, 0x00100500, 0x00100500, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(67361, 0x40, 7, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 6), +(67667, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(67672, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 50), +(67702, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(67771, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), +(70664, 0x00, 7, 0x00000010, 0x00000010, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(70748, 0x00, 3, 0x00000000, 0x00000000, 0x00000000, 0x00200000, 0x00200000, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 214c38534..30772826e 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -99,6 +99,9 @@ pkgdata_DATA = \ 10125_01_mangos_mangos_string.sql \ 10131_01_mangos_spell_bonus_data.sql \ 10148_01_mangos_mangos_string.sql \ + 10156_01_characters_character_aura.sql \ + 10156_02_characters_pet_aura.sql \ + 10156_03_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -178,4 +181,7 @@ EXTRA_DIST = \ 10125_01_mangos_mangos_string.sql \ 10131_01_mangos_spell_bonus_data.sql \ 10148_01_mangos_mangos_string.sql \ + 10156_01_characters_character_aura.sql \ + 10156_02_characters_pet_aura.sql \ + 10156_03_mangos_spell_proc_event.sql \ README diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 9fc50e7d5..1f4c8522b 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -75,7 +75,7 @@ bool LoginQueryHolder::Initialize() "health, power1, power2, power3, power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT groupId FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid)); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index a7975b282..ee759fda5 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1814,9 +1814,27 @@ bool Creature::LoadCreaturesAddon(bool reload) continue; } - Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, this, this, 0); - AddAura(AdditionalAura); - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: %u with Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[EFFECT_INDEX_0],GetGUIDLow(),GetEntry()); + SpellAuraHolder *holder = GetSpellAuraHolder(cAura->spell_id, GetGUID()); + + bool addedToExisting = true; + if (!holder) + { + holder = CreateSpellAuraHolder(AdditionalSpellInfo, this, this); + addedToExisting = false; + } + Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, cAura->effect_idx, NULL, holder, this, this, 0); + holder->AddAura(AdditionalAura, cAura->effect_idx); + + if (addedToExisting) + { + holder->SetInUse(true); + AdditionalAura->ApplyModifier(true,true); + holder->SetInUse(false); + } + else + AddSpellAuraHolder(holder); + + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: %u - Aura %u added to creature (GUIDLow: %u Entry: %u )", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[EFFECT_INDEX_0],GetGUIDLow(),GetEntry()); } } return true; diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index c79611c31..65cfeddbf 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -291,10 +291,8 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction break; case EVENT_T_BUFFED: { - //Note: checked only aura for effect 0, if need check aura for effect 1/2 then - // possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx) - Aura* aura = m_creature->GetAura(event.buffed.spellId, EFFECT_INDEX_0); - if (!aura || aura->GetStackAmount() < event.buffed.amount) + SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(event.buffed.spellId); + if (!holder || holder->GetStackAmount() < event.buffed.amount) return false; //Repeat Timers @@ -307,10 +305,8 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction if (!pActionInvoker) return false; - //Note: checked only aura for effect 0, if need check aura for effect 1/2 then - // possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx) - Aura* aura = pActionInvoker->GetAura(event.buffed.spellId, EFFECT_INDEX_0); - if(!aura || aura->GetStackAmount() < event.buffed.amount) + SpellAuraHolder* holder = pActionInvoker->GetSpellAuraHolder(event.buffed.spellId); + if(!holder || holder->GetStackAmount() < event.buffed.amount) return false; //Repeat Timers diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index c9c39df8b..1c0c250db 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -149,7 +149,7 @@ void DynamicObject::Delay(int32 delaytime) m_aliveDuration -= delaytime; for(AffectedSet::iterator iunit= m_affected.begin(); iunit != m_affected.end(); ++iunit) if (*iunit) - (*iunit)->DelayAura(m_spellId, m_effIndex, delaytime); + (*iunit)->DelaySpellAuraHolder(m_spellId, delaytime); } bool DynamicObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index b1cda7ecf..010c50a4e 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -172,8 +172,28 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) return; // Apply PersistentAreaAura on target - PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster()); - target->AddAura(Aur); + + SpellAuraHolder *holder = target->GetSpellAuraHolder(spellInfo->Id, i_dynobject.GetCaster()->GetGUID()); + + bool addedToExisting = true; + if (!holder) + { + holder = CreateSpellAuraHolder(spellInfo, target, i_dynobject.GetCaster()); + addedToExisting = false; + + } + PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, holder, target, i_dynobject.GetCaster()); + holder->AddAura(Aur, eff_index); + + if (addedToExisting) + { + holder->SetInUse(true); + Aur->ApplyModifier(true,true); + holder->SetInUse(false); + } + else + target->AddSpellAuraHolder(holder); + i_dynobject.AddAffected(target); } diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 54deb42d6..d3bcbb824 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -3563,6 +3563,10 @@ bool ChatHandler::HandleAuraCommand(const char* args) SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID ); if(spellInfo) { + SpellAuraHolder *holder = NULL; + if (IsSpellAppliesAura(spellInfo, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spellInfo, SPELL_EFFECT_PERSISTENT_AREA_AURA)) + holder = CreateSpellAuraHolder(spellInfo, target, m_session->GetPlayer()); + for(uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) { uint8 eff = spellInfo->Effect[i]; @@ -3572,10 +3576,11 @@ bool ChatHandler::HandleAuraCommand(const char* args) eff == SPELL_EFFECT_APPLY_AURA || eff == SPELL_EFFECT_PERSISTENT_AREA_AURA ) { - Aura *Aur = CreateAura(spellInfo, SpellEffectIndex(i), NULL, target); - target->AddAura(Aur); + Aura *aur = CreateAura(spellInfo, SpellEffectIndex(i), NULL, holder, target); + holder->AddAura(aur, SpellEffectIndex(i)); } } + target->AddSpellAuraHolder(holder); } return true; @@ -4252,32 +4257,40 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/) char const* talentStr = GetMangosString(LANG_TALENT); char const* passiveStr = GetMangosString(LANG_PASSIVE); - Unit::AuraMap const& uAuras = unit->GetAuras(); + Unit::SpellAuraHolderMap const& uAuras = unit->GetSpellAuraHolderMap(); PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size()); - for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) + for (Unit::SpellAuraHolderMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr) { bool talent = GetTalentSpellCost(itr->second->GetId()) > 0; + + SpellAuraHolder *holder = itr->second; + char const* name = holder->GetSpellProto()->SpellName[GetSessionDbcLocale()]; - char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()]; - - if (m_session) + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - std::ostringstream ss_name; - ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r"; + Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)); + if (!aur) + continue; + + if (m_session) + { + std::ostringstream ss_name; + ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r"; - PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(), - itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), - ss_name.str().c_str(), - (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), - IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); - } - else - { - PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffIndex(), - itr->second->GetModifier()->m_auraname, itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(), - name, - (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), - IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID())); + PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, holder->GetId(), aur->GetEffIndex(), + aur->GetModifier()->m_auraname, aur->GetAuraDuration(), aur->GetAuraMaxDuration(), + ss_name.str().c_str(), + (holder->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + IS_PLAYER_GUID(holder->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(holder->GetCasterGUID())); + } + else + { + PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, holder->GetId(), aur->GetEffIndex(), + aur->GetModifier()->m_auraname, aur->GetAuraDuration(), aur->GetAuraMaxDuration(), + name, + (holder->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + IS_PLAYER_GUID(holder->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(holder->GetCasterGUID())); + } } } for (int i = 0; i < TOTAL_AURAS; ++i) @@ -4297,13 +4310,13 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/) ss_name << "|cffffffff|Hspell:" << (*itr)->GetId() << "|h[" << name << "]|h|r"; PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), - ss_name.str().c_str(),((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + ss_name.str().c_str(),((*itr)->GetHolder()->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID())); } else { PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), - name,((*itr)->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), + name,((*itr)->GetHolder()->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""), IS_PLAYER_GUID((*itr)->GetCasterGUID()) ? "player" : "creature",GUID_LOPART((*itr)->GetCasterGUID())); } } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index a1db4709d..2aa9bb1c7 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7490,8 +7490,8 @@ bool PlayerCondition::Meets(Player const * player) const } case CONDITION_AD_COMMISSION_AURA: { - Unit::AuraMap const& auras = player->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = player->GetSpellAuraHolderMap(); + for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) if ((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580) return true; return false; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 29dcde733..45339c55e 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1143,8 +1143,8 @@ void Pet::_SaveSpells() void Pet::_LoadAuras(uint32 timediff) { RemoveAllAuras(); - - QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + + QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); if(result) { @@ -1153,34 +1153,29 @@ void Pet::_LoadAuras(uint32 timediff) Field *fields = result->Fetch(); uint64 caster_guid = fields[0].GetUInt64(); uint32 spellid = fields[1].GetUInt32(); - SpellEffectIndex effindex = SpellEffectIndex(fields[2].GetUInt32()); - uint32 stackcount= fields[3].GetUInt32(); - int32 damage = (int32)fields[4].GetUInt32(); - int32 maxduration = (int32)fields[5].GetUInt32(); - int32 remaintime = (int32)fields[6].GetUInt32(); - int32 remaincharges = (int32)fields[7].GetUInt32(); + uint32 stackcount= fields[2].GetUInt32(); + int32 remaincharges = (int32)fields[3].GetUInt32(); + int32 damage[MAX_EFFECT_INDEX]; + int32 maxduration[MAX_EFFECT_INDEX]; + int32 remaintime[MAX_EFFECT_INDEX]; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + damage[i] = (int32)fields[i+4].GetUInt32(); + maxduration[i] = (int32)fields[i+7].GetUInt32(); + remaintime[i] = (int32)fields[i+10].GetUInt32(); + } + uint32 effIndexMask = (int32)fields[13].GetUInt32(); SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); if(!spellproto) { - sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex); + sLog.outError("Unknown spell (spellid %u), ignore.",spellid); continue; } - if(effindex >= MAX_EFFECT_INDEX) - { - sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex); + // do not load single target auras (unless they were cast by the player) + if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto)) continue; - } - - // negative effects should continue counting down after logout - if (remaintime != -1 && !IsPositiveEffect(spellid, effindex)) - { - if (remaintime/IN_MILLISECONDS <= int32(timediff)) - continue; - - remaintime -= timediff*IN_MILLISECONDS; - } // prevent wrong values of remaincharges if(spellproto->procCharges) @@ -1191,19 +1186,38 @@ void Pet::_LoadAuras(uint32 timediff) else remaincharges = 0; - /// do not load single target auras (unless they were cast by the player) - if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto)) - continue; + if (spellproto->StackAmount < stackcount) + stackcount = spellproto->StackAmount; - for(uint32 i=0; i < stackcount; ++i) + SpellAuraHolder *holder = CreateSpellAuraHolder(spellproto, this, NULL); + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); + if ((effIndexMask & (1 << i)) == 0) + continue; - if(!damage) - damage = aura->GetModifier()->m_amount; - aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); - AddAura(aura); + if (remaintime[i] != -1 && !IsPositiveEffect(spellid, SpellEffectIndex(i))) + { + if (remaintime[i]/IN_MILLISECONDS <= int32(timediff)) + continue; + + remaintime[i] -= timediff*IN_MILLISECONDS; + } + + Aura* aura = CreateAura(spellproto, SpellEffectIndex(i), NULL, holder, this); + if (!damage[i]) + damage[i] = aura->GetModifier()->m_amount; + + aura->SetLoadedState(damage[i], maxduration[i], remaintime[i]); + holder->AddAura(aura, SpellEffectIndex(i)); } + + if (!holder->IsEmptyHolder()) + { + holder->SetLoadedState(caster_guid, stackcount, remaincharges); + AddSpellAuraHolder(holder); + } + else + delete holder; } while( result->NextRow() ); @@ -1215,52 +1229,60 @@ void Pet::_SaveAuras() { CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber()); - AuraMap const& auras = GetAuras(); - if (auras.empty()) + SpellAuraHolderMap const& auraHolders = GetSpellAuraHolderMap(); + + if (auraHolders.empty()) return; - spellEffectPair lastEffectPair = auras.begin()->first; - uint32 stackCounter = 1; - - for(AuraMap::const_iterator itr = auras.begin(); ; ++itr) + for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr) { - if(itr == auras.end() || lastEffectPair != itr->first) - { - AuraMap::const_iterator itr2 = itr; - // save previous spellEffectPair to db - itr2--; - SpellEntry const *spellInfo = itr2->second->GetSpellProto(); - /// do not save single target auras (unless they were cast by the player) - if (!(itr2->second->GetCasterGUID() != GetGUID() && IsSingleTargetSpell(spellInfo))) - { - if(!itr2->second->IsPassive()) - { - // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. - uint8 i; - for (i = 0; i < MAX_EFFECT_INDEX; ++i) - if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || - spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) - break; + SpellAuraHolder *holder = itr->second; - if (i == 3) - { - CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges) " - "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d')", - m_charmInfo->GetPetNumber(), itr2->second->GetCasterGUID(),(uint32)itr2->second->GetId(), (uint32)itr2->second->GetEffIndex(), stackCounter, itr2->second->GetModifier()->m_amount,int(itr2->second->GetAuraMaxDuration()),int(itr2->second->GetAuraDuration()),int(itr2->second->GetAuraCharges())); - } - } - } - if(itr == auras.end()) + bool save = true; + for (int32 j = 0; j < MAX_EFFECT_INDEX; ++j) + { + SpellEntry const* spellInfo = holder->GetSpellProto(); + if (spellInfo->EffectApplyAuraName[j] == SPELL_AURA_MOD_STEALTH || + spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER || + spellInfo->Effect[j] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) + { + save = false; break; + } } - if (lastEffectPair == itr->first) - stackCounter++; - else + //skip all holders from spells that are passive + //do not save single target holders (unless they were cast by the player) + if (save && !holder->IsPassive() && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget())) { - lastEffectPair = itr->first; - stackCounter = 1; + int32 damage[MAX_EFFECT_INDEX]; + int32 remaintime[MAX_EFFECT_INDEX]; + int32 maxduration[MAX_EFFECT_INDEX]; + uint32 effIndexMask = 0; + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + damage[i] = 0; + remaintime[i] = 0; + maxduration[i] = 0; + + if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) + { + // don't save not own area auras + if (aur->IsAreaAura() && holder->GetCasterGUID() != GetGUID()) + continue; + + damage[i] = aur->GetModifier()->m_amount; + remaintime[i] = aur->GetAuraDuration(); + maxduration[i] = aur->GetAuraMaxDuration(); + effIndexMask |= (1 << i); + } + } + + if (!effIndexMask) + continue; + + CharacterDatabase.PExecute("INSERT INTO pet_aura (guid, caster_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", m_charmInfo->GetPetNumber(), holder->GetCasterGUID(), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], effIndexMask); } } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 822f70653..d9237a1f7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4505,13 +4505,13 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) { int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE; - for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + if (SpellAuraHolder* holder = GetSpellAuraHolder(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS)) { - if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,SpellEffectIndex(i))) - { - Aur->SetAuraDuration(delta*IN_MILLISECONDS); - Aur->SendAuraUpdate(false); - } + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + if(Aura* Aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) + Aur->SetAuraDuration(delta*IN_MILLISECONDS); + + holder->SendAuraUpdate(false); } } } @@ -6811,8 +6811,8 @@ void Player::DuelComplete(DuelCompleteType type) /* remove auras */ std::vector auras2remove; - AuraMap const& vAuras = duel->opponent->GetAuras(); - for (AuraMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i) + SpellAuraHolderMap const& vAuras = duel->opponent->GetSpellAuraHolderMap(); + for (SpellAuraHolderMap::const_iterator i = vAuras.begin(); i != vAuras.end(); ++i) { if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) auras2remove.push_back(i->second->GetId()); @@ -6822,8 +6822,8 @@ void Player::DuelComplete(DuelCompleteType type) duel->opponent->RemoveAurasDueToSpell(auras2remove[i]); auras2remove.clear(); - AuraMap const& auras = GetAuras(); - for (AuraMap::const_iterator i = auras.begin(); i != auras.end(); ++i) + SpellAuraHolderMap const& auras = GetSpellAuraHolderMap(); + for (SpellAuraHolderMap::const_iterator i = auras.begin(); i != auras.end(); ++i) { if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime) auras2remove.push_back(i->second->GetId()); @@ -7302,8 +7302,8 @@ void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply bool found = false; for (int k=0; k < MAX_EFFECT_INDEX; ++k) { - spellEffectPair spair = spellEffectPair(spellInfo->Id, SpellEffectIndex(k)); - for (AuraMap::const_iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter) + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellInfo->Id); + for (SpellAuraHolderMap::const_iterator iter = spair.first; iter != spair.second; ++iter) { if(!item || iter->second->GetCastItemGUID() == item->GetGUID()) { @@ -15604,7 +15604,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) { //RemoveAllAuras(); -- some spells casted before aura load, for example in LoadSkills, aura list explcitly cleaned early - //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); + //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'",GetGUIDLow()); if(result) { @@ -15613,67 +15613,79 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) Field *fields = result->Fetch(); uint64 caster_guid = fields[0].GetUInt64(); uint32 spellid = fields[1].GetUInt32(); - SpellEffectIndex effindex = SpellEffectIndex(fields[2].GetUInt32()); - uint32 stackcount = fields[3].GetUInt32(); - int32 damage = fields[4].GetInt32(); - int32 maxduration = fields[5].GetInt32(); - int32 remaintime = fields[6].GetInt32(); - int32 remaincharges = fields[7].GetInt32(); + uint32 stackcount = fields[2].GetUInt32(); + int32 remaincharges = (int32)fields[3].GetUInt32(); + int32 damage[MAX_EFFECT_INDEX]; + int32 maxduration[MAX_EFFECT_INDEX]; + int32 remaintime[MAX_EFFECT_INDEX]; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + damage[i] = (int32)fields[i+4].GetUInt32(); + maxduration[i] = (int32)fields[i+7].GetUInt32(); + remaintime[i] = (int32)fields[i+10].GetUInt32(); + } + uint32 effIndexMask = (int32)fields[13].GetUInt32(); SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); - if (!spellproto) + if(!spellproto) { - sLog.outError("Unknown aura (spellid %u, effindex %u), ignore.",spellid,effindex); + sLog.outError("Unknown spell (spellid %u), ignore.",spellid); continue; } - if (effindex >= MAX_EFFECT_INDEX) - { - sLog.outError("Invalid effect index (spellid %u, effindex %u), ignore.",spellid,effindex); - continue; - } - - // negative effects should continue counting down after logout - if (remaintime != -1 && !IsPositiveEffect(spellid, effindex)) - { - if (remaintime/IN_MILLISECONDS <= int32(timediff)) - continue; - - remaintime -= timediff*IN_MILLISECONDS; - } - // prevent wrong values of remaincharges - if (spellproto->procCharges) + if(spellproto->procCharges) { - if (remaincharges <= 0 || remaincharges > (int32)spellproto->procCharges) + if(remaincharges <= 0 || remaincharges > (int32)spellproto->procCharges) remaincharges = spellproto->procCharges; } else remaincharges = 0; + if (spellproto->StackAmount < stackcount) + stackcount = spellproto->StackAmount; - for(uint32 i = 0; i < stackcount; ++i) + SpellAuraHolder *holder = CreateSpellAuraHolder(spellproto, this, NULL); + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - Aura* aura = CreateAura(spellproto, effindex, NULL, this, NULL); - if (!damage) - damage = aura->GetModifier()->m_amount; + if ((effIndexMask & (1 << i)) == 0) + continue; - // reset stolen single target auras - if (caster_guid != GetGUID() && aura->IsSingleTarget()) - aura->SetIsSingleTarget(false); + if (remaintime[i] != -1 && !IsPositiveEffect(spellid, SpellEffectIndex(i))) + { + if (remaintime[i]/IN_MILLISECONDS <= int32(timediff)) + continue; - aura->SetLoadedState(caster_guid,damage,maxduration,remaintime,remaincharges); - AddAura(aura); - DETAIL_LOG("Added aura spellid %u, effect %u", spellproto->Id, effindex); + remaintime[i] -= timediff*IN_MILLISECONDS; + } + + Aura* aura = CreateAura(spellproto, SpellEffectIndex(i), NULL, holder, this); + if (!damage[i]) + damage[i] = aura->GetModifier()->m_amount; + + aura->SetLoadedState(damage[i], maxduration[i], remaintime[i]); + holder->AddAura(aura, SpellEffectIndex(i)); } + + if (!holder->IsEmptyHolder()) + { + // reset stolen single target auras + if (caster_guid != GetGUID() && holder->IsSingleTarget()) + holder->SetIsSingleTarget(false); + + holder->SetLoadedState(caster_guid, stackcount, remaincharges); + AddSpellAuraHolder(holder); + DETAIL_LOG("Added auras from spellid %u, effect %u", spellproto->Id); + } + else + delete holder; } while( result->NextRow() ); - delete result; } if(getClass() == CLASS_WARRIOR && !HasAuraType(SPELL_AURA_MOD_SHAPESHIFT)) - CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); + CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); } void Player::_LoadGlyphs(QueryResult *result) @@ -16867,61 +16879,50 @@ void Player::_SaveAuras() { CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow()); - AuraMap const& auras = GetAuras(); + SpellAuraHolderMap const& auraHolders = GetSpellAuraHolderMap(); - if (auras.empty()) + if (auraHolders.empty()) return; - spellEffectPair lastEffectPair = auras.begin()->first; - uint32 stackCounter = 1; - /* copied following sql-code partly from achievementmgr */ - bool first_round = true; - std::ostringstream ss; - for(AuraMap::const_iterator itr = auras.begin(); ; ++itr) + + for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr) { - if(itr == auras.end() || lastEffectPair != itr->first) + SpellAuraHolder *holder = itr->second; + //skip all holders from spells that are passive + //do not save single target holders (unless they were cast by the player) + if (!holder->IsPassive() && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget())) { - AuraMap::const_iterator itr2 = itr; - // save previous spellEffectPair to db - itr2--; + int32 damage[MAX_EFFECT_INDEX]; + int32 remaintime[MAX_EFFECT_INDEX]; + int32 maxduration[MAX_EFFECT_INDEX]; + uint32 effIndexMask = 0; - //skip all auras from spells that are passive - //do not save single target auras (unless they were cast by the player) - if (!itr2->second->IsPassive() && (itr2->second->GetCasterGUID() == GetGUID() || !itr2->second->IsSingleTarget())) + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (first_round) + damage[i] = 0; + remaintime[i] = 0; + maxduration[i] = 0; + + if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) { - ss << "INSERT INTO character_aura (guid,caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges)VALUES "; - first_round = false; + // don't save not own area auras + if (aur->IsAreaAura() && holder->GetCasterGUID() != GetGUID()) + continue; + + damage[i] = aur->GetModifier()->m_amount; + remaintime[i] = aur->GetAuraDuration(); + maxduration[i] = aur->GetAuraMaxDuration(); + effIndexMask |= (1 << i); } - // next new/changed record prefix - else - ss << ", "; - - ss << "("<< GetGUIDLow() << "," << itr2->second->GetCasterGUID() << "," - << (uint32)itr2->second->GetId() << "," << (uint32)itr2->second->GetEffIndex() << "," - << stackCounter << "," << itr2->second->GetModifier()->m_amount << "," - <second->GetAuraMaxDuration()) << "," << int(itr2->second->GetAuraDuration()) << "," - << int(itr2->second->GetAuraCharges()) << ")"; } + + if (!effIndexMask) + continue; - if(itr == auras.end()) - break; - } - - if (lastEffectPair == itr->first) - stackCounter++; - else - { - lastEffectPair = itr->first; - stackCounter = 1; + CharacterDatabase.PExecute("INSERT INTO character_aura (guid, caster_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", GetGUIDLow(), holder->GetCasterGUID(), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], effIndexMask); } } - - // if something changed execute - if (!first_round) - CharacterDatabase.Execute( ss.str().c_str() ); } void Player::_SaveGlyphs() @@ -19750,38 +19751,51 @@ void Player::SendAurasForTarget(Unit *target) Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras(); for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) { - for(int j = 0; j < MAX_EFFECT_INDEX; ++j) + SpellAuraHolderBounds bounds = target->GetSpellAuraHolderBounds(itr->second); + for (SpellAuraHolderMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter) { - if(Aura *aura = target->GetAura(itr->second, SpellEffectIndex(j))) + SpellAuraHolder *holder = iter->second; + data << uint8(holder->GetAuraSlot()); + data << uint32(holder->GetId()); + + if(holder->GetId()) { - data << uint8(aura->GetAuraSlot()); - data << uint32(aura->GetId()); + uint8 auraFlags = holder->GetAuraFlags(); + // flags + data << uint8(auraFlags); + // level + data << uint8(holder->GetAuraLevel()); + // charges + if (holder->GetAuraCharges()) + data << uint8(holder->GetAuraCharges() * holder->GetStackAmount()); + else + data << uint8(holder->GetStackAmount()); - if(aura->GetId()) + if(!(auraFlags & AFLAG_NOT_CASTER)) // packed GUID of caster { - uint8 auraFlags = aura->GetAuraFlags(); - // flags - data << uint8(auraFlags); - // level - data << uint8(aura->GetAuraLevel()); - // charges - if (aura->GetAuraCharges()) - data << uint8(aura->GetAuraCharges() * aura->GetStackAmount()); - else - data << uint8(aura->GetStackAmount()); - - if(!(auraFlags & AFLAG_NOT_CASTER)) // packed GUID of caster - { - data.appendPackGUID(aura->GetCasterGUID()); - } - - if(auraFlags & AFLAG_DURATION) // include aura duration - { - data << uint32(aura->GetAuraMaxDuration()); - data << uint32(aura->GetAuraDuration()); - } + data.appendPackGUID(holder->GetCasterGUID()); + } + + if(auraFlags & AFLAG_DURATION) // include aura duration + { + // take highest - to display icon even if stun fades + uint32 max_duration = 0; + uint32 duration = 0; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) + { + if (uint32(aura->GetAuraMaxDuration()) > max_duration) + { + max_duration = aura->GetAuraMaxDuration(); + duration = aura->GetAuraDuration(); + } + } + } + + data << uint32(max_duration); + data << uint32(duration); } - break; } } } @@ -20121,14 +20135,14 @@ bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) { - AuraMap& auras = GetAuras(); - for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ) + SpellAuraHolderMap& auras = GetSpellAuraHolderMap(); + for(SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ) { - Aura* aura = itr->second; + SpellAuraHolder* holder = itr->second; // skip passive (passive item dependent spells work in another way) and not self applied auras - SpellEntry const* spellInfo = aura->GetSpellProto(); - if(aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) + SpellEntry const* spellInfo = holder->GetSpellProto(); + if(holder->IsPassive() || holder->GetCasterGUID()!=GetGUID()) { ++itr; continue; @@ -20142,7 +20156,7 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) } // no alt item, remove aura, restart check - RemoveAurasDueToSpell(aura->GetId()); + RemoveAurasDueToSpell(holder->GetId()); itr = auras.begin(); } @@ -20369,11 +20383,14 @@ void Player::UpdateZoneDependentAuras( uint32 newZone ) void Player::UpdateAreaDependentAuras( uint32 newArea ) { // remove auras from spells with area limitations - for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) + for(SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();) { // use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date if(sSpellMgr.GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,this) != SPELL_CAST_OK) - RemoveAura(iter); + { + RemoveSpellAuraHolder(iter->second); + iter = m_spellAuraHolders.begin(); + } else ++iter; } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a9a7e9079..c642715fe 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1060,12 +1060,11 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags & UI64LIT(0x0800000000000000)) { uint32 count = 0; - Unit::AuraMap const& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && - itr->second->GetCasterGUID() == caster->GetGUID() && - IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex())) + itr->second->GetCasterGUID() == caster->GetGUID()) ++count; } @@ -1219,6 +1218,11 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) // Apply additional spell effects to target CastPreCastSpells(unit); + if (IsSpellAppliesAura(m_spellInfo, effectMask)) + spellAuraHolder = CreateSpellAuraHolder(m_spellInfo, unit, realCaster, m_CastItem); + else + spellAuraHolder = NULL; + for(int effectNumber = 0; effectNumber < MAX_EFFECT_INDEX; ++effectNumber) { if (effectMask & (1 << effectNumber)) @@ -1236,6 +1240,16 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) } } } + + // now apply all created auras + if (spellAuraHolder) + { + // normally shouldn't happen + if (!spellAuraHolder->IsEmptyHolder()) + unit->AddSpellAuraHolder(spellAuraHolder); + else + delete spellAuraHolder; + } } void Spell::DoAllEffectOnTarget(GOTargetInfo *target) @@ -5378,43 +5392,48 @@ SpellCastResult Spell::CheckCasterAuras() const if (school_immune || mechanic_immune || dispel_immune) { //Checking auras is needed now, because you are prevented by some state but the spell grants immunity. - Unit::AuraMap const& auras = m_caster->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = m_caster->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - if (itr->second) + if (SpellAuraHolder *holder = itr->second) { - if (GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune) - continue; - if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune) - continue; - if ((1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) - continue; - - // Make a second check for spell failed so the right SPELL_FAILED message is returned. - // That is needed when your casting is prevented by multiple states and you are only immune to some of them. - switch(itr->second->GetModifier()->m_auraname) + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - case SPELL_AURA_MOD_STUN: - if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) - return SPELL_FAILED_STUNNED; - break; - case SPELL_AURA_MOD_CONFUSE: - if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) - return SPELL_FAILED_CONFUSED; - break; - case SPELL_AURA_MOD_FEAR: - if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) - return SPELL_FAILED_FLEEING; - break; - case SPELL_AURA_MOD_SILENCE: - case SPELL_AURA_MOD_PACIFY: - case SPELL_AURA_MOD_PACIFY_SILENCE: - if( m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) - return SPELL_FAILED_PACIFIED; - else if ( m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) - return SPELL_FAILED_SILENCED; - break; - default: break; + if (GetSpellMechanicMask(itr->second->GetSpellProto(), i) & mechanic_immune) + continue; + if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune) + continue; + if ((1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune) + continue; + Aura *aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i)); + if (!aura) + continue; + // Make a second check for spell failed so the right SPELL_FAILED message is returned. + // That is needed when your casting is prevented by multiple states and you are only immune to some of them. + switch(aura->GetModifier()->m_auraname) + { + case SPELL_AURA_MOD_STUN: + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)) + return SPELL_FAILED_STUNNED; + break; + case SPELL_AURA_MOD_CONFUSE: + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED)) + return SPELL_FAILED_CONFUSED; + break; + case SPELL_AURA_MOD_FEAR: + if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED)) + return SPELL_FAILED_FLEEING; + break; + case SPELL_AURA_MOD_SILENCE: + case SPELL_AURA_MOD_PACIFY: + case SPELL_AURA_MOD_PACIFY_SILENCE: + if( m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) + return SPELL_FAILED_PACIFIED; + else if ( m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE) + return SPELL_FAILED_SILENCED; + break; + default: break; + } } } } @@ -6131,10 +6150,7 @@ void Spell::DelayedChannel() if ((*ihit).missCondition == SPELL_MISS_NONE) { if (Unit* unit = m_caster->GetObjectGuid() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID)) - for (int j = 0; j < MAX_EFFECT_INDEX; ++j) - if (ihit->effectMask & (1 << j)) - unit->DelayAura(m_spellInfo->Id, SpellEffectIndex(j), delaytime); - + unit->DelaySpellAuraHolder(m_spellInfo->Id, delaytime); } } diff --git a/src/game/Spell.h b/src/game/Spell.h index 7dec310d0..2b30f151c 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -529,6 +529,7 @@ class Spell Unit* unitTarget; Item* itemTarget; GameObject* gameObjTarget; + SpellAuraHolder* spellAuraHolder; // spell aura holder for current target, created only if spell has aura applying effect int32 damage; // this is set in Spell Hit, but used in Apply Aura handler diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index bdef8e419..a9d87a7e4 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -371,41 +371,35 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= static AuraType const frozenAuraTypes[] = { SPELL_AURA_MOD_ROOT, SPELL_AURA_MOD_STUN, SPELL_AURA_NONE }; -Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : -m_spellmod(NULL), m_caster_guid(0), m_target(target), m_castItemGuid(castItem?castItem->GetGUID():0), -m_timeCla(1000), m_periodicTimer(0), m_periodicTick(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE), -m_effIndex(eff), m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0), m_stackAmount(1), -m_positive(false), m_permanent(false), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false), -m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false) +Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster, Item* castItem) : +m_spellmod(NULL), +m_timeCla(1000), m_periodicTimer(0), m_periodicTick(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), +m_effIndex(eff), m_spellAuraHolder(holder), m_isPersistent(false), +m_positive(false), m_isPeriodic(false), m_isAreaAura(false), m_in_use(0), m_deleted(false) { ASSERT(target); ASSERT(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element"); - m_spellProto = spellproto; + m_currentBasePoints = currentBasePoints ? *currentBasePoints : spellproto->CalculateSimpleValue(eff); - m_currentBasePoints = currentBasePoints ? *currentBasePoints : m_spellProto->CalculateSimpleValue(eff); - - m_isPassive = IsPassiveSpell(GetSpellProto()); - m_positive = IsPositiveEffect(GetId(), m_effIndex); - - m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto); + bool isPassive = IsPassiveSpell(GetSpellProto()); + bool isPermanent = false; + m_positive = IsPositiveEffect(spellproto->Id, m_effIndex); + uint64 caster_guid = !caster ? target->GetGUID() : caster->GetGUID(); m_applyTime = time(NULL); int32 damage; if(!caster) { - m_caster_guid = target->GetGUID(); damage = m_currentBasePoints; - m_maxduration = target->CalculateSpellDuration(m_spellProto, m_effIndex, target); + m_maxduration = target->CalculateSpellDuration(spellproto, m_effIndex, target); } else { - m_caster_guid = caster->GetGUID(); - - damage = caster->CalculateSpellDamage(target, m_spellProto, m_effIndex, &m_currentBasePoints); - m_maxduration = caster->CalculateSpellDuration(m_spellProto, m_effIndex, target); + damage = caster->CalculateSpellDamage(target, spellproto, m_effIndex, &m_currentBasePoints); + m_maxduration = caster->CalculateSpellDuration(spellproto, m_effIndex, target); if (!damage && castItem && castItem->GetItemSuffixFactor()) { @@ -418,7 +412,7 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false) if(pEnchant) { for (int t = 0; t < 3; ++t) - if(pEnchant->spellid[t] == m_spellProto->Id) + if(pEnchant->spellid[t] == spellproto->Id) { damage = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 ); break; @@ -432,14 +426,14 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false) } } - if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0) - m_permanent = true; + if(m_maxduration == -1 || isPassive && spellproto->DurationIndex == 0) + isPermanent = true; Player* modOwner = caster ? caster->GetSpellModOwner() : NULL; - if(!m_permanent && modOwner) + if(!isPermanent && modOwner) { - modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration); + modOwner->ApplySpellMod(spellproto->Id, SPELLMOD_DURATION, m_maxduration); // Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work if (m_maxduration<=0) m_maxduration = 1; @@ -447,52 +441,34 @@ m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false) m_duration = m_maxduration; - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage); + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", spellproto->Id, spellproto->EffectApplyAuraName[eff], m_maxduration, spellproto->EffectImplicitTargetA[eff],damage); - SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]); + SetModifier(AuraType(spellproto->EffectApplyAuraName[eff]), damage, spellproto->EffectAmplitude[eff], spellproto->EffectMiscValue[eff]); // Apply periodic time mod if(modOwner && m_modifier.periodictime) - modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_modifier.periodictime); + modOwner->ApplySpellMod(spellproto->Id, SPELLMOD_ACTIVATION_TIME, m_modifier.periodictime); // Start periodic on next tick or at aura apply - if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY)) + if (!(spellproto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY)) m_periodicTimer += m_modifier.periodictime; - - m_isDeathPersist = IsDeathPersistentSpell(m_spellProto); - - m_procCharges = m_spellProto->procCharges; - if(modOwner) - modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges); - - m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && - m_spellProto->Stances && - !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && - !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT)); - - if (caster && m_spellProto->Id == 22959) // Improved Scorch - { - // Glyph of Improved Scorch - if (Aura* glyph = caster->GetDummyAura(56371)) - m_stackAmount = glyph->GetModifier()->m_amount; - } } Aura::~Aura() { } -AreaAura::AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, -Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +AreaAura::AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem) { m_isAreaAura = true; // caster==NULL in constructor args if target==caster in fact Unit* caster_ptr = caster ? caster : target; - m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex])); + m_radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellproto->EffectRadiusIndex[m_effIndex])); if(Player* modOwner = caster_ptr->GetSpellModOwner()) - modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius); + modOwner->ApplySpellMod(spellproto->Id, SPELLMOD_RADIUS, m_radius); switch(spellproto->Effect[eff]) { @@ -506,7 +482,7 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, if (target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) m_modifier.m_auraname = SPELL_AURA_NONE; // Light's Beacon not applied to caster itself (TODO: more generic check for another simialr spell if any?) - else if (target == caster_ptr && m_spellProto->Id == 53651) + else if (target == caster_ptr && spellproto->Id == 53651) m_modifier.m_auraname = SPELL_AURA_NONE; break; case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: @@ -536,8 +512,8 @@ AreaAura::~AreaAura() { } -PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, -Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +PersistentAreaAura::PersistentAreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem) { m_isPersistent = true; } @@ -546,8 +522,8 @@ PersistentAreaAura::~PersistentAreaAura() { } -SingleEnemyTargetAura::SingleEnemyTargetAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, -Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target, caster, castItem) +SingleEnemyTargetAura::SingleEnemyTargetAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, +Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem) { if (caster) m_casters_target_guid = caster->GetTypeId()==TYPEID_PLAYER ? ((Player*)caster)->GetSelection() : caster->GetTargetGUID(); @@ -561,33 +537,27 @@ SingleEnemyTargetAura::~SingleEnemyTargetAura() Unit* SingleEnemyTargetAura::GetTriggerTarget() const { - return ObjectAccessor::GetUnit(*m_target, m_casters_target_guid); + return ObjectAccessor::GetUnit(*(m_spellAuraHolder->GetTarget()), m_casters_target_guid); } -Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) +Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster, Item* castItem) { if (IsAreaAuraEffect(spellproto->Effect[eff])) - return new AreaAura(spellproto, eff, currentBasePoints, target, caster, castItem); + return new AreaAura(spellproto, eff, currentBasePoints, holder, target, caster, castItem); uint32 triggeredSpellId = spellproto->EffectTriggerSpell[eff]; if(SpellEntry const* triggeredSpellInfo = sSpellStore.LookupEntry(triggeredSpellId)) for (int i = 0; i < MAX_EFFECT_INDEX; ++i) if (triggeredSpellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_ENEMY) - return new SingleEnemyTargetAura(spellproto, eff, currentBasePoints, target, caster, castItem); + return new SingleEnemyTargetAura(spellproto, eff, currentBasePoints, holder, target, caster, castItem); - return new Aura(spellproto, eff, currentBasePoints, target, caster, castItem); + return new Aura(spellproto, eff, currentBasePoints, holder, target, caster, castItem); } -Unit* Aura::GetCaster() const +SpellAuraHolder* CreateSpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem) { - if(m_caster_guid == m_target->GetGUID()) - return m_target; - - //return ObjectAccessor::GetUnit(*m_target,m_caster_guid); - //must return caster even if it's in another grid/map - Unit *unit = ObjectAccessor::GetUnitInWorld(*m_target,m_caster_guid); - return unit && unit->IsInWorld() ? unit : NULL; + return new SpellAuraHolder(spellproto, target, caster, castItem); } void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue) @@ -613,8 +583,8 @@ void Aura::Update(uint32 diff) { if(Unit* caster = GetCaster()) { - Powers powertype = Powers(m_spellProto->powerType); - int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel(); + Powers powertype = Powers(GetSpellProto()->powerType); + int32 manaPerSecond = GetSpellProto()->manaPerSecond + GetSpellProto()->manaPerSecondPerLevel * caster->getLevel(); m_timeCla = 1*IN_MILLISECONDS; if (manaPerSecond) { @@ -627,34 +597,7 @@ void Aura::Update(uint32 diff) } } - // Channeled aura required check distance from caster - if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID()) - { - Unit* caster = GetCaster(); - if(!caster) - { - m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); - return; - } - - // need check distance for channeled target only - if (caster->GetChannelObjectGUID() == m_target->GetGUID()) - { - // Get spell range - float max_range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)); - - if(Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod(GetId(), SPELLMOD_RANGE, max_range, NULL); - - if(!caster->IsWithinDistInMap(m_target, max_range)) - { - m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); - return; - } - } - } - - if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent)) + if(m_isPeriodic && (m_duration >= 0 || GetHolder()->IsPassive() || GetHolder()->IsPermanent())) { m_periodicTimer -= diff; if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N @@ -670,9 +613,9 @@ void Aura::Update(uint32 diff) void AreaAura::Update(uint32 diff) { // update for the caster of the aura - if(m_caster_guid == m_target->GetGUID()) + if(GetCasterGUID() == GetTarget()->GetGUID()) { - Unit* caster = m_target; + Unit* caster = GetTarget(); if( !caster->hasUnitState(UNIT_STAT_ISOLATED) ) { @@ -782,22 +725,27 @@ void AreaAura::Update(uint32 diff) // we need ignore present caster self applied are auras sometime // in cases if this only auras applied for spell effect - Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), m_effIndex); - for(Unit::AuraMap::const_iterator i = (*tIter)->GetAuras().lower_bound(spair); i != (*tIter)->GetAuras().upper_bound(spair); ++i) + Unit::SpellAuraHolderBounds spair = (*tIter)->GetSpellAuraHolderBounds(GetId()); + for(Unit::SpellAuraHolderMap::const_iterator i = spair.first; i != spair.second; ++i) { if (i->second->IsDeleted()) continue; + Aura *aur = i->second->GetAuraByEffectIndex(m_effIndex); + + if (!aur) + continue; + switch(m_areaAuraType) { case AREA_AURA_ENEMY: // non caster self-casted auras (non stacked) - if(i->second->GetModifier()->m_auraname != SPELL_AURA_NONE) + if(aur->GetModifier()->m_auraname != SPELL_AURA_NONE) apply = false; break; case AREA_AURA_RAID: // non caster self-casted auras (stacked from diff. casters) - if(i->second->GetModifier()->m_auraname != SPELL_AURA_NONE || i->second->GetCasterGUID() == GetCasterGUID()) + if(aur->GetModifier()->m_auraname != SPELL_AURA_NONE || i->second->GetCasterGUID() == GetCasterGUID()) apply = false; break; default: @@ -819,9 +767,28 @@ void AreaAura::Update(uint32 diff) // recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?) if(actualSpellInfo != GetSpellProto()) actualBasePoints = actualSpellInfo->CalculateSimpleValue(m_effIndex); - AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, (*tIter), caster, NULL); + + SpellAuraHolder *holder = (*tIter)->GetSpellAuraHolder(actualSpellInfo->Id, GetCasterGUID()); + + bool addedToExisting = true; + if (!holder) + { + holder = CreateSpellAuraHolder(actualSpellInfo, (*tIter), caster); + addedToExisting = false; + } + + AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, holder, (*tIter), caster, NULL); aur->SetAuraDuration(GetAuraDuration()); - (*tIter)->AddAura(aur); + holder->AddAura(aur, m_effIndex); + + if (addedToExisting) + { + holder->SetInUse(true); + aur->ApplyModifier(true,true); + holder->SetInUse(false); + } + else + (*tIter)->AddSpellAuraHolder(holder); } } } @@ -830,6 +797,7 @@ void AreaAura::Update(uint32 diff) else // aura at non-caster { Unit* caster = GetCaster(); + Unit* target = GetTarget(); Aura::Update(diff); @@ -838,53 +806,53 @@ void AreaAura::Update(uint32 diff) // or caster is (no longer) friendly bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true); if( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) || - !caster->IsWithinDistInMap(m_target, m_radius) || + !caster->IsWithinDistInMap(target, m_radius) || !caster->HasAura(GetId(), GetEffIndex()) || - caster->IsFriendlyTo(m_target) != needFriendly + caster->IsFriendlyTo(target) != needFriendly ) { - m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(),GetCasterGUID()); + target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(),GetCasterGUID()); } else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group { // not check group if target == owner or target == pet - if (caster->GetCharmerOrOwnerGUID() != m_target->GetGUID() && caster->GetGUID() != m_target->GetCharmerOrOwnerGUID()) + if (caster->GetCharmerOrOwnerGUID() != target->GetGUID() && caster->GetGUID() != target->GetCharmerOrOwnerGUID()) { Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); Group *pGroup = check ? check->GetGroup() : NULL; if( pGroup ) { - Player* checkTarget = m_target->GetCharmerOrOwnerPlayerOrPlayerItself(); + Player* checkTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself(); if(!checkTarget || !pGroup->SameSubGroup(check, checkTarget)) - m_target->RemoveAura(GetId(), GetEffIndex()); + target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(),GetCasterGUID()); } else - m_target->RemoveAura(GetId(), GetEffIndex()); + target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(),GetCasterGUID()); } } else if( m_areaAuraType == AREA_AURA_RAID) // TODO: fix me! { // not check group if target == owner or target == pet - if (caster->GetCharmerOrOwnerGUID() != m_target->GetGUID() && caster->GetGUID() != m_target->GetCharmerOrOwnerGUID()) + if (caster->GetCharmerOrOwnerGUID() != target->GetGUID() && caster->GetGUID() != target->GetCharmerOrOwnerGUID()) { Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); Group *pGroup = check ? check->GetGroup() : NULL; if( pGroup ) { - Player* checkTarget = m_target->GetCharmerOrOwnerPlayerOrPlayerItself(); + Player* checkTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself(); if(!checkTarget) - m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); + target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGUID()); } else - m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); + target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGUID()); } } else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER ) { - if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() ) - m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID()); + if( target->GetGUID() != caster->GetCharmerOrOwnerGUID() ) + target->RemoveSingleAuraFromSpellAuraHolder(GetId(), GetEffIndex(), GetCasterGUID()); } } } @@ -900,7 +868,7 @@ void PersistentAreaAura::Update(uint32 diff) DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()); if (dynObj) { - if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius())) + if (!GetTarget()->IsWithinDistInMap(dynObj, dynObj->GetRadius())) remove = true; } else @@ -912,7 +880,7 @@ void PersistentAreaAura::Update(uint32 diff) Aura::Update(diff); if(remove) - m_target->RemoveAura(GetId(), GetEffIndex()); + GetTarget()->RemoveAura(GetId(), GetEffIndex()); } void Aura::ApplyModifier(bool apply, bool Real) @@ -925,386 +893,10 @@ void Aura::ApplyModifier(bool apply, bool Real) SetInUse(false); } -bool Aura::IsNeedVisibleSlot(Unit const* caster) const -{ - bool totemAura = caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem(); - - // special area auras cases - switch(m_spellProto->Effect[GetEffIndex()]) - { - case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: - return m_target != caster; - case SPELL_EFFECT_APPLY_AREA_AURA_PET: - case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: - case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: - case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: - case SPELL_EFFECT_APPLY_AREA_AURA_RAID: - // passive auras (except totem auras) do not get placed in caster slot - return (m_target != caster || totemAura || !m_isPassive) && m_modifier.m_auraname != SPELL_AURA_NONE; - default: - break; - } - - // passive auras (except totem auras) do not get placed in the slots - return !m_isPassive || totemAura; -} - -void Aura::_AddAura() -{ - if (!GetId()) - return; - if(!m_target) - return; - - // Second aura if some spell - bool secondaura = false; - // Try find slot for aura - uint8 slot = NULL_AURA_SLOT; - // Lookup for some spell auras (and get slot from it) - for(uint8 i = 0; i < MAX_EFFECT_INDEX; ++i) - { - Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), SpellEffectIndex(i)); - for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr) - { - // allow use single slot only by auras from same caster - if(itr->second->GetCasterGUID()==GetCasterGUID() && - !isWeaponBuffCoexistableWith(itr->second)) - { - slot = itr->second->GetAuraSlot(); - secondaura = true; - break; - } - } - if (secondaura) - break; - } - // Lookup free slot - if (!secondaura && m_target->GetVisibleAurasCount() < MAX_AURAS) - { - Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras(); - for(uint8 i = 0; i < MAX_AURAS; ++i) - { - Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i); - if(itr == visibleAuras->end()) - { - slot = i; - // update for out of range group members (on 1 slot use) - m_target->UpdateAuraForGroup(slot); - break; - } - } - } - - Unit* caster = GetCaster(); - - // set infinity cooldown state for spells - if(caster && caster->GetTypeId() == TYPEID_PLAYER) - { - if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) - { - Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL; - ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true); - } - } - - if (IsNeedVisibleSlot(caster)) - { - SetAuraSlot( slot ); - if(slot < MAX_AURAS) // slot found send data to client - { - SetAura(false); - SetAuraFlags((1 << GetEffIndex()) | ((GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_NOT_CASTER : AFLAG_NONE) | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE)); - SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL)); - SendAuraUpdate(false); - } - - //***************************************************** - // Update target aura state flag (at 1 aura apply) - // TODO: Make it easer - //***************************************************** - if (!secondaura) - { - // Sitdown on apply aura req seated - if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState()) - m_target->SetStandState(UNIT_STAND_STATE_SIT); - - // register aura diminishing on apply - if (getDiminishGroup() != DIMINISHING_NONE ) - m_target->ApplyDiminishingAura(getDiminishGroup(), true); - - // Update Seals information - if (IsSealSpell(m_spellProto)) - m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); - - // Conflagrate aura state on Immolate and Shadowflame - if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && - // Immolate - ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) || - // Shadowflame - (m_spellProto->SpellFamilyFlags2 & 0x00000002))) - m_target->ModifyAuraState(AURA_STATE_CONFLAGRATE, true); - - // Faerie Fire (druid versions) - if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400))) - m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true); - - // Victorious - if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000))) - m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true); - - // Swiftmend state on Regrowth & Rejuvenation - if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (m_spellProto->SpellFamilyFlags & UI64LIT(0x50))) - m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true); - - // Deadly poison aura state - if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellProto->SpellFamilyFlags & UI64LIT(0x10000))) - m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true); - - // Enrage aura state - if(m_spellProto->Dispel == DISPEL_ENRAGE) - m_target->ModifyAuraState(AURA_STATE_ENRAGE, true); - } - } -} - -bool Aura::_RemoveAura() -{ - // Remove all triggered by aura spells vs unlimited duration - // except same aura replace case - if(m_removeMode!=AURA_REMOVE_BY_STACK) - CleanupTriggeredSpells(); - - Unit* caster = GetCaster(); - - if(caster && IsPersistent()) - { - DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()); - if (dynObj) - dynObj->RemoveAffected(m_target); - } - - //passive auras do not get put in slots - // Note: but totem can be not accessible for aura target in time remove (to far for find in grid) - //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) - // return; - - uint8 slot = GetAuraSlot(); - - if(slot >= MAX_AURAS) // slot not set - return false; - - if(m_target->GetVisibleAura(slot) == 0) - return false; - - bool lastaura = true; - - // find other aura in same slot (current already removed from list) - for(int i = 0; i < MAX_EFFECT_INDEX; ++i) - { - Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), SpellEffectIndex(i)); - for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr) - { - if(itr->second->GetAuraSlot() == slot) - { - lastaura = false; - break; - } - } - if(!lastaura) - break; - } - - // only remove icon when the last aura of the spell is removed (current aura already removed from list) - if (!lastaura) - return false; - - // unregister aura diminishing (and store last time) - if (getDiminishGroup() != DIMINISHING_NONE ) - m_target->ApplyDiminishingAura(getDiminishGroup(), false); - - SetAura(true); - SetAuraFlags(AFLAG_NONE); - SetAuraLevel(0); - - if (m_removeMode != AURA_REMOVE_BY_DELETE) - { - SendAuraUpdate(true); - - // update for out of range group members - m_target->UpdateAuraForGroup(slot); - - //***************************************************** - // Update target aura state flag (at last aura remove) - //***************************************************** - // Enrage aura state - if(m_spellProto->Dispel == DISPEL_ENRAGE) - m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); - - uint32 removeState = 0; - uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags; - uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2; - switch(m_spellProto->SpellFamilyName) - { - case SPELLFAMILY_PALADIN: - if (IsSealSpell(m_spellProto)) - removeState = AURA_STATE_JUDGEMENT; // Update Seals information - break; - case SPELLFAMILY_WARLOCK: - // Conflagrate aura state on Immolate and Shadowflame, - if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) || - (m_spellProto->SpellFamilyFlags2 & 0x00000002)) - { - removeFamilyFlag = UI64LIT(0x0000000000000004); - removeFamilyFlag2 = 0x00000002; - removeState = AURA_STATE_CONFLAGRATE; - } - break; - case SPELLFAMILY_DRUID: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400)) - removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) - else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50)) - { - removeFamilyFlag = 0x50; - removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state - } - break; - case SPELLFAMILY_WARRIOR: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000)) - removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious - break; - case SPELLFAMILY_ROGUE: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000)) - removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state - break; - case SPELLFAMILY_HUNTER: - if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) - removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) - } - - // Remove state (but need check other auras for it) - if (removeState) - { - bool found = false; - Unit::AuraMap& Auras = m_target->GetAuras(); - for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) - { - SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); - if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && - (auraSpellInfo->SpellFamilyFlags & removeFamilyFlag || auraSpellInfo->SpellFamilyFlags2 & removeFamilyFlag2)) - { - found = true; - break; - } - } - // this has been last aura - if(!found) - m_target->ModifyAuraState(AuraState(removeState), false); - } - - // reset cooldown state for spells - if(caster && caster->GetTypeId() == TYPEID_PLAYER) - { - if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE ) - // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) - ((Player*)caster)->SendCooldownEvent(GetSpellProto()); - } - } - - return true; -} - -void Aura::SendAuraUpdate(bool remove) -{ - WorldPacket data(SMSG_AURA_UPDATE); - data << m_target->GetPackGUID(); - data << uint8(GetAuraSlot()); - data << uint32(remove ? 0 : GetId()); - - if(remove) - { - m_target->SendMessageToSet(&data, true); - return; - } - - uint8 auraFlags = GetAuraFlags(); - data << uint8(auraFlags); - data << uint8(GetAuraLevel()); - data << uint8(m_procCharges ? m_procCharges*m_stackAmount : m_stackAmount); - - if(!(auraFlags & AFLAG_NOT_CASTER)) - { - data.appendPackGUID(GetCasterGUID()); - } - - if(auraFlags & AFLAG_DURATION) - { - data << uint32(GetAuraMaxDuration()); - data << uint32(GetAuraDuration()); - } - - m_target->SendMessageToSet(&data, true); -} - -void Aura::SetStackAmount(uint8 stackAmount) -{ - Unit *target = GetTarget(); - Unit *caster = GetCaster(); - if (!target || !caster) - return; - - bool refresh = stackAmount >= m_stackAmount; - if (stackAmount != m_stackAmount) - { - m_stackAmount = stackAmount; - int32 amount = m_stackAmount * caster->CalculateSpellDamage(target, m_spellProto, m_effIndex, &m_currentBasePoints); - // Reapply if amount change - if (amount!=m_modifier.m_amount) - { - ApplyModifier(false, true); - m_modifier.m_amount = amount; - ApplyModifier(true, true); - } - } - - if (refresh) - // Stack increased refresh duration - RefreshAura(); - else - // Stack decreased only send update - SendAuraUpdate(false); -} - -bool Aura::modStackAmount(int32 num) -{ - // Can`t mod - if (!m_spellProto->StackAmount) - return true; - - // Modify stack but limit it - int32 stackAmount = m_stackAmount + num; - if (stackAmount > (int32)m_spellProto->StackAmount) - stackAmount = m_spellProto->StackAmount; - else if (stackAmount <=0) // Last aura from stack removed - { - m_stackAmount = 0; - return true; // need remove aura - } - - // Update stack amount - SetStackAmount(stackAmount); - return false; -} - -void Aura::RefreshAura() -{ - m_duration = m_maxduration; - SendAuraUpdate(false); -} - bool Aura::isAffectedOnSpell(SpellEntry const *spell) const { // Check family name - if (spell->SpellFamilyName != m_spellProto->SpellFamilyName) + if (spell->SpellFamilyName != GetSpellProto()->SpellFamilyName) return false; // Check EffectClassMask uint32 const *ptr = getAuraSpellClassMask(); @@ -1320,11 +912,11 @@ void Aura::ReapplyAffectedPassiveAuras( Unit* target, bool owner_mode ) std::set affectedSelf; std::set affectedAuraCaster; - for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) + for(Unit::SpellAuraHolderMap::const_iterator itr = target->GetSpellAuraHolderMap().begin(); itr != target->GetSpellAuraHolderMap().end(); ++itr) { // permanent passive or permanent area aura // passive spells can be affected only by own or owner spell mods) - if (itr->second->IsPermanent() && (owner_mode && itr->second->IsPassive() || itr->second->IsAreaAura()) && + if (itr->second->IsPermanent() && (owner_mode && itr->second->IsPassive() /*|| itr->second->IsAreaAura()*/) && // non deleted and not same aura (any with same spell id) !itr->second->IsDeleted() && itr->second->GetId() != GetId() && // and affected by aura @@ -1341,7 +933,7 @@ void Aura::ReapplyAffectedPassiveAuras( Unit* target, bool owner_mode ) for(std::set::const_iterator set_itr = affectedSelf.begin(); set_itr != affectedSelf.end(); ++set_itr) { target->RemoveAurasDueToSpell(*set_itr); - target->CastSpell(m_target, *set_itr, true); + target->CastSpell(GetTarget(), *set_itr, true); } if (!affectedAuraCaster.empty()) @@ -1351,7 +943,7 @@ void Aura::ReapplyAffectedPassiveAuras( Unit* target, bool owner_mode ) { target->RemoveAurasDueToSpell(*set_itr); if (caster) - caster->CastSpell(m_target, *set_itr, true); + caster->CastSpell(GetTarget(), *set_itr, true); } } } @@ -1397,38 +989,6 @@ void Aura::ReapplyAffectedPassiveAuras() ReapplyAffectedPassiveAuras(member, false); } - -bool Aura::isWeaponBuffCoexistableWith(Aura* ref) -{ - // Exclude Debuffs - if (!IsPositive()) - return false; - - // Exclude Non-generic Buffs [ie: Runeforging] and Executioner-Enchant - if (GetSpellProto()->SpellFamilyName != SPELLFAMILY_GENERIC || GetId() == 42976) - return false; - - // Exclude Stackable Buffs [ie: Blood Reserve] - if (GetSpellProto()->StackAmount) - return false; - - // only self applied player buffs - if (m_target->GetTypeId() != TYPEID_PLAYER || m_target->GetGUID() != GetCasterGUID()) - return false; - - Item* castItem = ((Player*)m_target)->GetItemByGuid(GetCastItemGUID()); - if (!castItem) - return false; - - // Limit to Weapon-Slots - if (!castItem->IsEquipped() || - (castItem->GetSlot() != EQUIPMENT_SLOT_MAINHAND && castItem->GetSlot() != EQUIPMENT_SLOT_OFFHAND)) - return false; - - // form different weapons - return ref->GetCastItemGUID() != GetCastItemGUID(); -} - /*********************************************************/ /*** BASIC AURA FUNCTION ***/ /*********************************************************/ @@ -1456,7 +1016,7 @@ void Aura::HandleAddModifier(bool apply, bool Real) case 54741: // Firestarter case 57761: // Fireball! case 64823: // Elune's Wrath (Balance druid t8 set - SetAuraCharges(1); + GetHolder()->SetAuraCharges(1); break; } @@ -1467,7 +1027,7 @@ void Aura::HandleAddModifier(bool apply, bool Real) this, // prevent expire spell mods with (charges > 0 && m_stackAmount > 1) // all this spell expected expire not at use but at spell proc event check - GetSpellProto()->StackAmount > 1 ? 0 : m_procCharges); + GetSpellProto()->StackAmount > 1 ? 0 : GetHolder()->GetAuraCharges()); } ((Player*)GetTarget())->AddSpellMod(m_spellmod, apply); @@ -2071,8 +1631,8 @@ void Aura::TriggerSpell() case 28820: { // Need remove self if Lightning Shield not active - Unit::AuraMap const& auras = triggerTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = triggerTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { SpellEntry const* spell = itr->second->GetSpellProto(); if( spell->SpellFamilyName == SPELLFAMILY_SHAMAN && @@ -3133,7 +2693,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real) { // remove other shapeshift before applying a new one if(target->m_ShapeShiftFormSpellId) - target->RemoveAurasDueToSpell(target->m_ShapeShiftFormSpellId, this); + target->RemoveAurasDueToSpell(target->m_ShapeShiftFormSpellId, GetHolder()); target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form); @@ -3545,7 +3105,7 @@ void Aura::HandleBindSight(bool apply, bool /*Real*/) Camera& camera = ((Player*)caster)->GetCamera(); if (apply) - camera.SetView(m_target); + camera.SetView(GetTarget()); else camera.ResetView(); } @@ -3569,7 +3129,7 @@ void Aura::HandleAuraTrackCreatures(bool apply, bool /*Real*/) return; if(apply) - GetTarget()->RemoveNoStackAurasDueToAura(this); + GetTarget()->RemoveNoStackAurasDueToAuraHolder(GetHolder()); GetTarget()->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1) : 0 ); } @@ -3579,7 +3139,7 @@ void Aura::HandleAuraTrackResources(bool apply, bool /*Real*/) return; if(apply) - GetTarget()->RemoveNoStackAurasDueToAura(this); + GetTarget()->RemoveNoStackAurasDueToAuraHolder(GetHolder()); GetTarget()->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(m_modifier.m_miscvalue-1): 0 ); } @@ -3589,7 +3149,7 @@ void Aura::HandleAuraTrackStealthed(bool apply, bool /*Real*/) return; if(apply) - GetTarget()->RemoveNoStackAurasDueToAura(this); + GetTarget()->RemoveNoStackAurasDueToAuraHolder(GetHolder()); GetTarget()->ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_TRACK_STEALTHED, apply); } @@ -4142,7 +3702,7 @@ void Aura::HandleModStealth(bool apply, bool Real) if (Aura* aura = target->GetAura(58427, EFFECT_INDEX_0)) { aura->SetAuraMaxDuration(20*IN_MILLISECONDS); - aura->RefreshAura(); + GetHolder()->RefreshHolder(); } } } @@ -4670,8 +4230,8 @@ void Aura::HandleAuraModSchoolImmunity(bool apply, bool Real) && IsPositiveSpell(GetId()) ) //Only positive immunity removes auras { uint32 school_mask = m_modifier.m_miscvalue; - Unit::AuraMap& Auras = target->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + Unit::SpellAuraHolderMap& Auras = target->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) { next = iter; ++next; @@ -4723,7 +4283,7 @@ void Aura::HandleAuraProcTriggerSpell(bool apply, bool Real) switch (GetId()) { case 28200: // Ascendance (Talisman of Ascendance trinket) - SetAuraCharges(6); + GetHolder()->SetAuraCharges(6); break; default: break; } @@ -6220,12 +5780,12 @@ void Aura::HandleShapeshiftBoosts(bool apply) if(MasterShaperSpellId) target->RemoveAurasDueToSpell(MasterShaperSpellId); - Unit::AuraMap& tAuras = m_target->GetAuras(); - for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) + Unit::SpellAuraHolderMap& tAuras = target->GetSpellAuraHolderMap(); + for (Unit::SpellAuraHolderMap::iterator itr = tAuras.begin(); itr != tAuras.end();) { if (itr->second->IsRemovedOnShapeLost()) { - m_target->RemoveAurasDueToSpell(itr->second->GetId()); + target->RemoveAurasDueToSpell(itr->second->GetId()); itr = tAuras.begin(); } else @@ -6234,564 +5794,6 @@ void Aura::HandleShapeshiftBoosts(bool apply) } } -void Aura::HandleSpellSpecificBoosts(bool apply) -{ - bool cast_at_remove = false; // if spell must be casted at last aura from stack remove - uint32 spellId1 = 0; - uint32 spellId2 = 0; - uint32 spellId3 = 0; - uint32 spellId4 = 0; - - switch(GetSpellProto()->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - { - // Illusionary Barrier - if(GetId() == 57350 && !apply && m_target->getPowerType() == POWER_MANA) - { - cast_at_remove = true; - spellId1 = 60242; // Darkmoon Card: Illusion - } - else - return; - break; - } - case SPELLFAMILY_MAGE: - { - // Ice Barrier (non stacking from one caster) - if (m_spellProto->SpellIconID == 32) - { - if (!apply && (m_removeMode == AURA_REMOVE_BY_DISPEL || m_removeMode == AURA_REMOVE_BY_SHIELD_BREAK)) - { - Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) - { - // Shattered Barrier - if ((*itr)->GetSpellProto()->SpellIconID == 2945) - { - cast_at_remove = true; - // first rank have 50% chance - if ((*itr)->GetId() != 44745 || roll_chance_i(50)) - spellId1 = 55080; - break; - } - } - } - else - return; - break; - } - - switch(GetId()) - { - case 11129: // Combustion (remove triggered aura stack) - { - if(!apply) - spellId1 = 28682; - else - return; - break; - } - case 28682: // Combustion (remove main aura) - { - if(!apply) - spellId1 = 11129; - else - return; - break; - } - case 44401: // Missile Barrage (triggered) - case 48108: // Hot Streak (triggered) - case 57761: // Fireball! (Brain Freeze triggered) - { - // consumed aura - if (!apply && m_removeMode != AURA_REMOVE_BY_EXPIRE) - { - Unit* caster = GetCaster(); - // Item - Mage T10 2P Bonus - if (!caster || !caster->HasAura(70752)) - return; - - cast_at_remove = true; - spellId1 = 70753; // Pushing the Limit - } - else - return; - break; - } - default: - return; - } - break; - } - case SPELLFAMILY_WARRIOR: - { - if(!apply) - { - // Remove Blood Frenzy only if target no longer has any Deep Wound or Rend (applying is handled by procs) - if (GetSpellProto()->Mechanic != MECHANIC_BLEED) - return; - - // If target still has one of Warrior's bleeds, do nothing - Unit::AuraList const& PeriodicDamage = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(Unit::AuraList::const_iterator i = PeriodicDamage.begin(); i != PeriodicDamage.end(); ++i) - if( (*i)->GetCasterGUID() == GetCasterGUID() && - (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARRIOR && - (*i)->GetSpellProto()->Mechanic == MECHANIC_BLEED) - return; - - spellId1 = 30069; // Blood Frenzy (Rank 1) - spellId2 = 30070; // Blood Frenzy (Rank 2) - } - break; - } - case SPELLFAMILY_WARLOCK: - { - // Fear (non stacking) - if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) - { - if(!apply) - { - Unit* caster = GetCaster(); - if(!caster) - return; - - Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) - { - SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); - // Improved Fear - if (dummyEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && dummyEntry->SpellIconID == 98) - { - cast_at_remove = true; - switch((*itr)->GetModifier()->m_amount) - { - // Rank 1 - case 0: spellId1 = 60946; break; - // Rank 1 - case 1: spellId1 = 60947; break; - } - break; - } - } - } - else - return; - } - // Shadowflame (DoT) - else if (m_spellProto->SpellFamilyFlags2 & 0x00000002) - { - // Glyph of Shadowflame - Unit* caster; - if(!apply) - spellId1 = 63311; - else if(((caster = GetCaster())) && caster->HasAura(63310)) - spellId1 = 63311; - else - return; - } - else - return; - break; - } - case SPELLFAMILY_PRIEST: - { - // Shadow Word: Pain (need visual check fro skip improvement talent) or Vampiric Touch - if (m_spellProto->SpellIconID == 234 && m_spellProto->SpellVisual[0] || m_spellProto->SpellIconID == 2213) - { - if (!apply && m_removeMode == AURA_REMOVE_BY_DISPEL) - { - Unit* caster = GetCaster(); - if(!caster) - return; - - Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) - { - // Shadow Affinity - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST - && (*itr)->GetSpellProto()->SpellIconID == 178) - { - // custom cast code - int32 basepoints0 = (*itr)->GetModifier()->m_amount * caster->GetCreateMana() / 100; - caster->CastCustomSpell(caster, 64103, &basepoints0, NULL, NULL, true, NULL, this); - return; - } - } - } - else - return; - } - // Power Word: Shield - else if (apply && m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001) && m_spellProto->Mechanic == MECHANIC_SHIELD) - { - Unit* caster = GetCaster(); - if(!caster) - return; - - // Glyph of Power Word: Shield - if (Aura* glyph = caster->GetAura(55672, EFFECT_INDEX_0)) - { - int32 heal = (glyph->GetModifier()->m_amount * m_modifier.m_amount)/100; - caster->CastCustomSpell(m_target, 56160, &heal, NULL, NULL, true, 0, this); - } - return; - } - - switch(GetId()) - { - // Abolish Disease (remove 1 more poison effect with Body and Soul) - case 552: - { - if(apply) - { - int chance =0; - Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) - { - SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); - // Body and Soul (talent ranks) - if (dummyEntry->SpellFamilyName == SPELLFAMILY_PRIEST && dummyEntry->SpellIconID == 2218 && - dummyEntry->SpellVisual[0]==0) - { - chance = (*itr)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_1); - break; - } - } - - if(roll_chance_i(chance)) - spellId1 = 64134; // Body and Soul (periodic dispel effect) - } - else - spellId1 = 64134; // Body and Soul (periodic dispel effect) - break; - } - // Dispersion mana reg and immunity - case 47585: - spellId1 = 60069; // Dispersion - spellId2 = 63230; // Dispersion - break; - default: - return; - } - break; - } - case SPELLFAMILY_DRUID: - { - // Barkskin - if (GetId()==22812 && m_target->HasAura(63057)) // Glyph of Barkskin - spellId1 = 63058; // Glyph - Barkskin 01 - else - return; - break; - } - case SPELLFAMILY_ROGUE: - // Sprint (skip non player casted spells by category) - if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000040) && GetSpellProto()->Category == 44) - { - if(!apply || m_target->HasAura(58039)) // Glyph of Blurred Speed - spellId1 = 61922; // Sprint (waterwalk) - else - return; - } - else - return; - break; - case SPELLFAMILY_HUNTER: - { - // Freezing Trap Effect - if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000008)) - { - if(!apply) - { - Unit *caster = GetCaster(); - // Glyph of Freezing Trap - if (caster && caster->HasAura(56845)) - { - cast_at_remove = true; - spellId1 = 61394; - } - else - return; - } - else - return; - } - // Aspect of the Dragonhawk dodge - else if (GetSpellProto()->SpellFamilyFlags2 & 0x00001000) - { - spellId1 = 61848; - - // triggered spell have same category as main spell and cooldown - if (apply && m_target->GetTypeId()==TYPEID_PLAYER) - ((Player*)m_target)->RemoveSpellCooldown(61848); - } - else - return; - break; - } - case SPELLFAMILY_PALADIN: - { - if (m_spellProto->Id == 31884) // Avenging Wrath - { - if(!apply) - spellId1 = 57318; // Sanctified Wrath (triggered) - else - { - int32 percent = 0; - Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) - { - if ((*itr)->GetSpellProto()->SpellIconID == 3029) - { - percent = (*itr)->GetModifier()->m_amount; - break; - } - } - - // apply in special way - if(percent) - { - spellId1 = 57318; // Sanctified Wrath (triggered) - // prevent aura deletion, specially in multi-boost case - SetInUse(true); - m_target->CastCustomSpell(m_target, spellId1, &percent, &percent, NULL, true, NULL, this); - SetInUse(false); - } - return; - } - break; - } - - // Only process on player casting paladin aura - // all aura bonuses applied also in aura area effect way to caster - if (GetCasterGUID() != m_target->GetGUID() || !IS_PLAYER_GUID(GetCasterGUID())) - return; - - if (GetSpellSpecific(m_spellProto->Id) != SPELL_AURA) - return; - - // Sanctified Retribution and Swift Retribution (they share one aura), but not Retribution Aura (already gets modded) - if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000008))==0) - spellId1 = 63531; // placeholder for talent spell mods - // Improved Concentration Aura (auras bonus) - spellId2 = 63510; // placeholder for talent spell mods - // Improved Devotion Aura (auras bonus) - spellId3 = 63514; // placeholder for talent spell mods - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // second part of spell apply - switch (GetId()) - { - case 49039: spellId1 = 50397; break; // Lichborne - - case 48263: // Frost Presence - case 48265: // Unholy Presence - case 48266: // Blood Presence - { - // else part one per 3 pair - if (GetId()==48263 || GetId()==48265) // Frost Presence or Unholy Presence - { - // Improved Blood Presence - int32 heal_pct = 0; - if (apply) - { - Unit::AuraList const& bloodAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = bloodAuras.begin(); itr != bloodAuras.end(); ++itr) - { - // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2636) - { - heal_pct = (*itr)->GetModifier()->m_amount; - break; - } - } - } - - if (heal_pct) - m_target->CastCustomSpell(m_target, 63611, &heal_pct, NULL, NULL, true, NULL, this); - else - m_target->RemoveAurasDueToSpell(63611); - } - else - spellId1 = 63611; // Improved Blood Presence, trigger for heal - - if (GetId()==48263 || GetId()==48266) // Frost Presence or Blood Presence - { - // Improved Unholy Presence - int32 power_pct = 0; - if (apply) - { - Unit::AuraList const& unholyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = unholyAuras.begin(); itr != unholyAuras.end(); ++itr) - { - // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2633) - { - power_pct = (*itr)->GetModifier()->m_amount; - break; - } - } - } - - if (power_pct || !apply) - spellId2 = 49772; // Unholy Presence, speed part, spell1 used for Improvement presence fit to own presence - } - else - spellId1 = 49772; // Unholy Presence move speed - - if (GetId()==48265 || GetId()==48266) // Unholy Presence or Blood Presence - { - // Improved Frost Presence - int32 stamina_pct = 0; - if (apply) - { - Unit::AuraList const& frostAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = frostAuras.begin(); itr != frostAuras.end(); ++itr) - { - // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2632) - { - stamina_pct = (*itr)->GetModifier()->m_amount; - break; - } - } - } - - if (stamina_pct) - m_target->CastCustomSpell(m_target, 61261, &stamina_pct, NULL, NULL, true, NULL, this); - else - m_target->RemoveAurasDueToSpell(61261); - } - else - spellId1 = 61261; // Frost Presence, stamina - - if (GetId()==48265) // Unholy Presence - { - // Improved Unholy Presence, special case for own presence - int32 power_pct = 0; - if (apply) - { - Unit::AuraList const& unholyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = unholyAuras.begin(); itr != unholyAuras.end(); ++itr) - { - // skip same icon - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && - (*itr)->GetSpellProto()->SpellIconID == 2633) - { - power_pct = (*itr)->GetModifier()->m_amount; - break; - } - } - } - - if (power_pct) - { - int32 bp = 5; - m_target->CastCustomSpell(m_target, 63622, &bp, &bp, &bp, true, NULL, this); - m_target->CastCustomSpell(m_target, 65095, &bp, NULL, NULL, true, NULL, this); - } - else - { - m_target->RemoveAurasDueToSpell(63622); - m_target->RemoveAurasDueToSpell(65095); - } - } - break; - } - } - - // Improved Blood Presence - if (GetSpellProto()->SpellIconID == 2632 && GetModifier()->m_auraname==SPELL_AURA_DUMMY) - { - // if presence active: Frost Presence or Unholy Presence - if (apply && (m_target->HasAura(48263) || m_target->HasAura(48265))) - { - int32 bp = GetModifier()->m_amount; - m_target->CastCustomSpell(m_target, 63611, &bp, NULL, NULL, true, NULL, this); - } - else - m_target->RemoveAurasDueToSpell(63611); - return; - } - - // Improved Frost Presence - if (GetSpellProto()->SpellIconID == 2636 && GetModifier()->m_auraname==SPELL_AURA_DUMMY) - { - // if presence active: Unholy Presence or Blood Presence - if (apply && (m_target->HasAura(48265) || m_target->HasAura(48266))) - { - int32 bp = GetModifier()->m_amount; - m_target->CastCustomSpell(m_target, 61261, &bp, NULL, NULL, true, NULL, this); - } - else - m_target->RemoveAurasDueToSpell(61261); - return; - } - - // Improved Unholy Presence - if (GetSpellProto()->SpellIconID == 2633 && GetModifier()->m_auraname==SPELL_AURA_DUMMY) - { - // if presence active: Unholy Presence - if (apply && m_target->HasAura(48265)) - { - int32 bp = 5; - m_target->CastCustomSpell(m_target, 63622, &bp, &bp, &bp, true, NULL, this); - m_target->CastCustomSpell(m_target, 65095, &bp, NULL, NULL, true, NULL, this); - } - else - { - m_target->RemoveAurasDueToSpell(63622); - m_target->RemoveAurasDueToSpell(65095); - } - - // if presence active: Frost Presence or Blood Presence - if (!apply || m_target->HasAura(48263) || m_target->HasAura(48266)) - spellId1 = 49772; - else - return; - break; - } - break; - } - default: - return; - } - - // prevent aura deletion, specially in multi-boost case - SetInUse(true); - - if (apply || cast_at_remove) - { - if (spellId1) - m_target->CastSpell(m_target, spellId1, true, NULL, this); - if (spellId2 && !IsDeleted()) - m_target->CastSpell(m_target, spellId2, true, NULL, this); - if (spellId3 && !IsDeleted()) - m_target->CastSpell(m_target, spellId3, true, NULL, this); - if (spellId4 && !IsDeleted()) - m_target->CastSpell(m_target, spellId4, true, NULL, this); - } - else - { - if (spellId1) - m_target->RemoveAurasByCasterSpell(spellId1, GetCasterGUID()); - if (spellId2) - m_target->RemoveAurasByCasterSpell(spellId2, GetCasterGUID()); - if (spellId3) - m_target->RemoveAurasByCasterSpell(spellId3, GetCasterGUID()); - if (spellId4) - m_target->RemoveAurasByCasterSpell(spellId4, GetCasterGUID()); - } - - SetInUse(false); -} - void Aura::HandleAuraEmpathy(bool apply, bool /*Real*/) { if(GetTarget()->GetTypeId() != TYPEID_UNIT) @@ -6988,27 +5990,6 @@ void Aura::HandleSpiritOfRedemption( bool apply, bool Real ) target->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, GetSpellProto(), false); } -void Aura::CleanupTriggeredSpells() -{ - uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()]; - if(!tSpellId) - return; - - SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId); - if(!tProto) - return; - - if(GetSpellDuration(tProto) != -1) - return; - - // needed for spell 43680, maybe others - // TODO: is there a spell flag, which can solve this in a more sophisticated way? - if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL && - GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()]) - return; - m_target->RemoveAurasDueToSpell(tSpellId); -} - void Aura::HandleSchoolAbsorb(bool apply, bool Real) { if(!Real) @@ -8345,7 +7326,7 @@ void Aura::HandlePhase(bool apply, bool Real) { Unit::AuraList const& phases = target->GetAurasByType(SPELL_AURA_PHASE); if(!phases.empty()) - target->RemoveAurasDueToSpell(phases.front()->GetId(), this); + target->RemoveAurasDueToSpell(phases.front()->GetId(), GetHolder()); } // no-phase is also phase state so same code for apply and remove @@ -8395,23 +7376,6 @@ void Aura::HandlePhase(bool apply, bool Real) target->SetVisibility(target->GetVisibility()); } -void Aura::UnregisterSingleCastAura() -{ - if (IsSingleTarget()) - { - if(Unit* caster = GetCaster()) - { - caster->GetSingleCastAuras().remove(this); - } - else - { - sLog.outError("Couldn't find the caster of the single target aura (SpellId %u), may crash later!", GetId()); - ASSERT(false); - } - m_isSingleTargetAura = false; - } -} - void Aura::HandleAuraSafeFall( bool Apply, bool Real ) { // implemented in WorldSession::HandleMovementOpcodes @@ -8491,14 +7455,1199 @@ void Aura::HandleAllowOnlyAbility(bool apply, bool Real) void Aura::SetAuraMaxDuration( int32 duration ) { - m_maxduration = duration; - - // possible overwrite persistent state - if (duration > 0) - { - if (!(m_isPassive && m_spellProto->DurationIndex == 0)) - m_permanent = false; + m_maxduration = duration; - m_auraFlags |= AFLAG_DURATION; + // possible overwrite persistent state + if (duration > 0) + { + if (!(GetHolder()->IsPassive() && GetSpellProto()->DurationIndex == 0)) + GetHolder()->SetPermanent(false); + + GetHolder()->SetAuraFlags(GetHolder()->GetAuraFlags() | AFLAG_DURATION); + } +} + +bool Aura::IsLastAuraOnHolder() +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (i != GetEffIndex() && GetHolder()->m_auras[i]) + return false; + return true; +} + +SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem) : m_caster_guid(0), m_target(target), +m_castItemGuid(castItem?castItem->GetGUID():0), m_permanent(false), +m_isRemovedOnShapeLost(true), m_in_use(0), m_deleted(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE), m_auraSlot(MAX_AURAS), +m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0), m_stackAmount(1) +{ + ASSERT(target); + ASSERT(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element"); + + if(!caster) + m_caster_guid = target->GetGUID(); + else + { + // remove this assert when not unit casters will be supported + ASSERT(caster->GetObjectGuid().IsUnit()) + m_caster_guid = caster->GetGUID(); + } + + m_applyTime = time(NULL); + m_spellProto = spellproto; + m_isPassive = IsPassiveSpell(GetId()); + m_isDeathPersist = IsDeathPersistentSpell(m_spellProto); + m_isSingleTarget = IsSingleTargetSpell(spellproto); + + if(GetSpellMaxDuration(m_spellProto) == -1 || m_isPassive && m_spellProto->DurationIndex == 0) + m_permanent = true; + + m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && + m_spellProto->Stances && + !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && + !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT)); + + Player* modOwner = caster && caster->GetObjectGuid().IsUnit() ? ((Unit*)caster)->GetSpellModOwner() : NULL; + + m_procCharges = m_spellProto->procCharges; + if(modOwner) + modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges); + + if (caster && caster->GetObjectGuid().IsUnit() && m_spellProto->Id == 22959) // Improved Scorch + { + // Glyph of Improved Scorch + if (Aura* glyph = ((Unit*)caster)->GetDummyAura(56371)) + m_stackAmount = glyph->GetModifier()->m_amount; + } + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + m_auras[i] = NULL; +} + +void SpellAuraHolder::AddAura(Aura *aura, SpellEffectIndex index) +{ + m_auras[index] = aura; + m_auraFlags |= (1 << index); +} + +void SpellAuraHolder::RemoveAura(SpellEffectIndex index) +{ + m_auras[index] = NULL; + m_auraFlags &= ~(1 << index); +} + +void SpellAuraHolder::ApplyAuraModifiers(bool apply, bool real) +{ + SetInUse(true); + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + Aura *aur = GetAuraByEffectIndex(SpellEffectIndex(i)); + if (aur) + aur->ApplyModifier(apply, real); + } + SetInUse(false); +} + +void SpellAuraHolder::_AddSpellAuraHolder() +{ + if (!GetId()) + return; + if(!m_target) + return; + + // Try find slot for aura + uint8 slot = NULL_AURA_SLOT; + + // Lookup free slot + if (m_target->GetVisibleAurasCount() < MAX_AURAS) + { + Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras(); + for(uint8 i = 0; i < MAX_AURAS; ++i) + { + Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i); + if(itr == visibleAuras->end()) + { + slot = i; + // update for out of range group members (on 1 slot use) + m_target->UpdateAuraForGroup(slot); + break; + } + } + } + + Unit* caster = GetCaster(); + + // set infinity cooldown state for spells + if(caster && caster->GetTypeId() == TYPEID_PLAYER) + { + if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + { + Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL; + ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true); + } + } + + uint8 flags = 0; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (m_auras[i]) + flags |= (1 << i); + } + flags |= ((GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_NOT_CASTER : AFLAG_NONE) | ((GetSpellMaxDuration(m_spellProto) > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE); + SetAuraFlags(flags); + + SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL)); + + if (IsNeedVisibleSlot(caster)) + { + SetAuraSlot( slot ); + if(slot < MAX_AURAS) // slot found send data to client + { + SetVisibleAura(false); + SendAuraUpdate(false); + } + + //***************************************************** + // Update target aura state flag on holder apply + // TODO: Make it easer + //***************************************************** + + // Sitdown on apply aura req seated + if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState()) + m_target->SetStandState(UNIT_STAND_STATE_SIT); + + // register aura diminishing on apply + if (getDiminishGroup() != DIMINISHING_NONE ) + m_target->ApplyDiminishingAura(getDiminishGroup(), true); + + // Update Seals information + if (IsSealSpell(m_spellProto)) + m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); + + // Conflagrate aura state on Immolate and Shadowflame + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && + // Immolate + ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) || + // Shadowflame + (m_spellProto->SpellFamilyFlags2 & 0x00000002))) + m_target->ModifyAuraState(AURA_STATE_CONFLAGRATE, true); + + // Faerie Fire (druid versions) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400))) + m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true); + + // Victorious + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && (m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000))) + m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true); + + // Swiftmend state on Regrowth & Rejuvenation + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && (m_spellProto->SpellFamilyFlags & UI64LIT(0x50))) + m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true); + + // Deadly poison aura state + if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellProto->SpellFamilyFlags & UI64LIT(0x10000))) + m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true); + + // Enrage aura state + if(m_spellProto->Dispel == DISPEL_ENRAGE) + m_target->ModifyAuraState(AURA_STATE_ENRAGE, true); + + } +} + +void SpellAuraHolder::_RemoveSpellAuraHolder() +{ + // Remove all triggered by aura spells vs unlimited duration + // except same aura replace case + if(m_removeMode!=AURA_REMOVE_BY_STACK) + CleanupTriggeredSpells(); + + Unit* caster = GetCaster(); + + if(caster && IsPersistent()) + { + DynamicObject *dynObj = caster->GetDynObject(GetId()); + if (dynObj) + dynObj->RemoveAffected(m_target); + } + + //passive auras do not get put in slots - said who? ;) + // Note: but totem can be not accessible for aura target in time remove (to far for find in grid) + //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) + // return; + + uint8 slot = GetAuraSlot(); + + if(slot >= MAX_AURAS) // slot not set + return; + + if(m_target->GetVisibleAura(slot) == 0) + return; + + // unregister aura diminishing (and store last time) + if (getDiminishGroup() != DIMINISHING_NONE ) + m_target->ApplyDiminishingAura(getDiminishGroup(), false); + + SetAuraFlags(AFLAG_NONE); + SetAuraLevel(0); + SetVisibleAura(true); + + if (m_removeMode != AURA_REMOVE_BY_DELETE) + { + SendAuraUpdate(true); + + // update for out of range group members + m_target->UpdateAuraForGroup(slot); + + //***************************************************** + // Update target aura state flag (at last aura remove) + //***************************************************** + // Enrage aura state + if(m_spellProto->Dispel == DISPEL_ENRAGE) + m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); + + uint32 removeState = 0; + uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags; + uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2; + switch(m_spellProto->SpellFamilyName) + { + case SPELLFAMILY_PALADIN: + if (IsSealSpell(m_spellProto)) + removeState = AURA_STATE_JUDGEMENT; // Update Seals information + break; + case SPELLFAMILY_WARLOCK: + // Conflagrate aura state on Immolate and Shadowflame, + if ((m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) || + (m_spellProto->SpellFamilyFlags2 & 0x00000002)) + { + removeFamilyFlag = UI64LIT(0x0000000000000004); + removeFamilyFlag2 = 0x00000002; + removeState = AURA_STATE_CONFLAGRATE; + } + break; + case SPELLFAMILY_DRUID: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000400)) + removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) + else if(m_spellProto->SpellFamilyFlags & UI64LIT(0x50)) + { + removeFamilyFlag = 0x50; + removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state + } + break; + case SPELLFAMILY_WARRIOR: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0004000000000000)) + removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious + break; + case SPELLFAMILY_ROGUE: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x10000)) + removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state + break; + case SPELLFAMILY_HUNTER: + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) + removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) + } + + // Remove state (but need check other auras for it) + if (removeState) + { + bool found = false; + Unit::SpellAuraHolderMap const& holders = m_target->GetSpellAuraHolderMap(); + for (Unit::SpellAuraHolderMap::const_iterator i = holders.begin(); i != holders.end(); ++i) + { + SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); + if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && + (auraSpellInfo->SpellFamilyFlags & removeFamilyFlag || auraSpellInfo->SpellFamilyFlags2 & removeFamilyFlag2)) + { + found = true; + break; + } + } + // this was last holder + if(!found) + m_target->ModifyAuraState(AuraState(removeState), false); + } + + // reset cooldown state for spells + if(caster && caster->GetTypeId() == TYPEID_PLAYER) + { + if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE ) + // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) + ((Player*)caster)->SendCooldownEvent(GetSpellProto()); + } + } +} + +void SpellAuraHolder::CleanupTriggeredSpells() +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (!m_auras[i]) + continue; + + uint32 tSpellId = m_spellProto->EffectTriggerSpell[i]; + if(!tSpellId) + continue; + + SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId); + if(!tProto) + continue; + + if(GetSpellDuration(tProto) != -1) + continue; + + // needed for spell 43680, maybe others + // TODO: is there a spell flag, which can solve this in a more sophisticated way? + if(m_spellProto->EffectApplyAuraName[i] == SPELL_AURA_PERIODIC_TRIGGER_SPELL && + GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[i]) + continue; + + m_target->RemoveAurasDueToSpell(tSpellId); + } +} + +bool SpellAuraHolder::ModStackAmount(int32 num) +{ + // Can`t mod + if (!m_spellProto->StackAmount) + return true; + + // Modify stack but limit it + int32 stackAmount = m_stackAmount + num; + if (stackAmount > (int32)m_spellProto->StackAmount) + stackAmount = m_spellProto->StackAmount; + else if (stackAmount <=0) // Last aura from stack removed + { + m_stackAmount = 0; + return true; // need remove aura + } + + // Update stack amount + SetStackAmount(stackAmount); + return false; +} + +void SpellAuraHolder::SetStackAmount(uint8 stackAmount) +{ + Unit *target = GetTarget(); + Unit *caster = GetCaster(); + if (!target || !caster) + return; + + bool refresh = stackAmount >= m_stackAmount; + if (stackAmount != m_stackAmount) + { + m_stackAmount = stackAmount; + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aur = m_auras[i]) + { + int32 bp = aur->GetBasePoints(); + int32 amount = m_stackAmount * caster->CalculateSpellDamage(target, m_spellProto, SpellEffectIndex(i), &bp); + // Reapply if amount change + if (amount != aur->GetModifier()->m_amount) + { + aur->ApplyModifier(false, true); + aur->GetModifier()->m_amount = amount; + aur->ApplyModifier(true, true); + } + } + } + } + + if (refresh) + // Stack increased refresh duration + RefreshHolder(); + else + // Stack decreased only send update + SendAuraUpdate(false); +} + +Unit* SpellAuraHolder::GetCaster() const +{ + if(m_caster_guid == m_target->GetGUID()) + return m_target; + + //return ObjectAccessor::GetUnit(*m_target,m_caster_guid); + //must return caster even if it's in another grid/map + Unit *unit = ObjectAccessor::GetUnitInWorld(*m_target,m_caster_guid); + return unit && unit->IsInWorld() ? unit : NULL; +} + +bool SpellAuraHolder::IsWeaponBuffCoexistableWith(SpellAuraHolder* ref) +{ + // Exclude Debuffs + if (!IsPositive()) + return false; + + // Exclude Non-generic Buffs [ie: Runeforging] and Executioner-Enchant + if (GetSpellProto()->SpellFamilyName != SPELLFAMILY_GENERIC || GetId() == 42976) + return false; + + // Exclude Stackable Buffs [ie: Blood Reserve] + if (GetSpellProto()->StackAmount) + return false; + + // only self applied player buffs + if (m_target->GetTypeId() != TYPEID_PLAYER || m_target->GetGUID() != GetCasterGUID()) + return false; + + Item* castItem = ((Player*)m_target)->GetItemByGuid(GetCastItemGUID()); + if (!castItem) + return false; + + // Limit to Weapon-Slots + if (!castItem->IsEquipped() || + (castItem->GetSlot() != EQUIPMENT_SLOT_MAINHAND && castItem->GetSlot() != EQUIPMENT_SLOT_OFFHAND)) + return false; + + // form different weapons + return ref->GetCastItemGUID() != GetCastItemGUID(); +} + +bool SpellAuraHolder::IsNeedVisibleSlot(Unit const* caster) const +{ + bool totemAura = caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem(); + + if (m_spellProto->procFlags) + return true; + else if (HasAuraWithTriggerEffect(m_spellProto)) + return true; + else if (IsSpellHaveAura(m_spellProto, SPELL_AURA_MOD_IGNORE_SHAPESHIFT)) + return true; + else if (IsSpellHaveAura(m_spellProto, SPELL_AURA_262)) + return true; + + // passive auras (except totem auras) do not get placed in the slots + return !m_isPassive || totemAura || HasAreaAuraEffect(m_spellProto); +} + +void SpellAuraHolder::SendAuraUpdate(bool remove) +{ + WorldPacket data(SMSG_AURA_UPDATE); + data << m_target->GetPackGUID(); + data << uint8(GetAuraSlot()); + data << uint32(remove ? 0 : GetId()); + + if(remove) + { + m_target->SendMessageToSet(&data, true); + return; + } + + uint8 auraFlags = GetAuraFlags(); + data << uint8(auraFlags); + data << uint8(GetAuraLevel()); + data << uint8(m_procCharges ? m_procCharges*m_stackAmount : m_stackAmount); + + if(!(auraFlags & AFLAG_NOT_CASTER)) + { + data.appendPackGUID(GetCasterGUID()); + } + + if(auraFlags & AFLAG_DURATION) + { + // take highest - to display icon even if stun fades + uint32 max_duration = 0; + uint32 duration = 0; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aura = m_auras[i]) + { + if (uint32(aura->GetAuraMaxDuration()) > max_duration) + { + max_duration = aura->GetAuraMaxDuration(); + duration = aura->GetAuraDuration(); + } + } + } + + data << uint32(max_duration); + data << uint32(duration); + } + + m_target->SendMessageToSet(&data, true); +} + +void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply) +{ + bool cast_at_remove = false; // if spell must be casted at last aura from stack remove + uint32 spellId1 = 0; + uint32 spellId2 = 0; + uint32 spellId3 = 0; + uint32 spellId4 = 0; + + switch(GetSpellProto()->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + // Illusionary Barrier + if(GetId() == 57350 && !apply && m_target->getPowerType() == POWER_MANA) + { + cast_at_remove = true; + spellId1 = 60242; // Darkmoon Card: Illusion + } + else + return; + break; + } + case SPELLFAMILY_MAGE: + { + // Ice Barrier (non stacking from one caster) + if (m_spellProto->SpellIconID == 32) + { + if (!apply && m_removeMode == AURA_REMOVE_BY_DISPEL || m_removeMode == AURA_REMOVE_BY_SHIELD_BREAK) + { + Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + // Shattered Barrier + if ((*itr)->GetSpellProto()->SpellIconID == 2945) + { + cast_at_remove = true; + // first rank have 50% chance + if ((*itr)->GetId() != 44745 || roll_chance_i(50)) + spellId1 = 55080; + break; + } + } + } + else + return; + break; + } + + switch(GetId()) + { + case 11129: // Combustion (remove triggered aura stack) + { + if(!apply) + spellId1 = 28682; + else + return; + break; + } + case 28682: // Combustion (remove main aura) + { + if(!apply) + spellId1 = 11129; + else + return; + break; + } + case 44401: // Missile Barrage (triggered) + case 48108: // Hot Streak (triggered) + case 57761: // Fireball! (Brain Freeze triggered) + { + // consumed aura + if (!apply && m_removeMode != AURA_REMOVE_BY_EXPIRE) + { + Unit* caster = GetCaster(); + // Item - Mage T10 2P Bonus + if (!caster || !caster->HasAura(70752)) + return; + + cast_at_remove = true; + spellId1 = 70753; // Pushing the Limit + } + else + return; + break; + } + default: + return; + } + break; + } + case SPELLFAMILY_WARRIOR: + { + if(!apply) + { + // Remove Blood Frenzy only if target no longer has any Deep Wound or Rend (applying is handled by procs) + if (GetSpellProto()->Mechanic != MECHANIC_BLEED) + return; + + // If target still has one of Warrior's bleeds, do nothing + Unit::AuraList const& PeriodicDamage = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(Unit::AuraList::const_iterator i = PeriodicDamage.begin(); i != PeriodicDamage.end(); ++i) + if( (*i)->GetCasterGUID() == GetCasterGUID() && + (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARRIOR && + (*i)->GetSpellProto()->Mechanic == MECHANIC_BLEED) + return; + + spellId1 = 30069; // Blood Frenzy (Rank 1) + spellId2 = 30070; // Blood Frenzy (Rank 2) + } + break; + } + case SPELLFAMILY_WARLOCK: + { + // Fear (non stacking) + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + { + if(!apply) + { + Unit* caster = GetCaster(); + if(!caster) + return; + + Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); + // Improved Fear + if (dummyEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && dummyEntry->SpellIconID == 98) + { + cast_at_remove = true; + switch((*itr)->GetModifier()->m_amount) + { + // Rank 1 + case 0: spellId1 = 60946; break; + // Rank 1 + case 1: spellId1 = 60947; break; + } + break; + } + } + } + else + return; + } + // Shadowflame (DoT) + else if (m_spellProto->SpellFamilyFlags2 & 0x00000002) + { + // Glyph of Shadowflame + Unit* caster; + if(!apply) + spellId1 = 63311; + else if(((caster = GetCaster())) && caster->HasAura(63310)) + spellId1 = 63311; + else + return; + } + else + return; + break; + } + case SPELLFAMILY_PRIEST: + { + // Shadow Word: Pain (need visual check fro skip improvement talent) or Vampiric Touch + if (m_spellProto->SpellIconID == 234 && m_spellProto->SpellVisual[0] || m_spellProto->SpellIconID == 2213) + { + if (!apply && m_removeMode == AURA_REMOVE_BY_DISPEL) + { + Unit* caster = GetCaster(); + if(!caster) + return; + + Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + // Shadow Affinity + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST + && (*itr)->GetSpellProto()->SpellIconID == 178) + { + // custom cast code + int32 basepoints0 = (*itr)->GetModifier()->m_amount * caster->GetCreateMana() / 100; + caster->CastCustomSpell(caster, 64103, &basepoints0, NULL, NULL, true, NULL); + return; + } + } + } + else + return; + } + // Power Word: Shield + else if (apply && m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001) && m_spellProto->Mechanic == MECHANIC_SHIELD) + { + Unit* caster = GetCaster(); + if(!caster) + return; + + // Glyph of Power Word: Shield + if (Aura* glyph = caster->GetAura(55672, EFFECT_INDEX_0)) + { + Aura *shield = GetAuraByEffectIndex(EFFECT_INDEX_0); + int32 heal = (glyph->GetModifier()->m_amount * shield->GetModifier()->m_amount)/100; + caster->CastCustomSpell(m_target, 56160, &heal, NULL, NULL, true, 0, shield); + } + return; + } + + switch(GetId()) + { + // Abolish Disease (remove 1 more poison effect with Body and Soul) + case 552: + { + if(apply) + { + int chance =0; + Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); + // Body and Soul (talent ranks) + if (dummyEntry->SpellFamilyName == SPELLFAMILY_PRIEST && dummyEntry->SpellIconID == 2218 && + dummyEntry->SpellVisual[0]==0) + { + chance = (*itr)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_1); + break; + } + } + + if(roll_chance_i(chance)) + spellId1 = 64134; // Body and Soul (periodic dispel effect) + } + else + spellId1 = 64134; // Body and Soul (periodic dispel effect) + break; + } + // Dispersion mana reg and immunity + case 47585: + spellId1 = 60069; // Dispersion + spellId2 = 63230; // Dispersion + break; + default: + return; + } + break; + } + case SPELLFAMILY_DRUID: + { + // Barkskin + if (GetId()==22812 && m_target->HasAura(63057)) // Glyph of Barkskin + spellId1 = 63058; // Glyph - Barkskin 01 + else + return; + break; + } + case SPELLFAMILY_ROGUE: + // Sprint (skip non player casted spells by category) + if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000040) && GetSpellProto()->Category == 44) + { + if(!apply || m_target->HasAura(58039)) // Glyph of Blurred Speed + spellId1 = 61922; // Sprint (waterwalk) + else + return; + } + else + return; + break; + case SPELLFAMILY_HUNTER: + { + // The Beast Within and Bestial Wrath - immunity + if (GetId() == 19574 || GetId() == 34471) + { + spellId1 = 24395; + spellId2 = 24396; + spellId3 = 24397; + spellId4 = 26592; + } + // Freezing Trap Effect + else if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000008)) + { + if(!apply) + { + Unit *caster = GetCaster(); + // Glyph of Freezing Trap + if (caster && caster->HasAura(56845)) + { + cast_at_remove = true; + spellId1 = 61394; + } + else + return; + } + else + return; + } + // Aspect of the Dragonhawk dodge + else if (GetSpellProto()->SpellFamilyFlags2 & 0x00001000) + { + spellId1 = 61848; + + // triggered spell have same category as main spell and cooldown + if (apply && m_target->GetTypeId()==TYPEID_PLAYER) + ((Player*)m_target)->RemoveSpellCooldown(61848); + } + else + return; + break; + } + case SPELLFAMILY_PALADIN: + { + if (m_spellProto->Id == 31884) // Avenging Wrath + { + if(!apply) + spellId1 = 57318; // Sanctified Wrath (triggered) + else + { + int32 percent = 0; + Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); itr) + { + if ((*itr)->GetSpellProto()->SpellIconID == 3029) + { + percent = (*itr)->GetModifier()->m_amount; + break; + } + } + + // apply in special way + if(percent) + { + spellId1 = 57318; // Sanctified Wrath (triggered) + // prevent aura deletion, specially in multi-boost case + SetInUse(true); + m_target->CastCustomSpell(m_target, spellId1, &percent, &percent, NULL, true, NULL); + SetInUse(false); + } + return; + } + break; + } + + // Only process on player casting paladin aura + // all aura bonuses applied also in aura area effect way to caster + if (GetCasterGUID() != m_target->GetGUID() || !IS_PLAYER_GUID(GetCasterGUID())) + return; + + if (GetSpellSpecific(m_spellProto->Id) != SPELL_AURA) + return; + + // Sanctified Retribution and Swift Retribution (they share one aura), but not Retribution Aura (already gets modded) + if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000008))==0) + spellId1 = 63531; // placeholder for talent spell mods + // Improved Concentration Aura (auras bonus) + spellId2 = 63510; // placeholder for talent spell mods + // Improved Devotion Aura (auras bonus) + spellId3 = 63514; // placeholder for talent spell mods + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // second part of spell apply + switch (GetId()) + { + case 49039: spellId1 = 50397; break; // Lichborne + + case 48263: // Frost Presence + case 48265: // Unholy Presence + case 48266: // Blood Presence + { + // else part one per 3 pair + if (GetId()==48263 || GetId()==48265) // Frost Presence or Unholy Presence + { + // Improved Blood Presence + int32 heal_pct = 0; + if (apply) + { + Unit::AuraList const& bloodAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = bloodAuras.begin(); itr != bloodAuras.end(); ++itr) + { + // skip same icon + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2636) + { + heal_pct = (*itr)->GetModifier()->m_amount; + break; + } + } + } + + if (heal_pct) + m_target->CastCustomSpell(m_target, 63611, &heal_pct, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + else + m_target->RemoveAurasDueToSpell(63611); + } + else + spellId1 = 63611; // Improved Blood Presence, trigger for heal + + if (GetId()==48263 || GetId()==48266) // Frost Presence or Blood Presence + { + // Improved Unholy Presence + int32 power_pct = 0; + if (apply) + { + Unit::AuraList const& unholyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = unholyAuras.begin(); itr != unholyAuras.end(); ++itr) + { + // skip same icon + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2633) + { + power_pct = (*itr)->GetModifier()->m_amount; + break; + } + } + } + if (power_pct || !apply) + spellId2 = 49772; // Unholy Presence, speed part, spell1 used for Improvement presence fit to own presence + } + else + spellId1 = 49772; // Unholy Presence move speed + + if (GetId()==48265 || GetId()==48266) // Unholy Presence or Blood Presence + { + // Improved Frost Presence + int32 stamina_pct = 0; + if (apply) + { + Unit::AuraList const& frostAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = frostAuras.begin(); itr != frostAuras.end(); ++itr) + { + // skip same icon + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2632) + { + stamina_pct = (*itr)->GetModifier()->m_amount; + break; + } + } + } + + if (stamina_pct) + m_target->CastCustomSpell(m_target, 61261, &stamina_pct, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + else + m_target->RemoveAurasDueToSpell(61261); + } + else + spellId1 = 61261; // Frost Presence, stamina + + if (GetId()==48265) // Unholy Presence + { + // Improved Unholy Presence, special case for own presence + int32 power_pct = 0; + if (apply) + { + Unit::AuraList const& unholyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = unholyAuras.begin(); itr != unholyAuras.end(); ++itr) + { + // skip same icon + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && + (*itr)->GetSpellProto()->SpellIconID == 2633) + { + power_pct = (*itr)->GetModifier()->m_amount; + break; + } + } + } + + if (power_pct) + { + int32 bp = 5; + m_target->CastCustomSpell(m_target, 63622, &bp, &bp, &bp, true, NULL, NULL, GetCasterGUID()); + m_target->CastCustomSpell(m_target, 65095, &bp, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + } + else + { + m_target->RemoveAurasDueToSpell(63622); + m_target->RemoveAurasDueToSpell(65095); + } + } + break; + } + } + + // Improved Blood Presence + if (GetSpellProto()->SpellIconID == 2636 && m_isPassive) + { + // if presence active: Frost Presence or Unholy Presence + if (apply && (m_target->HasAura(48263) || m_target->HasAura(48265))) + { + Aura* aura = GetAuraByEffectIndex(EFFECT_INDEX_0); + if (!aura) + return; + + int32 bp = aura->GetModifier()->m_amount; + m_target->CastCustomSpell(m_target, 63611, &bp, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + } + else + m_target->RemoveAurasDueToSpell(63611); + return; + } + + // Improved Frost Presence + if (GetSpellProto()->SpellIconID == 2632 && m_isPassive) + { + // if presence active: Unholy Presence or Blood Presence + if (apply && (m_target->HasAura(48265) || m_target->HasAura(48266))) + { + Aura* aura = GetAuraByEffectIndex(EFFECT_INDEX_0); + if (!aura) + return; + + int32 bp = aura->GetModifier()->m_amount; + m_target->CastCustomSpell(m_target, 61261, &bp, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + } + else + m_target->RemoveAurasDueToSpell(61261); + return; + } + + // Improved Unholy Presence + if (GetSpellProto()->SpellIconID == 2633 && m_isPassive) + { + // if presence active: Unholy Presence + if (apply && m_target->HasAura(48265)) + { + int32 bp = 5; + m_target->CastCustomSpell(m_target, 63622, &bp, &bp, &bp, true, NULL, NULL, GetCasterGUID()); + m_target->CastCustomSpell(m_target, 65095, &bp, NULL, NULL, true, NULL, NULL, GetCasterGUID()); + } + else + { + m_target->RemoveAurasDueToSpell(63622); + m_target->RemoveAurasDueToSpell(65095); + } + + // if presence active: Frost Presence or Blood Presence + if (!apply || m_target->HasAura(48263) || m_target->HasAura(48266)) + spellId1 = 49772; + else + return; + break; + } + break; + } + default: + return; + } + + // prevent aura deletion, specially in multi-boost case + SetInUse(true); + + if (apply || cast_at_remove) + { + if (spellId1) + m_target->CastSpell(m_target, spellId1, true, NULL, NULL, GetCasterGUID()); + if (spellId2 && !IsDeleted()) + m_target->CastSpell(m_target, spellId1, true, NULL, NULL, GetCasterGUID()); + if (spellId3 && !IsDeleted()) + m_target->CastSpell(m_target, spellId1, true, NULL, NULL, GetCasterGUID()); + if (spellId4 && !IsDeleted()) + m_target->CastSpell(m_target, spellId1, true, NULL, NULL, GetCasterGUID()); + } + else + { + if (spellId1) + m_target->RemoveAurasByCasterSpell(spellId1, GetCasterGUID()); + if (spellId2) + m_target->RemoveAurasByCasterSpell(spellId2, GetCasterGUID()); + if (spellId3) + m_target->RemoveAurasByCasterSpell(spellId3, GetCasterGUID()); + if (spellId4) + m_target->RemoveAurasByCasterSpell(spellId4, GetCasterGUID()); + } + + SetInUse(false); +} + +SpellAuraHolder::~SpellAuraHolder() +{ + // note: auras in delete list won't be affected since they clear themselves from holder when adding to deletedAuraslist + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aur = m_auras[i]) + delete aur; +} + +void SpellAuraHolder::Update(uint32 diff) +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aura = m_auras[i]) + aura->UpdateAura(diff); + + // Channeled aura required check distance from caster + if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID()) + { + Unit* caster = GetCaster(); + if(!caster) + { + m_target->RemoveAurasByCasterSpell(GetId(), GetCasterGUID()); + return; + } + + // need check distance for channeled target only + if (caster->GetChannelObjectGUID() == m_target->GetGUID()) + { + // Get spell range + float max_range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)); + + if(Player* modOwner = caster->GetSpellModOwner()) + modOwner->ApplySpellMod(GetId(), SPELLMOD_RANGE, max_range, NULL); + + if(!caster->IsWithinDistInMap(m_target, max_range)) + { + m_target->RemoveAurasByCasterSpell(GetId(), GetCasterGUID()); + return; + } + } + } +} + +void SpellAuraHolder::RefreshHolder() +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aura = m_auras[i]) + aura->SetAuraDuration(aura->GetAuraMaxDuration()); + + SendAuraUpdate(false); +} + +bool SpellAuraHolder::HasAuraAndMechanicEffect(uint32 mechanic) const +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (m_auras[i] && m_spellProto->EffectMechanic[i] == mechanic) + return true; + return false; +} + +bool SpellAuraHolder::HasAuraAndMechanicEffectMask(uint32 mechanicMask) const +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (m_auras[i] && m_spellProto->EffectMechanic[i] & mechanicMask) + return true; + return false; +} + +bool SpellAuraHolder::IsPersistent() const +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aur = m_auras[i]) + if (aur->IsPersistent()) + return true; + return false; +} + +bool SpellAuraHolder::IsPositive() const +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aur = m_auras[i]) + if (!aur->IsPositive()) + return false; + return true; +} + +bool SpellAuraHolder::IsEmptyHolder() const +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aur = m_auras[i]) + return false; + return true; +} + +void SpellAuraHolder::UnregisterSingleCastHolder() +{ + if (IsSingleTarget()) + { + if(Unit* caster = GetCaster()) + { + caster->GetSingleCastSpellAuraHolders().remove(this); + } + else + { + sLog.outError("Couldn't find the caster of the single target aura (SpellId %u), may crash later!", GetId()); + ASSERT(false); + } + m_isSingleTarget = false; } } \ No newline at end of file diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 89918a8a8..22dffa7f2 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -40,6 +40,150 @@ class Aura; // internal helper struct ReapplyAffectedPassiveAurasHelper; +class MANGOS_DLL_SPEC SpellAuraHolder +{ + public: + SpellAuraHolder (SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem); + Aura* m_auras[MAX_EFFECT_INDEX]; + + void AddAura(Aura *aura, SpellEffectIndex index); + void RemoveAura(SpellEffectIndex index); + void ApplyAuraModifiers(bool apply, bool real = false); + void _AddSpellAuraHolder(); + void _RemoveSpellAuraHolder(); + void SendAuraUpdate(bool remove); + void HandleSpellSpecificBoosts(bool apply); + void CleanupTriggeredSpells(); + + void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; } + DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; } + + uint8 GetStackAmount() { return m_stackAmount; } + void SetStackAmount(uint8 stackAmount); + bool ModStackAmount(int32 num); // return true if last charge dropped + + Aura* GetAuraByEffectIndex(SpellEffectIndex index) const + { + if (Aura *aur = m_auras[index]) + return aur; + else + return NULL; + } + + uint32 GetId() const { return m_spellProto->Id; } + SpellEntry const* GetSpellProto() const { return m_spellProto; } + + uint64 const& GetCasterGUID() const { return m_caster_guid; } + void SetCasterGUID(uint64 guid) { m_caster_guid = guid; } + uint64 GetCastItemGUID() const { return m_castItemGuid; } + Unit* GetCaster() const; + Unit* GetTarget() const { return m_target; } + void SetTarget(Unit* target) { m_target = target; } + + bool IsPermanent() const { return m_permanent; } + void SetPermanent (bool permanent) { m_permanent = permanent; } + bool IsPassive() const { return m_isPassive; } + bool IsDeathPersistent() const { return m_isDeathPersist; } + bool IsPersistent() const; + bool IsPositive() const; + bool IsWeaponBuffCoexistableWith(SpellAuraHolder* ref); + bool IsNeedVisibleSlot(Unit const* caster) const; + bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; } + bool IsInUse() const { return m_in_use;} + bool IsDeleted() const { return m_deleted;} + bool IsEmptyHolder() const; + + void SetInUse(bool state) + { + if(state) + ++m_in_use; + else + { + if(m_in_use) + --m_in_use; + } + } + + void UpdateHolder(uint32 diff) { SetInUse(true); Update(diff); SetInUse(false); } + void Update(uint32 diff); + void RefreshHolder(); + + bool IsSingleTarget() {return m_isSingleTarget; } + void SetIsSingleTarget(bool val) { m_isSingleTarget = val; } + void UnregisterSingleCastHolder(); + + uint8 GetAuraSlot() const { return m_auraSlot; } + void SetAuraSlot(uint8 slot) { m_auraSlot = slot; } + uint8 GetAuraFlags() const { return m_auraFlags; } + void SetAuraFlags(uint8 flags) { m_auraFlags = flags; } + uint8 GetAuraLevel() const { return m_auraLevel; } + void SetAuraLevel(uint8 level) { m_auraLevel = level; } + uint8 GetAuraCharges() const { return m_procCharges; } + void SetAuraCharges(uint8 charges) + { + if (m_procCharges == charges) + return; + m_procCharges = charges; + SendAuraUpdate(false); + } + bool DropAuraCharge() // return true if last charge dropped + { + if (m_procCharges == 0) + return false; + + // exist spells that have maxStack > 1 and m_procCharges > 0 (==1 in fact) + // all like stacks have 1 value in one from this fields + // so return true for allow remove one aura from stacks as expired + if (GetStackAmount() > 1) + return true; + + m_procCharges--; + SendAuraUpdate(false); + return m_procCharges == 0; + } + + time_t GetAuraApplyTime() const { return m_applyTime; } + + void SetVisibleAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); } + void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; } + void SetLoadedState(uint64 casterGUID, int32 stackAmount, int32 charges) + { + m_caster_guid = casterGUID; + m_procCharges = charges; + m_stackAmount = stackAmount; + } + + bool HasAuraAndMechanicEffect(uint32 mechanic) const; + bool HasAuraAndMechanicEffectMask(uint32 mechanicMask) const; + + ~SpellAuraHolder(); + private: + Unit* m_target; + uint64 m_caster_guid; + uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted + time_t m_applyTime; + + SpellEntry const* m_spellProto; + + uint8 m_auraSlot; // Aura slot on unit (for show in client) + uint8 m_auraFlags; // Aura info flag (for send data to client) + uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount) + uint8 m_procCharges; // Aura charges (0 for infinite) + uint8 m_stackAmount; // Aura stack amount + + AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason + DiminishingGroup m_AuraDRGroup:8; // Diminishing + + bool m_permanent:1; + bool m_isPassive:1; + bool m_isDeathPersist:1; + bool m_isRemovedOnShapeLost:1; + bool m_isSingleTarget:1; // true if it's a single target spell and registered at caster - can change at spell steal for example + bool m_deleted:1; + + uint32 m_in_use; // > 0 while in SpellAuraHolder::ApplyModifiers call/SpellAuraHolder::Update/etc +}; + typedef void(Aura::*pAuraHandler)(bool Apply, bool Real); // Real == true at aura add/remove // Real == false at aura mod unapply/reapply; when adding/removing dependent aura/item/stat mods @@ -57,7 +201,7 @@ typedef void(Aura::*pAuraHandler)(bool Apply, bool Real); class MANGOS_DLL_SPEC Aura { friend struct ReapplyAffectedPassiveAurasHelper; - friend Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem); + friend Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster, Item* castItem); public: //aura handlers @@ -226,12 +370,16 @@ class MANGOS_DLL_SPEC Aura void SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue); Modifier* GetModifier() { return &m_modifier; } Modifier const* GetModifier() const { return &m_modifier; } - int32 GetMiscValue() const { return m_spellProto->EffectMiscValue[m_effIndex]; } - int32 GetMiscBValue() const { return m_spellProto->EffectMiscValueB[m_effIndex]; } + int32 GetMiscValue() const { return m_spellAuraHolder->GetSpellProto()->EffectMiscValue[m_effIndex]; } + int32 GetMiscBValue() const { return m_spellAuraHolder->GetSpellProto()->EffectMiscValueB[m_effIndex]; } + + SpellEntry const* GetSpellProto() const { return GetHolder()->GetSpellProto(); } + uint32 GetId() const{ return GetHolder()->GetSpellProto()->Id; } + uint64 GetCastItemGUID() const { return GetHolder()->GetCastItemGUID(); } + uint64 const& GetCasterGUID() const { return GetHolder()->GetCasterGUID(); } + Unit* GetCaster() const { return GetHolder()->GetCaster(); } + Unit* GetTarget() const { return GetHolder()->GetTarget(); } - SpellEntry const* GetSpellProto() const { return m_spellProto; } - uint32 GetId() const{ return m_spellProto->Id; } - uint64 GetCastItemGUID() const { return m_castItemGuid; } SpellEffectIndex GetEffIndex() const{ return m_effIndex; } int32 GetBasePoints() const { return m_currentBasePoints; } @@ -242,76 +390,23 @@ class MANGOS_DLL_SPEC Aura time_t GetAuraApplyTime() const { return m_applyTime; } uint32 GetAuraTicks() const { return m_periodicTick; } uint32 GetAuraMaxTicks() const { return m_maxduration > 0 && m_modifier.periodictime > 0 ? m_maxduration / m_modifier.periodictime : 0; } + uint8 GetStackAmount() const { return GetHolder()->GetStackAmount(); } - uint64 const& GetCasterGUID() const { return m_caster_guid; } - Unit* GetCaster() const; - Unit* GetTarget() const { return m_target; } - void SetTarget(Unit* target) { m_target = target; } - void SetLoadedState(uint64 caster_guid,int32 damage,int32 maxduration,int32 duration,int32 charges) + void SetLoadedState(int32 damage,int32 maxduration,int32 duration) { - m_caster_guid = caster_guid; m_modifier.m_amount = damage; SetAuraMaxDuration(maxduration); SetAuraDuration(duration); - m_procCharges = charges; - if(uint32 maxticks = GetAuraMaxTicks()) m_periodicTick = maxticks - m_duration / m_modifier.periodictime; } - uint8 GetAuraSlot() const { return m_auraSlot; } - void SetAuraSlot(uint8 slot) { m_auraSlot = slot; } - uint8 GetAuraFlags() const { return m_auraFlags; } - void SetAuraFlags(uint8 flags) { m_auraFlags = flags; } - uint8 GetAuraLevel() const { return m_auraLevel; } - void SetAuraLevel(uint8 level) { m_auraLevel = level; } - uint8 GetAuraCharges() const { return m_procCharges; } - void SetAuraCharges(uint8 charges) - { - if (m_procCharges == charges) - return; - m_procCharges = charges; - SendAuraUpdate(false); - } - bool DropAuraCharge() // return true if last charge dropped - { - if (m_procCharges == 0) - return false; - - // exist spells that have maxStack > 1 and m_procCharges > 0 (==1 in fact) - // all like stacks have 1 value in one from this fields - // so return true for allow remove one aura from stacks as expired - if (GetStackAmount() > 1) - return true; - - m_procCharges--; - SendAuraUpdate(false); - return m_procCharges == 0; - } - - void UnregisterSingleCastAura(); - - void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); } - void SendAuraUpdate(bool remove); - - uint8 GetStackAmount() {return m_stackAmount;} - void SetStackAmount(uint8 num); - bool modStackAmount(int32 num); // return true if last charge dropped - void RefreshAura(); - bool IsPositive() { return m_positive; } - void SetNegative() { m_positive = false; } - void SetPositive() { m_positive = true; } - - bool IsPermanent() const { return m_permanent; } + bool IsPersistent() const { return m_isPersistent; } bool IsAreaAura() const { return m_isAreaAura; } bool IsPeriodic() const { return m_isPeriodic; } - bool IsPassive() const { return m_isPassive; } - bool IsPersistent() const { return m_isPersistent; } - bool IsDeathPersistent() const { return m_isDeathPersist; } - bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; } - bool IsInUse() const { return m_in_use;} - bool IsDeleted() const { return m_deleted;} + bool IsInUse() const { return m_in_use; } + bool IsDeleted() const { return m_deleted; } void SetInUse(bool state) { @@ -329,29 +424,26 @@ class MANGOS_DLL_SPEC Aura void _AddAura(); bool _RemoveAura(); - bool IsSingleTarget() {return m_isSingleTargetAura;} - void SetIsSingleTarget(bool val) { m_isSingleTargetAura = val;} - void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; } - virtual Unit* GetTriggerTarget() const { return m_target; } + virtual Unit* GetTriggerTarget() const { return m_spellAuraHolder->GetTarget(); } // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras void HandleShapeshiftBoosts(bool apply); - void HandleSpellSpecificBoosts(bool apply); - - // Allow Apply Aura Handler to modify and access m_AuraDRGroup - void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; } - DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; } void TriggerSpell(); void TriggerSpellWithValue(); - uint32 const *getAuraSpellClassMask() const { return m_spellProto->GetEffectSpellClassMask(m_effIndex); } + uint32 const *getAuraSpellClassMask() const { return m_spellAuraHolder->GetSpellProto()->GetEffectSpellClassMask(m_effIndex); } bool isAffectedOnSpell(SpellEntry const *spell) const; - bool isWeaponBuffCoexistableWith(Aura* ref); + + //SpellAuraHolder const* GetHolder() const { return m_spellHolder; } + SpellAuraHolder* GetHolder() { return m_spellAuraHolder; } + SpellAuraHolder* const GetHolder() const { return m_spellAuraHolder; } + + bool IsLastAuraOnHolder(); protected: - Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster = NULL, Item* castItem = NULL); // must be called only from Aura::UpdateAura virtual void Update(uint32 diff); @@ -366,10 +458,6 @@ class MANGOS_DLL_SPEC Aura Modifier m_modifier; SpellModifier *m_spellmod; - SpellEntry const *m_spellProto; - Unit* m_target; - uint64 m_caster_guid; - uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted time_t m_applyTime; int32 m_currentBasePoints; // cache SpellEntry::CalculateSimpleValue and use for set custom base points @@ -380,27 +468,18 @@ class MANGOS_DLL_SPEC Aura uint32 m_periodicTick; // Tick count pass (including current if use in tick code) from aura apply, used for some tick count dependent aura effects AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason - DiminishingGroup m_AuraDRGroup:8; // Diminishing SpellEffectIndex m_effIndex :8; // Aura effect index in spell - uint8 m_auraSlot; // Aura slot on unit (for show in client) - uint8 m_auraFlags; // Aura info flag (for send data to client) - uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount) - uint8 m_procCharges; // Aura charges (0 for infinite) - uint8 m_stackAmount; // Aura stack amount - + bool m_positive:1; - bool m_permanent:1; bool m_isPeriodic:1; bool m_isAreaAura:1; - bool m_isPassive:1; - bool m_isPersistent:1; - bool m_isDeathPersist:1; - bool m_isRemovedOnShapeLost:1; bool m_deleted:1; // true if RemoveAura(iterator) called while in Aura::ApplyModifier call (added to Unit::m_deletedAuras) - bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example + bool m_isPersistent:1; uint32 m_in_use; // > 0 while in Aura::ApplyModifier call/Aura::Update/etc + + SpellAuraHolder* const m_spellAuraHolder; private: void CleanupTriggeredSpells(); bool IsNeedVisibleSlot(Unit const* caster) const; // helper for check req. visibility slot @@ -410,7 +489,7 @@ class MANGOS_DLL_SPEC Aura class MANGOS_DLL_SPEC AreaAura : public Aura { public: - AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster = NULL, Item* castItem = NULL); ~AreaAura(); protected: void Update(uint32 diff); @@ -422,7 +501,7 @@ class MANGOS_DLL_SPEC AreaAura : public Aura class MANGOS_DLL_SPEC PersistentAreaAura : public Aura { public: - PersistentAreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + PersistentAreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster = NULL, Item* castItem = NULL); ~PersistentAreaAura(); protected: void Update(uint32 diff); @@ -430,16 +509,17 @@ class MANGOS_DLL_SPEC PersistentAreaAura : public Aura class MANGOS_DLL_SPEC SingleEnemyTargetAura : public Aura { - friend Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem); + friend Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster, Item* castItem); public: ~SingleEnemyTargetAura(); Unit* GetTriggerTarget() const; protected: - SingleEnemyTargetAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + SingleEnemyTargetAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster = NULL, Item* castItem = NULL); uint64 m_casters_target_guid; }; -Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); +Aura* CreateAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster = NULL, Item* castItem = NULL); +SpellAuraHolder* CreateSpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem = NULL); #endif diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 9e7c57762..d697e4349 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -598,7 +598,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex effect_idx) if (needConsume) for (uint32 i = 0; i < doses; ++i) - unitTarget->RemoveSingleSpellAurasByCasterSpell(spellId, m_caster->GetGUID()); + unitTarget->RemoveSingleAuraHolderFromStack(spellId, m_caster->GetGUID()); damage *= doses; damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * doses); @@ -2460,12 +2460,11 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010)) { uint32 count = 0; - Unit::AuraMap const& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { if (itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && - itr->second->GetCasterGUID() == m_caster->GetGUID() && - IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex())) + itr->second->GetCasterGUID() == m_caster->GetGUID()) { ++count; // max. 15% @@ -2635,8 +2634,8 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex) // Cloak of Shadows case 35729: { - Unit::AuraMap& Auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter) + Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter) { // Remove all harmful spells on you except positive/passive/physical auras if (!iter->second->IsPositive() && @@ -2972,16 +2971,16 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx) DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[eff_idx]); - Aura* Aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], unitTarget, caster, m_CastItem); + Aura* Aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], spellAuraHolder, unitTarget, caster, m_CastItem); // Now Reduce spell duration using data received at spell hit int32 duration = Aur->GetAuraMaxDuration(); int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,m_spellInfo); unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel,limitduration); - Aur->setDiminishGroup(m_diminishGroup); + spellAuraHolder->setDiminishGroup(m_diminishGroup); // if Aura removed and deleted, do not continue. - if(duration== 0 && !(Aur->IsPermanent())) + if(duration== 0 && !(spellAuraHolder->IsPermanent())) { delete Aur; return; @@ -2993,7 +2992,7 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx) Aur->SetAuraDuration(duration); } - unitTarget->AddAura(Aur); + spellAuraHolder->AddAura(Aur, eff_idx); } void Spell::EffectUnlearnSpecialization(SpellEffectIndex eff_idx) @@ -3200,7 +3199,7 @@ void Spell::EffectHeal(SpellEffectIndex /*eff_idx*/) if (riptide) { addhealth += addhealth/4; - unitTarget->RemoveAura(riptide); + unitTarget->RemoveAurasDueToSpell(riptide->GetId()); } } } @@ -3506,8 +3505,8 @@ void Spell::EffectEnergize(SpellEffectIndex eff_idx) { // find elixirs on target uint32 elixir_mask = 0; - Unit::AuraMap& Auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr) + Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr) { uint32 spell_id = itr->second->GetId(); if(uint32 mask = sSpellMgr.GetSpellElixirMask(spell_id)) @@ -3801,8 +3800,8 @@ void Spell::EffectApplyAreaAura(SpellEffectIndex eff_idx) if (!unitTarget->isAlive()) return; - AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], unitTarget, m_caster, m_CastItem); - unitTarget->AddAura(Aur); + AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], spellAuraHolder, unitTarget, m_caster, m_CastItem); + spellAuraHolder->AddAura(Aur, eff_idx); } void Spell::EffectSummonType(SpellEffectIndex eff_idx) @@ -4044,33 +4043,31 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) return; // Fill possible dispell list - std::vector dispel_list; - + std::list > dispel_list; + // Create dispel mask by dispel type uint32 dispel_type = m_spellInfo->EffectMiscValue[eff_idx]; uint32 dispelMask = GetDispellMask( DispelType(dispel_type) ); - Unit::AuraMap const& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - Aura *aur = (*itr).second; - if (aur && (1<GetSpellProto()->Dispel) & dispelMask) + SpellAuraHolder *holder = itr->second; + if ((1<GetSpellProto()->Dispel) & dispelMask) { - if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC) + if(holder->GetSpellProto()->Dispel == DISPEL_MAGIC) { bool positive = true; - if (!aur->IsPositive()) + if (!holder->IsPositive()) positive = false; else - positive = (aur->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)==0; + positive = (holder->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)==0; // do not remove positive auras if friendly target // negative auras if non-friendly target if (positive == unitTarget->IsFriendlyTo(m_caster)) continue; } - // Add aura to dispel list (all stack cases) - for(int k = 0; k < aur->GetStackAmount(); ++k) - dispel_list.push_back(aur); + dispel_list.push_back(std::pair(holder, holder->GetStackAmount())); } } // Ok if exist some buffs for dispel try dispel it @@ -4087,20 +4084,23 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) for (int32 count=0; count < damage && !dispel_list.empty(); ++count) { // Random select buff for dispel - std::vector::iterator dispel_itr = dispel_list.begin(); + std::list>::iterator dispel_itr = dispel_list.begin(); std::advance(dispel_itr,urand(0, dispel_list.size()-1)); - Aura *aur = *dispel_itr; + SpellAuraHolder *holder = dispel_itr->first; - // remove entry from dispel_list - dispel_list.erase(dispel_itr); + dispel_itr->second -= 1; - SpellEntry const* spellInfo = aur->GetSpellProto(); + // remove entry from dispel_list if nothing left in stack + if (dispel_itr->second == 0) + dispel_list.erase(dispel_itr); + + SpellEntry const* spellInfo = holder->GetSpellProto(); // Base dispel chance // TODO: possible chance depend from spell level?? int32 miss_chance = 0; // Apply dispel mod from aura caster - if (Unit *caster = aur->GetCaster()) + if (Unit *caster = holder->GetCaster()) { if ( Player* modOwner = caster->GetSpellModOwner() ) modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, this); @@ -4109,7 +4109,7 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) if (roll_chance_i(miss_chance)) fail_list.push_back(spellInfo->Id); else - success_list.push_back(std::pair(aur->GetId(),aur->GetCasterGUID())); + success_list.push_back(std::pair(holder->GetId(),holder->GetCasterGUID())); } // Send success log and really remove auras if (!success_list.empty()) @@ -4126,7 +4126,7 @@ void Spell::EffectDispel(SpellEffectIndex eff_idx) SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first); data << uint32(spellInfo->Id); // Spell Id data << uint8(0); // 0 - dispeled !=0 cleansed - unitTarget->RemoveSingleAuraDueToSpellByDispel(spellInfo->Id, j->second, m_caster); + unitTarget->RemoveSingleAuraHolderDueToSpellByDispel(spellInfo->Id, j->second, m_caster); } m_caster->SendMessageToSet(&data, true); @@ -5002,16 +5002,16 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) { uint32 stack = 0; // Need refresh all Sunder Armor auras from this caster - Unit::AuraMap& suAuras = unitTarget->GetAuras(); + Unit::SpellAuraHolderMap& suAuras = unitTarget->GetSpellAuraHolderMap(); SpellEntry const *spellInfo; - for(Unit::AuraMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr) + for(Unit::SpellAuraHolderMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr) { spellInfo = (*itr).second->GetSpellProto(); if( spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) && (*itr).second->GetCasterGUID() == m_caster->GetGUID()) { - (*itr).second->RefreshAura(); + (*itr).second->RefreshHolder(); stack = (*itr).second->GetStackAmount(); break; } @@ -5037,8 +5037,8 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) // full aura scan else { - Unit::AuraMap const& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON) { @@ -5125,12 +5125,11 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) m_spellInfo->SpellIconID == 1736) { uint32 count = 0; - Unit::AuraMap const& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE && - itr->second->GetCasterGUID() == m_caster->GetGUID() && - IsSpellLastAuraEffect(itr->second->GetSpellProto(), itr->second->GetEffIndex())) + itr->second->GetCasterGUID() == m_caster->GetGUID()) ++count; } @@ -5435,7 +5434,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; } case 24590: // Brittle Armor - need remove one 24575 Brittle Armor aura - unitTarget->RemoveSingleSpellAurasFromStack(24575); + unitTarget->RemoveSingleAuraHolderFromStack(24575); return; case 26275: // PX-238 Winter Wondervolt TRAP { @@ -5454,7 +5453,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; } case 26465: // Mercurial Shield - need remove one 26464 Mercurial Shield aura - unitTarget->RemoveSingleSpellAurasFromStack(26464); + unitTarget->RemoveSingleAuraHolderFromStack(26464); return; case 25140: // Orb teleport spells case 25143: @@ -6188,22 +6187,22 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) case 47422: // Everlasting Affliction { // Need refresh caster corruption auras on target - Unit::AuraMap& suAuras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr) + Unit::SpellAuraHolderMap& suAuras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr) { SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); if(spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000002)) && (*itr).second->GetCasterGUID() == m_caster->GetGUID()) - (*itr).second->RefreshAura(); + (*itr).second->RefreshHolder(); } return; } case 63521: // Guarded by The Light (Paladin spell with SPELLFAMILY_WARLOCK) { // Divine Plea, refresh on target (3 aura slots) - if (Aura* aura = unitTarget->GetAura(54428, EFFECT_INDEX_0)) - aura->RefreshAura(); + if (SpellAuraHolder* holder = unitTarget->GetSpellAuraHolder(54428)) + holder->RefreshHolder(); return; } @@ -6220,15 +6219,15 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) return; // Refresh Shadow Word: Pain on target - Unit::AuraMap& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::SpellAuraHolderMap& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator itr = auras.begin(); itr != auras.end(); ++itr) { SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); if (spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000008000)) && (*itr).second->GetCasterGUID() == m_caster->GetGUID()) { - (*itr).second->RefreshAura(); + (*itr).second->RefreshHolder(); return; } } @@ -6251,23 +6250,28 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) uint32 spellId = 0; int32 basePoint = 0; Unit* target = unitTarget; - Unit::AuraMap& Auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) + Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { - Aura *aura = (*i).second; - if (aura->GetCasterGUID() != m_caster->GetGUID()) + SpellAuraHolder *holder = i->second; + if (holder->GetCasterGUID() != m_caster->GetGUID()) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras - uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; + uint64 familyFlag = holder->GetSpellProto()->SpellFamilyFlags; if (!(familyFlag & UI64LIT(0x000000800000C000))) continue; // Refresh aura duration - aura->RefreshAura(); + holder->RefreshHolder(); + + Aura *aura = holder->GetAuraByEffectIndex(EFFECT_INDEX_0); + + if (!aura) + continue; // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if ((familyFlag & UI64LIT(0x0000000000004000)) && aura->GetEffIndex() == EFFECT_INDEX_0) + if ((familyFlag & UI64LIT(0x0000000000004000))) { // m_amount already include RAP bonus basePoint = aura->GetModifier()->m_amount * aura->GetAuraMaxTicks() * 40 / 100; @@ -6275,7 +6279,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. - if ((familyFlag & UI64LIT(0x0000008000000000)) && aura->GetEffIndex() == EFFECT_INDEX_0) + if ((familyFlag & UI64LIT(0x0000008000000000))) { uint32 target_max_mana = unitTarget->GetMaxPower(POWER_MANA); if (!target_max_mana) @@ -7317,13 +7321,13 @@ void Spell::EffectDispelMechanic(SpellEffectIndex eff_idx) uint32 mechanic = m_spellInfo->EffectMiscValue[eff_idx]; - Unit::AuraMap& Auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + Unit::SpellAuraHolderMap& Auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) { next = iter; ++next; SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); - if(spell->Mechanic == mechanic || spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic) + if(spell->Mechanic == mechanic || iter->second->HasAuraAndMechanicEffect(mechanic)) { unitTarget->RemoveAurasDueToSpell(spell->Id); if(Auras.empty()) @@ -7661,19 +7665,19 @@ void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx) if(!unitTarget || unitTarget==m_caster) // can't steal from self return; - - std::vector steal_list; + + std::vector steal_list; // Create dispel mask by dispel type uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[eff_idx]) ); - Unit::AuraMap const& auras = unitTarget->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { - Aura *aur = (*itr).second; - if (aur && (1<GetSpellProto()->Dispel) & dispelMask) + SpellAuraHolder *holder = itr->second; + if (holder && (1<GetSpellProto()->Dispel) & dispelMask) { // Need check for passive? this - if (aur->IsPositive() && !aur->IsPassive() && !(aur->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE)) - steal_list.push_back(aur); + if (holder->IsPositive() && !holder->IsPassive() && !(holder->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE)) + steal_list.push_back(holder); } } // Ok if exist some buffs for dispel try dispel it @@ -7685,16 +7689,16 @@ void Spell::EffectStealBeneficialBuff(SpellEffectIndex eff_idx) for (int32 count=0; count < damage && list_size > 0; ++count) { // Random select buff for dispel - Aura *aur = steal_list[urand(0, list_size-1)]; + SpellAuraHolder *holder = steal_list[urand(0, list_size-1)]; // Not use chance for steal // TODO possible need do it - success_list.push_back( std::pair(aur->GetId(),aur->GetCasterGUID())); + success_list.push_back( std::pair(holder->GetId(),holder->GetCasterGUID())); // Remove buff from list for prevent doubles - for (std::vector::iterator j = steal_list.begin(); j != steal_list.end(); ) + for (std::vector::iterator j = steal_list.begin(); j != steal_list.end(); ) { - Aura *stealed = *j; - if (stealed->GetId() == aur->GetId() && stealed->GetCasterGUID() == aur->GetCasterGUID()) + SpellAuraHolder *stealed = *j; + if (stealed->GetId() == holder->GetId() && stealed->GetCasterGUID() == holder->GetCasterGUID()) { j = steal_list.erase(j); --list_size; diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 4a901c579..41adfd32a 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -457,6 +457,12 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket) return; } + SpellAuraHolder *holder = _player->GetSpellAuraHolder(spellId); + + // not own area auras can't be cancelled (note: maybe need to check for aura on holder and not general on spell) + if (holder && holder->GetCasterGUID() != _player->GetGUID() && HasAreaAuraEffect(holder->GetSpellProto())) + return; + // non channeled case _player->RemoveAurasDueToSpellByCancel(spellId); } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 7eee55e3c..a65fe2077 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -291,33 +291,46 @@ bool IsPassiveSpell(SpellEntry const *spellInfo) return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0; } -bool IsNoStackAuraDueToAura(uint32 spellId_1, SpellEffectIndex effIndex_1, uint32 spellId_2, SpellEffectIndex effIndex_2) +bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 spellId_2) { SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); if(!spellInfo_1 || !spellInfo_2) return false; if(spellInfo_1->Id == spellId_2) return false; - if (spellInfo_1->Effect[effIndex_1] != spellInfo_2->Effect[effIndex_2] || - spellInfo_1->EffectItemType[effIndex_1] != spellInfo_2->EffectItemType[effIndex_2] || - spellInfo_1->EffectMiscValue[effIndex_1] != spellInfo_2->EffectMiscValue[effIndex_2] || - spellInfo_1->EffectApplyAuraName[effIndex_1] != spellInfo_2->EffectApplyAuraName[effIndex_2]) - return false; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + for (int32 j = 0; i < MAX_EFFECT_INDEX; ++j) + { + if (spellInfo_1->Effect[i] == spellInfo_2->Effect[j] + && spellInfo_1->EffectApplyAuraName[i] == spellInfo_2->EffectApplyAuraName[j] + && spellInfo_1->EffectMiscValue[i] == spellInfo_2->EffectMiscValue[j] + && spellInfo_1->EffectItemType[i] == spellInfo_2->EffectItemType[j]) + return true; + } + } - return true; + return false; } -int32 CompareAuraRanks(uint32 spellId_1, SpellEffectIndex effIndex_1, uint32 spellId_2, SpellEffectIndex effIndex_2) +int32 CompareAuraRanks(uint32 spellId_1, uint32 spellId_2) { SpellEntry const*spellInfo_1 = sSpellStore.LookupEntry(spellId_1); SpellEntry const*spellInfo_2 = sSpellStore.LookupEntry(spellId_2); if(!spellInfo_1 || !spellInfo_2) return 0; if (spellId_1 == spellId_2) return 0; - int32 diff = spellInfo_1->EffectBasePoints[effIndex_1] - spellInfo_2->EffectBasePoints[effIndex_2]; - if (spellInfo_1->CalculateSimpleValue(effIndex_1) < 0 && spellInfo_2->CalculateSimpleValue(effIndex_2) < 0) - return -diff; - else return diff; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (spellInfo_1->Effect[i] != 0 && spellInfo_2->Effect[i] != 0 && spellInfo_1->Effect[i] == spellInfo_2->Effect[i]) + { + int32 diff = spellInfo_1->EffectBasePoints[i] - spellInfo_2->EffectBasePoints[i]; + if (spellInfo_1->CalculateSimpleValue(SpellEffectIndex(i)) < 0 && spellInfo_2->CalculateSimpleValue(SpellEffectIndex(i)) < 0) + return -diff; + else return diff; + } + } + return 0; } SpellSpecific GetSpellSpecific(uint32 spellId) @@ -1044,11 +1057,20 @@ struct DoSpellProcEvent if (spe.spellFamilyName != r_spe.spellFamilyName) sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyName from first rank in chain", spell_id); - if (spe.spellFamilyMask != r_spe.spellFamilyMask) - sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask from first rank in chain", spell_id); + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (spe.spellFamilyMask[i] != r_spe.spellFamilyMask[i]) + { + sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask from first rank in chain", spell_id); + break; + } - if (spe.spellFamilyMask2 != r_spe.spellFamilyMask2) - sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask2 from first rank in chain", spell_id); + if (spe.spellFamilyMask2[i] != r_spe.spellFamilyMask2[i]) + { + sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask2 from first rank in chain", spell_id); + break; + } + } if (spe.procFlags != r_spe.procFlags) sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different procFlags from first rank in chain", spell_id); @@ -1076,8 +1098,8 @@ void SpellMgr::LoadSpellProcEvents() uint32 count = 0; - // 0 1 2 3 4 5 6 7 8 9 10 - QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask0, SpellFamilyMask1, SpellFamilyMask2, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event"); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + QueryResult *result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMaskA0, SpellFamilyMaskA1, SpellFamilyMaskA2, SpellFamilyMaskB0, SpellFamilyMaskB1, SpellFamilyMaskB2, SpellFamilyMaskC0, SpellFamilyMaskC1, SpellFamilyMaskC2, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event"); if( !result ) { barGoLink bar( 1 ); @@ -1112,13 +1134,17 @@ void SpellMgr::LoadSpellProcEvents() spe.schoolMask = fields[1].GetUInt32(); spe.spellFamilyName = fields[2].GetUInt32(); - spe.spellFamilyMask = (uint64)fields[3].GetUInt32()|((uint64)fields[4].GetUInt32()<<32); - spe.spellFamilyMask2= fields[5].GetUInt32(); - spe.procFlags = fields[6].GetUInt32(); - spe.procEx = fields[7].GetUInt32(); - spe.ppmRate = fields[8].GetFloat(); - spe.customChance = fields[9].GetFloat(); - spe.cooldown = fields[10].GetUInt32(); + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + spe.spellFamilyMask[i] = (uint64)fields[i+3].GetUInt32()|((uint64)fields[i+6].GetUInt32()<<32); + spe.spellFamilyMask2[i] = fields[i+9].GetUInt32(); + } + spe.procFlags = fields[12].GetUInt32(); + spe.procEx = fields[13].GetUInt32(); + spe.ppmRate = fields[14].GetFloat(); + spe.customChance = fields[15].GetFloat(); + spe.cooldown = fields[16].GetUInt32(); uint32 first_id = GetFirstSpellInChain(entry); @@ -1178,10 +1204,22 @@ void SpellMgr::LoadSpellProcEvents() } // totally redundant record - if (!spe.schoolMask && !spe.spellFamilyMask && !spe.spellFamilyMask2 && !spe.procFlags && + if (!spe.schoolMask && !spe.procFlags && !spe.procEx && !spe.ppmRate && !spe.customChance && !spe.cooldown) { - sLog.outErrorDb("Spell %u listed in `spell_proc_event` not have any useful data", entry); + bool empty = !spe.spellFamilyName ? true : false; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (spe.spellFamilyMask[i] || spe.spellFamilyMask2[i]) + { + empty = false; + uint32 const* ptr = spell->GetEffectSpellClassMask(SpellEffectIndex(i)); + if ((((uint64*)ptr)[0] != 0 && spe.spellFamilyMask[i] == ((uint64*)ptr)[0]) && (ptr[2] == 0 || spe.spellFamilyMask2[i] == ptr[2])) + sLog.outErrorDb("Spell %u listed in `spell_proc_event` have same class mask as in Spell.dbc (EffectIndex %u) and doesn't have any other data", entry, i); + } + } + if (empty) + sLog.outErrorDb("Spell %u listed in `spell_proc_event` not have any useful data", entry); } if (isCustom) @@ -1440,7 +1478,7 @@ void SpellMgr::LoadSpellBonuses() sLog.outString( ">> Loaded %u extra spell bonus data", count); } -bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active) +bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra) { // No extra req need uint32 procEvent_procEx = PROC_EX_NONE; @@ -1474,32 +1512,20 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP // Check (if set) for spellFamilyName if(spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName)) return false; - - // spellFamilyName is Ok need check for spellFamilyMask if present - if(spellProcEvent->spellFamilyMask || spellProcEvent->spellFamilyMask2) - { - if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags ) == 0 && - (spellProcEvent->spellFamilyMask2 & procSpell->SpellFamilyFlags2) == 0) - return false; - active = true; // Spell added manualy -> so its active spell - } } } // Check for extra req (if none) and hit/crit if (procEvent_procEx == PROC_EX_NONE) { - // No extra req, so can trigger only for active (damage/healing present) and hit/crit - if((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && active) + // No extra req, so can trigger for (damage/healing present) and hit/crit + if(procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) return true; } - else // Passive spells hits here only if resist/reflect/immune/evade + else // all spells hits here only if resist/reflect/immune/evade { // Exist req for PROC_EX_EX_TRIGGER_ALWAYS if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS) return true; - // Passive spells can`t trigger if need hit (exclude cases when procExtra include non-active flags) - if ((procEvent_procEx & PROC_EX_NORMAL_HIT & procExtra) && !active) - return false; // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other) if (procEvent_procEx & procExtra) return true; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 88fc5ab75..b9a4cbf4b 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -139,6 +139,28 @@ inline bool IsSpellHaveEffect(SpellEntry const *spellInfo, SpellEffects effect) return false; } +inline bool IsSpellAppliesAura(SpellEntry const *spellInfo, uint32 effectMask) +{ + for(int i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (effectMask & (1 << i)) + { + switch (spellInfo->Effect[i]) + { + case SPELL_EFFECT_APPLY_AURA: + case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: + case SPELL_EFFECT_APPLY_AREA_AURA_RAID: + case SPELL_EFFECT_APPLY_AREA_AURA_PET: + case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: + case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: + case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: + return true; + } + } + } + return false; +} + inline bool IsEffectHandledOnDelayedSpellLaunch(SpellEntry const *spellInfo, SpellEffectIndex effecIdx) { switch (spellInfo->Effect[effecIdx]) @@ -170,7 +192,7 @@ inline bool IsSpellLastAuraEffect(SpellEntry const *spellInfo, SpellEffectIndex return true; } -bool IsNoStackAuraDueToAura(uint32 spellId_1, SpellEffectIndex effIndex_1, uint32 spellId_2, SpellEffectIndex effIndex_2); +bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 spellId_2); inline bool IsSealSpell(SpellEntry const *spellInfo) { @@ -203,7 +225,7 @@ inline bool IsLootCraftingSpell(SpellEntry const *spellInfo) (spellInfo->TotemCategory[0] != 0 || spellInfo->EffectItemType[0]==0))); } -int32 CompareAuraRanks(uint32 spellId_1, SpellEffectIndex effIndex_1, uint32 spellId_2, SpellEffectIndex effIndex_2); +int32 CompareAuraRanks(uint32 spellId_1, uint32 spellId_2); // order from less to more strict bool IsSingleFromSpellSpecificPerTargetPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2); @@ -390,6 +412,30 @@ inline bool IsAreaAuraEffect(uint32 effect) return false; } +inline bool HasAreaAuraEffect(SpellEntry const *spellInfo) +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (IsAreaAuraEffect(spellInfo->Effect[i])) + return true; + return false; +} + +inline bool HasAuraWithTriggerEffect(SpellEntry const *spellInfo) +{ + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + switch(spellInfo->Effect[i]) + { + case SPELL_AURA_PERIODIC_TRIGGER_SPELL: + case SPELL_AURA_PROC_TRIGGER_SPELL: + case SPELL_AURA_PROC_TRIGGER_DAMAGE: + case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: + return true; + } + } + return false; +} + inline bool IsDispelSpell(SpellEntry const *spellInfo) { return IsSpellHaveEffect(spellInfo, SPELL_EFFECT_DISPEL); @@ -553,8 +599,8 @@ struct SpellProcEventEntry { uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2 uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value - uint64 spellFamilyMask; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) - uint32 spellFamilyMask2; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags2 (like auras 107 and 108 do) + uint64 spellFamilyMask[MAX_EFFECT_INDEX]; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) + uint32 spellFamilyMask2[MAX_EFFECT_INDEX]; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags2 (like auras 107 and 108 do) uint32 procFlags; // bitmask for matching proc event uint32 procEx; // proc Extend info (see ProcFlagsEx) float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc @@ -831,7 +877,7 @@ class SpellMgr return itr->second; } - static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active); + static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra); // Spell bonus data SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f2d4b5e24..1c647cffe 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -65,15 +65,6 @@ float baseMoveSpeed[MAX_MOVE_TYPE] = 3.14f // MOVE_PITCH_RATE }; -// Used for prepare can/can`t trigger aura -static bool InitTriggerAuraData(); -// Define can trigger auras -static bool isTriggerAura[TOTAL_AURAS]; -// Define can`t trigger auras (need for disable second trigger) -static bool isNonTriggerAura[TOTAL_AURAS]; -// Prepare lists -static bool procPrepared = InitTriggerAuraData(); - void MovementInfo::Read(ByteBuffer &data) { data >> moveFlags; @@ -199,7 +190,7 @@ Unit::Unit() //m_Aura = NULL; //m_AurasCheck = 2000; //m_removeAuraTimer = 4; - m_AurasUpdateIterator = m_Auras.end(); + m_spellAuraHoldersUpdateIterator = m_spellAuraHolders.end(); m_AuraFlags = 0; m_Visibility = VISIBILITY_ON; @@ -272,6 +263,7 @@ Unit::~Unit() ASSERT(m_gameObj.size() == 0); ASSERT(m_dynObjGUIDs.size() == 0); ASSERT(m_deletedAuras.size() == 0); + ASSERT(m_deletedHolders.size() == 0); } void Unit::Update( uint32 p_time ) @@ -954,8 +946,8 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa } // TODO: Store auras by interrupt flag to speed this up. - AuraMap& vAuras = pVictim->GetAuras(); - for (AuraMap::const_iterator i = vAuras.begin(), next; i != vAuras.end(); i = next) + SpellAuraHolderMap& vAuras = pVictim->GetSpellAuraHolderMap(); + for (SpellAuraHolderMap::const_iterator i = vAuras.begin(), next; i != vAuras.end(); i = next) { const SpellEntry *se = i->second->GetSpellProto(); next = i; ++next; @@ -972,7 +964,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if (remove) { pVictim->RemoveAurasDueToSpell(i->second->GetId()); - // FIXME: this may cause the auras with proc chance to be rerolled several times next = vAuras.begin(); } } @@ -2132,7 +2123,7 @@ void Unit::CalculateAbsorbAndResist(Unit *pCaster, SpellSchoolMask schoolMask, D // Reduce shield amount mod->m_amount-=currentAbsorb; - if((*i)->DropAuraCharge()) + if((*i)->GetHolder()->DropAuraCharge()) mod->m_amount = 0; // Need remove it later if (mod->m_amount<=0) @@ -3313,25 +3304,44 @@ void Unit::_UpdateSpells( uint32 time ) // update auras // m_AurasUpdateIterator can be updated in inderect called code at aura remove to skip next planned to update but removed auras - for (m_AurasUpdateIterator = m_Auras.begin(); m_AurasUpdateIterator != m_Auras.end();) + for (m_spellAuraHoldersUpdateIterator = m_spellAuraHolders.begin(); m_spellAuraHoldersUpdateIterator != m_spellAuraHolders.end();) { - Aura* i_aura = m_AurasUpdateIterator->second; - ++m_AurasUpdateIterator; // need shift to next for allow update if need into aura update - i_aura->UpdateAura(time); + SpellAuraHolder* i_holder = m_spellAuraHoldersUpdateIterator->second; + ++m_spellAuraHoldersUpdateIterator; // need shift to next for allow update if need into aura update + i_holder->UpdateHolder(time); } // remove expired auras - for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();) + for (SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();) { - if ((*i).second) + SpellAuraHolder *holder = iter->second; + if (holder) { - if ( !(*i).second->GetAuraDuration() && !((*i).second->IsPermanent() || ((*i).second->IsPassive())) ) - RemoveAura(i, AURA_REMOVE_BY_EXPIRE); + if (!(holder->IsPermanent() || holder->IsPassive()) ) + { + bool removedAura = false; + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) + { + if (!aura->GetAuraDuration()) + { + RemoveSingleAuraFromSpellAuraHolder(holder, aura->GetEffIndex(), AURA_REMOVE_BY_EXPIRE); + removedAura = true; + } + } + } + + if (!removedAura) + ++iter; + else + iter = m_spellAuraHolders.begin(); + } else - ++i; + ++iter; } else - ++i; + ++iter; } if(!m_gameObj.empty()) @@ -3802,75 +3812,93 @@ float Unit::GetTotalAuraMultiplierByMiscValueForMask(AuraType auratype, uint32 m return multiplier; } -bool Unit::AddAura(Aura *Aur) +bool Unit::AddSpellAuraHolder(SpellAuraHolder *holder) { - SpellEntry const* aurSpellInfo = Aur->GetSpellProto(); + SpellEntry const* aurSpellInfo = holder->GetSpellProto(); // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) && !IsDeathOnlySpell(aurSpellInfo) && (GetTypeId()!=TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) ) { - delete Aur; + delete holder; return false; } - if(Aur->GetTarget() != this) + if(holder->GetTarget() != this) { - sLog.outError("Aura (spell %u eff %u) add to aura list of %s (lowguid: %u) but Aura target is %s (lowguid: %u)", - Aur->GetId(),Aur->GetEffIndex(),(GetTypeId()==TYPEID_PLAYER?"player":"creature"),GetGUIDLow(), - (Aur->GetTarget()->GetTypeId()==TYPEID_PLAYER?"player":"creature"),Aur->GetTarget()->GetGUIDLow()); - delete Aur; + sLog.outError("Holder (spell %u) add to spell aura holder list of %s (lowguid: %u) but spell aura holder target is %s (lowguid: %u)", + holder->GetId(),(GetTypeId()==TYPEID_PLAYER?"player":"creature"),GetGUIDLow(), + (holder->GetTarget()->GetTypeId()==TYPEID_PLAYER?"player":"creature"),holder->GetTarget()->GetGUIDLow()); + delete holder; return false; } - // m_auraname can be modified to SPELL_AURA_NONE for area auras, this expected for this value - AuraType aurName = Aur->GetModifier()->m_auraname; - - spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex()); - AuraMap::iterator i = m_Auras.find( spair ); - - // take out same spell - if (i != m_Auras.end()) + // passive and persistent auras can stack with themselves any number of times + if (!holder->IsPassive() && !holder->IsPersistent()) { - // passive and persistent auras can stack with themselves any number of times - if (!Aur->IsPassive() && !Aur->IsPersistent()) + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(aurSpellInfo->Id); + + // take out same spell + for (SpellAuraHolderMap::iterator iter = spair.first; iter != spair.second; ++iter) { - for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2) + SpellAuraHolder *foundHolder = iter->second; + if(foundHolder->GetCasterGUID() == holder->GetCasterGUID()) { - Aura* aur2 = i2->second; - if(aur2->GetCasterGUID()==Aur->GetCasterGUID()) + // Aura can stack on self -> Stack it; + if(aurSpellInfo->StackAmount) { - // Aura can stack on self -> Stack it; - if(aurSpellInfo->StackAmount) - { - // can be created with >1 stack by some spell mods - aur2->modStackAmount(Aur->GetStackAmount()); - delete Aur; - return false; - } - - // Check for coexisting Weapon-proced Auras - if (Aur->isWeaponBuffCoexistableWith(aur2)) - continue; - - // Carry over removed Aura's remaining damage if Aura still has ticks remaining - if (aur2->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_STACK_DOT_MODIFIER && aurName == SPELL_AURA_PERIODIC_DAMAGE && aur2->GetAuraDuration() > 0) - { - int32 remainingTicks = aur2->GetAuraMaxTicks() - aur2->GetAuraTicks(); - int32 remainingDamage = aur2->GetModifier()->m_amount * remainingTicks; - - Aur->GetModifier()->m_amount += int32(remainingDamage / Aur->GetAuraMaxTicks()); - } - // can be only single (this check done at _each_ aura add - RemoveAura(i2,AURA_REMOVE_BY_STACK); - break; + // can be created with >1 stack by some spell mods + foundHolder->ModStackAmount(holder->GetStackAmount()); + delete holder; + return false; } - bool stop = false; + // Check for coexisting Weapon-proced Auras + if (holder->IsWeaponBuffCoexistableWith(foundHolder)) + continue; + + // Carry over removed Aura's remaining damage if Aura still has ticks remaining + if (foundHolder->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_STACK_DOT_MODIFIER) + { + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) + { + // m_auraname can be modified to SPELL_AURA_NONE for area auras, use original + AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[i]); + + if (aurNameReal == SPELL_AURA_PERIODIC_DAMAGE && aur->GetAuraDuration() > 0) + { + if (Aura *existing = foundHolder->GetAuraByEffectIndex(SpellEffectIndex(i))) + { + int32 remainingTicks = existing->GetAuraMaxTicks() - existing->GetAuraTicks(); + int32 remainingDamage = existing->GetModifier()->m_amount * remainingTicks; + + aur->GetModifier()->m_amount += int32(remainingDamage / aur->GetAuraMaxTicks()); + } + else + DEBUG_LOG("Holder (spell %u) on target (lowguid: %u) doesn't have aura on effect index %u. skipping.", aurSpellInfo->Id, holder->GetTarget()->GetGUIDLow(), i); + } + } + } + } + + // can be only single + RemoveSpellAuraHolder(foundHolder, AURA_REMOVE_BY_STACK); + break; + } + + bool stop = false; + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + // no need to check non stacking auras that weren't/won't be applied on this target + if (!foundHolder->m_auras[i] || !holder->m_auras[i]) + continue; // m_auraname can be modified to SPELL_AURA_NONE for area auras, use original - AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]); + AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[i]); switch(aurNameReal) { @@ -3888,50 +3916,51 @@ bool Unit::AddAura(Aura *Aur) case SPELL_AURA_PERIODIC_ENERGIZE: // all or self or clear non-stackable default: // not allow // can be only single (this check done at _each_ aura add - RemoveAura(i2,AURA_REMOVE_BY_STACK); + RemoveSpellAuraHolder(foundHolder,AURA_REMOVE_BY_STACK); stop = true; break; } - - if(stop) - break; } + + if(stop) + break; + } } // passive auras not stacable with other ranks if (!IsPassiveSpellStackableWithRanks(aurSpellInfo)) { - if (!RemoveNoStackAurasDueToAura(Aur)) + if (!RemoveNoStackAurasDueToAuraHolder(holder)) { - delete Aur; + delete holder; return false; // couldn't remove conflicting aura with higher rank } } // update single target auras list (before aura add to aura list, to prevent unexpected remove recently added aura) - if (Aur->IsSingleTarget() && Aur->GetTarget()) + if (holder->IsSingleTarget() && holder->GetTarget()) { // caster pointer can be deleted in time aura remove, find it by guid at each iteration for(;;) { - Unit* caster = Aur->GetCaster(); + Unit* caster = holder->GetCaster(); if(!caster) // caster deleted and not required adding scAura break; bool restart = false; - AuraList& scAuras = caster->GetSingleCastAuras(); - for(AuraList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr) + SpellAuraHolderList& scAuras = caster->GetSingleCastSpellAuraHolders(); + for(SpellAuraHolderList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr) { - if( (*itr)->GetTarget() != Aur->GetTarget() && + if( (*itr)->GetTarget() != holder->GetTarget() && IsSingleTargetSpells((*itr)->GetSpellProto(),aurSpellInfo) ) { if ((*itr)->IsInUse()) { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for IsSingleTargetSpell", (*itr)->GetId(), (*itr)->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + sLog.outError("Holder (Spell %u) is in process but attempt removed at aura (Spell %u) adding, need add stack rule for IsSingleTargetSpell", (*itr)->GetId(), holder->GetId()); continue; } - (*itr)->GetTarget()->RemoveAura((*itr)->GetId(), (*itr)->GetEffIndex()); + (*itr)->GetTarget()->RemoveSpellAuraHolder((*itr)); restart = true; break; } @@ -3940,30 +3969,30 @@ bool Unit::AddAura(Aura *Aur) if(!restart) { // done - scAuras.push_back(Aur); + scAuras.push_back(holder); break; } } } // add aura, register in lists and arrays - Aur->_AddAura(); - m_Auras.insert(AuraMap::value_type(spellEffectPair(Aur->GetId(), Aur->GetEffIndex()), Aur)); - if (aurName < TOTAL_AURAS) - { - m_modAuras[aurName].push_back(Aur); - } + holder->_AddSpellAuraHolder(); + m_spellAuraHolders.insert(SpellAuraHolderMap::value_type(holder->GetId(), holder)); - Aur->ApplyModifier(true,true); - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u now is in use", aurName); + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) + if (aur->GetModifier()->m_auraname < TOTAL_AURAS) + m_modAuras[aur->GetModifier()->m_auraname].push_back(aur); + + holder->ApplyAuraModifiers(true, true); + DEBUG_LOG("Holder of spell %u now is in use", holder->GetId()); // if aura deleted before boosts apply ignore // this can be possible it it removed indirectly by triggered spell effect at ApplyModifier - if (Aur->IsDeleted()) + if (holder->IsDeleted()) return false; - if(IsSpellLastAuraEffect(aurSpellInfo,Aur->GetEffIndex())) - Aur->HandleSpellSpecificBoosts(true); + holder->HandleSpellSpecificBoosts(true); return true; } @@ -3973,8 +4002,8 @@ void Unit::RemoveRankAurasDueToSpell(uint32 spellId) SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if(!spellInfo) return; - AuraMap::const_iterator i,next; - for (i = m_Auras.begin(); i != m_Auras.end(); i = next) + SpellAuraHolderMap::const_iterator i,next; + for (i = m_spellAuraHolders.begin(); i != m_spellAuraHolders.end(); i = next) { next = i; ++next; @@ -3985,26 +4014,25 @@ void Unit::RemoveRankAurasDueToSpell(uint32 spellId) { RemoveAurasDueToSpell(i_spellId); - if( m_Auras.empty() ) + if( m_spellAuraHolders.empty() ) break; else - next = m_Auras.begin(); + next = m_spellAuraHolders.begin(); } } } } -bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) +bool Unit::RemoveNoStackAurasDueToAuraHolder(SpellAuraHolder *holder) { - if (!Aur) + if (!holder) return false; - SpellEntry const* spellProto = Aur->GetSpellProto(); + SpellEntry const* spellProto = holder->GetSpellProto(); if (!spellProto) return false; - uint32 spellId = Aur->GetId(); - SpellEffectIndex effIndex = Aur->GetEffIndex(); + uint32 spellId = holder->GetId(); // passive spell special case (only non stackable with ranks) if(IsPassiveSpell(spellProto)) @@ -4015,8 +4043,8 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) SpellSpecific spellId_spec = GetSpellSpecific(spellId); - AuraMap::iterator i,next; - for (i = m_Auras.begin(); i != m_Auras.end(); i = next) + SpellAuraHolderMap::iterator i,next; + for (i = m_spellAuraHolders.begin(); i != m_spellAuraHolders.end(); i = next) { next = i; ++next; @@ -4033,7 +4061,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) if(IsPassiveSpell(i_spellProto)) { // passive non-stackable spells not stackable only for same caster - if(Aur->GetCasterGUID()!=i->second->GetCasterGUID()) + if(holder->GetCasterGUID()!=i->second->GetCasterGUID()) continue; // passive non-stackable spells not stackable only with another rank of same spell @@ -4041,8 +4069,6 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) continue; } - SpellEffectIndex i_effIndex = (*i).second->GetEffIndex(); - if(i_spellId == spellId) continue; bool is_triggered_by_spell = false; @@ -4064,25 +4090,25 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) // single allowed spell specific from same caster or from any caster at target bool is_spellSpecPerTargetPerCaster = IsSingleFromSpellSpecificPerTargetPerCaster(spellId_spec,i_spellId_spec); bool is_spellSpecPerTarget = IsSingleFromSpellSpecificPerTarget(spellId_spec,i_spellId_spec); - if( is_spellSpecPerTarget || is_spellSpecPerTargetPerCaster && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() ) + if( is_spellSpecPerTarget || is_spellSpecPerTargetPerCaster && holder->GetCasterGUID() == (*i).second->GetCasterGUID() ) { // cannot remove higher rank if (sSpellMgr.IsRankSpellDueToSpell(spellProto, i_spellId)) - if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) + if(CompareAuraRanks(spellId, i_spellId) < 0) return false; // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + sLog.outError("SpellAuraHolder (Spell %u) is in process but attempt removed at SpellAuraHolder (Spell %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAuraHolder", i->second->GetId(), holder->GetId()); continue; } RemoveAurasDueToSpell(i_spellId); - if( m_Auras.empty() ) + if( m_spellAuraHolders.empty() ) break; else - next = m_Auras.begin(); + next = m_spellAuraHolders.begin(); continue; } @@ -4090,24 +4116,24 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) // spell with spell specific that allow single ranks for spell from diff caster // same caster case processed or early or later bool is_spellPerTarget = IsSingleFromSpellSpecificSpellRanksPerTarget(spellId_spec,i_spellId_spec); - if ( is_spellPerTarget && Aur->GetCasterGUID() != (*i).second->GetCasterGUID() && sSpellMgr.IsRankSpellDueToSpell(spellProto, i_spellId)) + if ( is_spellPerTarget && holder->GetCasterGUID() != (*i).second->GetCasterGUID() && sSpellMgr.IsRankSpellDueToSpell(spellProto, i_spellId)) { // cannot remove higher rank - if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) + if(CompareAuraRanks(spellId, i_spellId) < 0) return false; // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + sLog.outError("SpellAuraHolder (Spell %u) is in process but attempt removed at SpellAuraHolder (Spell %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAuraHolder", i->second->GetId(), holder->GetId()); continue; } RemoveAurasDueToSpell(i_spellId); - if( m_Auras.empty() ) + if( m_spellAuraHolders.empty() ) break; else - next = m_Auras.begin(); + next = m_spellAuraHolders.begin(); continue; } @@ -4118,15 +4144,15 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + sLog.outError("SpellAuraHolder (Spell %u) is in process but attempt removed at SpellAuraHolder (Spell %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAuraHolder", i->second->GetId(), holder->GetId()); continue; } RemoveAurasDueToSpell(i_spellId); - if( m_Auras.empty() ) + if( m_spellAuraHolders.empty() ) break; else - next = m_Auras.begin(); + next = m_spellAuraHolders.begin(); continue; } @@ -4134,69 +4160,80 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur) // Potions stack aura by aura (elixirs/flask already checked) if( spellProto->SpellFamilyName == SPELLFAMILY_POTION && i_spellProto->SpellFamilyName == SPELLFAMILY_POTION ) { - if (IsNoStackAuraDueToAura(spellId, effIndex, i_spellId, i_effIndex)) + if (IsNoStackAuraDueToAura(spellId, i_spellId)) { - if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) + if(CompareAuraRanks(spellId, i_spellId) < 0) return false; // cannot remove higher rank // Its a parent aura (create this aura in ApplyModifier) if ((*i).second->IsInUse()) { - sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex()); + sLog.outError("SpellAuraHolder (Spell %u) is in process but attempt removed at SpellAuraHolder (Spell %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAuraHolder", i->second->GetId(), holder->GetId()); continue; } - RemoveAura(i); - next = i; + RemoveAurasDueToSpell(i_spellId); + + if( m_spellAuraHolders.empty() ) + break; + else + next = m_spellAuraHolders.begin(); } } } return true; } -void Unit::RemoveAura(uint32 spellId, SpellEffectIndex effindex, Aura* except, AuraRemoveMode mode) +void Unit::RemoveAura(uint32 spellId, SpellEffectIndex effindex, Aura* except) { - spellEffectPair spair = spellEffectPair(spellId, effindex); - for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);) + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellId); + for(SpellAuraHolderMap::iterator iter = spair.first; iter != spair.second; ) { - if(iter->second!=except) + Aura *aur = iter->second->m_auras[effindex]; + if (aur && aur != except) { - RemoveAura(iter, mode); - iter = m_Auras.lower_bound(spair); + RemoveSingleAuraFromSpellAuraHolder(iter->second, effindex); + // may remove holder + spair = GetSpellAuraHolderBounds(spellId); + iter = spair.first; } else ++iter; } } - void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID) { - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellId); + for(SpellAuraHolderMap::iterator iter = spair.first; iter != spair.second; ) { - Aura *aur = iter->second; - if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) - RemoveAura(iter); - else - ++iter; - } -} - -void Unit::RemoveAurasByCasterSpell(uint32 spellId, SpellEffectIndex effindex, uint64 casterGUID) -{ - spellEffectPair spair = spellEffectPair(spellId, effindex); - for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);) - { - Aura *aur = iter->second; - if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) + if (iter->second->GetCasterGUID() == casterGUID) { - RemoveAura(iter); - iter = m_Auras.lower_bound(spair); + RemoveSpellAuraHolder(iter->second); + spair = GetSpellAuraHolderBounds(spellId); + iter = spair.first; } else ++iter; } } -void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler) +void Unit::RemoveSingleAuraFromSpellAuraHolder(uint32 spellId, SpellEffectIndex effindex, uint64 casterGUID, AuraRemoveMode mode) +{ + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellId); + for(SpellAuraHolderMap::iterator iter = spair.first; iter != spair.second; ) + { + Aura *aur = iter->second->m_auras[effindex]; + if (aur && aur->GetCasterGUID() == casterGUID) + { + RemoveSingleAuraFromSpellAuraHolder(iter->second, effindex, mode); + spair = GetSpellAuraHolderBounds(spellId); + iter = spair.first; + } + else + ++iter; + } +} + +void Unit::RemoveSingleAuraHolderDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler) { SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId); @@ -4211,7 +4248,7 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, damage *= 9; // Remove spell auras from stack - RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); + RemoveSingleAuraHolderFromStack(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); // backfire damage and silence dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,casterGUID); @@ -4244,7 +4281,7 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, } // Remove spell auras from stack - RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); + RemoveSingleAuraHolderFromStack(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); // Haste if (triggeredSpell) @@ -4263,7 +4300,7 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, bp0 *= 8; // Remove spell auras from stack - RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); + RemoveSingleAuraHolderFromStack(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); CastCustomSpell(this, 64085, &bp0, NULL, NULL, true, NULL, NULL, casterGUID); return; @@ -4271,58 +4308,61 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, } } - RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); + RemoveSingleAuraHolderFromStack(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); } void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer) { - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + SpellAuraHolder *holder = GetSpellAuraHolder(spellId, casterGUID); + SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId); + SpellAuraHolder *new_holder = CreateSpellAuraHolder(spellProto, stealer, this); + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - Aura *aur = iter->second; - if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) - { - int32 basePoints = aur->GetBasePoints(); - // construct the new aura for the attacker - will never return NULL, it's just a wrapper for - // some different constructors - Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), &basePoints, stealer, this); + Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)); - // set its duration and maximum duration - // max duration 2 minutes (in msecs) - int32 dur = aur->GetAuraDuration(); - int32 max_dur = 2*MINUTE*IN_MILLISECONDS; - int32 new_max_dur = max_dur > dur ? dur : max_dur; - new_aur->SetAuraMaxDuration( new_max_dur ); - new_aur->SetAuraDuration( new_max_dur ); + if (!aur) + continue; - // set periodic to do at least one tick (for case when original aura has been at last tick preparing) - int32 periodic = aur->GetModifier()->periodictime; - new_aur->GetModifier()->periodictime = periodic < new_max_dur ? periodic : new_max_dur; + int32 basePoints = aur->GetBasePoints(); + // construct the new aura for the attacker - will never return NULL, it's just a wrapper for + // some different constructors + Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), &basePoints, new_holder, stealer, this); - // Unregister _before_ adding to stealer - aur->UnregisterSingleCastAura(); + // set its duration and maximum duration + // max duration 2 minutes (in msecs) + int32 dur = aur->GetAuraDuration(); + int32 max_dur = 2*MINUTE*IN_MILLISECONDS; + int32 new_max_dur = max_dur > dur ? dur : max_dur; + new_aur->SetAuraMaxDuration( new_max_dur ); + new_aur->SetAuraDuration( new_max_dur ); - // strange but intended behaviour: Stolen single target auras won't be treated as single targeted - new_aur->SetIsSingleTarget(false); + // set periodic to do at least one tick (for case when original aura has been at last tick preparing) + int32 periodic = aur->GetModifier()->periodictime; + new_aur->GetModifier()->periodictime = periodic < new_max_dur ? periodic : new_max_dur; - // add the new aura to stealer - stealer->AddAura(new_aur); - - // Remove aura as dispel - RemoveAura(iter, AURA_REMOVE_BY_DISPEL); - } - else - ++iter; + // add the new aura to stealer + new_holder->AddAura(new_aur, new_aur->GetEffIndex()); } + + if (holder->ModStackAmount(-1)) + // Remove aura as dispel + RemoveSpellAuraHolder(holder, AURA_REMOVE_BY_DISPEL); + + // strange but intended behaviour: Stolen single target auras won't be treated as single targeted + new_holder->SetIsSingleTarget(false); + + stealer->AddSpellAuraHolder(new_holder); } void Unit::RemoveAurasDueToSpellByCancel(uint32 spellId) -{ - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) +{ + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellId); + for(SpellAuraHolderMap::iterator iter = spair.first; iter != spair.second;) { - if (iter->second->GetId() == spellId) - RemoveAura(iter, AURA_REMOVE_BY_CANCEL); - else - ++iter; + RemoveSpellAuraHolder(iter->second, AURA_REMOVE_BY_CANCEL); + spair = GetSpellAuraHolderBounds(spellId); + iter = spair.first; } } @@ -4331,8 +4371,8 @@ void Unit::RemoveAurasWithDispelType( DispelType type ) // Create dispel mask by dispel type uint32 dispelMask = GetDispellMask(type); // Dispel all existing auras vs current dispel type - AuraMap& auras = GetAuras(); - for(AuraMap::iterator itr = auras.begin(); itr != auras.end(); ) + SpellAuraHolderMap& auras = GetSpellAuraHolderMap(); + for(SpellAuraHolderMap::iterator itr = auras.begin(); itr != auras.end(); ) { SpellEntry const* spell = itr->second->GetSpellProto(); if( (1<Dispel) & dispelMask ) @@ -4346,77 +4386,63 @@ void Unit::RemoveAurasWithDispelType( DispelType type ) } } -void Unit::RemoveSingleAuraFromStack(AuraMap::iterator &i, AuraRemoveMode mode) +void Unit::RemoveSingleAuraHolderFromStack(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode) { - if (i->second->modStackAmount(-1)) - RemoveAura(i,mode); -} - - -void Unit::RemoveSingleAuraFromStack(uint32 spellId, SpellEffectIndex effindex, AuraRemoveMode mode) -{ - AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); - if(iter != m_Auras.end()) - RemoveSingleAuraFromStack(iter,mode); -} - -void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId, AuraRemoveMode mode) -{ - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - RemoveSingleAuraFromStack(spellId, SpellEffectIndex(i), mode); -} - -void Unit::RemoveSingleSpellAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode) -{ - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - RemoveSingleAuraByCasterSpell(spellId, SpellEffectIndex(i), casterGUID, mode); -} - -void Unit::RemoveSingleAuraByCasterSpell(uint32 spellId, SpellEffectIndex effindex, uint64 casterGUID, AuraRemoveMode mode) -{ - spellEffectPair spair = spellEffectPair(spellId, effindex); - for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter) + SpellAuraHolderBounds spair = GetSpellAuraHolderBounds(spellId); + for(SpellAuraHolderMap::iterator iter = spair.first; iter != spair.second; ++iter) { - Aura *aur = iter->second; - if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID) + if (!casterGUID || iter->second->GetCasterGUID() == casterGUID) { - RemoveSingleAuraFromStack(iter,mode); - break; + if (iter->second->ModStackAmount(-1)) + { + RemoveSpellAuraHolder(iter->second, mode); + break; + } } } } - -void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except, AuraRemoveMode mode) +void Unit::RemoveAurasDueToSpell(uint32 spellId, SpellAuraHolder* except, AuraRemoveMode mode) { - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - RemoveAura(spellId,SpellEffectIndex(i),except, mode); + SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(spellId); + for (SpellAuraHolderMap::iterator iter = bounds.first; iter != bounds.second; ) + { + if (iter->second != except) + { + RemoveSpellAuraHolder(iter->second, mode); + bounds = GetSpellAuraHolderBounds(spellId); + iter = bounds.first; + } + else + ++iter; + } } void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId) { - for (int k=0; k < MAX_EFFECT_INDEX; ++k) + SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(spellId); + for (SpellAuraHolderMap::iterator iter = bounds.first; iter != bounds.second; ) { - spellEffectPair spair = spellEffectPair(spellId, SpellEffectIndex(k)); - for (AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);) + if (iter->second->GetCastItemGUID() == castItem->GetGUID()) { - if (iter->second->GetCastItemGUID() == castItem->GetGUID()) - { - RemoveAura(iter); - iter = m_Auras.upper_bound(spair); // overwrite by more appropriate - } - else - ++iter; + RemoveSpellAuraHolder(iter->second); + bounds = GetSpellAuraHolderBounds(spellId); + iter = bounds.first; } + else + ++iter; } } void Unit::RemoveAurasWithInterruptFlags(uint32 flags) { - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + for (SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end(); ) { if (iter->second->GetSpellProto()->AuraInterruptFlags & flags) - RemoveAura(iter); + { + RemoveSpellAuraHolder(iter->second); + iter = m_spellAuraHolders.begin(); + } else ++iter; } @@ -4425,17 +4451,23 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flags) void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) { // single target auras from other casters - for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ) + for (SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end(); ) { if (iter->second->GetCasterGUID()!=GetGUID() && IsSingleTargetSpell(iter->second->GetSpellProto())) { if(!newPhase) - RemoveAura(iter); + { + RemoveSpellAuraHolder(iter->second); + m_spellAuraHolders.begin(); + } else { Unit* caster = iter->second->GetCaster(); if(!caster || !caster->InSamePhase(newPhase)) - RemoveAura(iter); + { + RemoveSpellAuraHolder(iter->second); + m_spellAuraHolders.begin(); + } else ++iter; } @@ -4444,15 +4476,16 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) ++iter; } + // single cast!! // single target auras at other targets - AuraList& scAuras = GetSingleCastAuras(); - for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end(); ) + SpellAuraHolderList& scAuras = GetSingleCastSpellAuraHolders(); + for (SpellAuraHolderList::iterator iter = scAuras.begin(); iter != scAuras.end(); ) { - Aura* aura = *iter; - if (aura->GetTarget() != this && !aura->GetTarget()->InSamePhase(newPhase)) + SpellAuraHolder* holder = *iter; + if (holder->GetTarget() != this && !holder->GetTarget()->InSamePhase(newPhase)) { - scAuras.erase(iter); // explicitly remove, instead waiting remove in RemoveAura - aura->GetTarget()->RemoveAura(aura); + scAuras.erase(iter); // explicitly remove, instead waiting remove in RemoveSpellAuraHolder + holder->GetTarget()->RemoveSpellAuraHolder(holder); iter = scAuras.begin(); } else @@ -4461,27 +4494,69 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) } -void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/) +void Unit::RemoveSpellAuraHolder(SpellAuraHolder *holder, AuraRemoveMode mode) { - AuraMap::iterator i = m_Auras.lower_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex())); - AuraMap::iterator upperBound = m_Auras.upper_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex())); - for (; i != upperBound; ++i) + // Statue unsummoned at holder remove + SpellEntry const* AurSpellInfo = holder->GetSpellProto(); + Totem* statue = NULL; + if(IsChanneledSpell(AurSpellInfo)) + if(Unit* caster = holder->GetCaster()) + if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) + statue = ((Totem*)caster); + + if (m_spellAuraHoldersUpdateIterator != m_spellAuraHolders.end() && m_spellAuraHoldersUpdateIterator->second == holder) + ++m_spellAuraHoldersUpdateIterator; + + SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(holder->GetId()); + for (SpellAuraHolderMap::iterator itr = bounds.first; itr != bounds.second; ++itr) { - if (i->second == aura) + if (itr->second == holder) { - RemoveAura(i,mode); - return; + m_spellAuraHolders.erase(itr); + break; } } - DEBUG_LOG("Trying to remove aura id %u effect %u by pointer but aura not found on target", aura->GetId(), aura->GetEffIndex()); + + holder->SetRemoveMode(mode); + holder->UnregisterSingleCastHolder(); + + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aura = holder->m_auras[i]) + RemoveAura(aura, mode); + } + + holder->_RemoveSpellAuraHolder(); + + if (mode != AURA_REMOVE_BY_DELETE) + holder->HandleSpellSpecificBoosts(false); + + if(statue) + statue->UnSummon(); + + // If holder in use (removed from code that plan access to it data after return) + // store it in holder list with delayed deletion + if (holder->IsInUse()) + m_deletedHolders.push_back(holder); + else + delete holder; } -void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) +void Unit::RemoveSingleAuraFromSpellAuraHolder(SpellAuraHolder *holder, SpellEffectIndex index, AuraRemoveMode mode) { - Aura* Aur = i->second; - SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); + Aura *aura = holder->GetAuraByEffectIndex(index); + if (!aura) + return; - Aur->UnregisterSingleCastAura(); + if (aura->IsLastAuraOnHolder()) + RemoveSpellAuraHolder(holder, mode); + else + RemoveAura(aura, mode); +} + +void Unit::RemoveAura(Aura *Aur, AuraRemoveMode mode) +{ + SpellEntry const* AurSpellInfo = Aur->GetSpellProto(); // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order) if (Aur->GetModifier()->m_auraname < TOTAL_AURAS) @@ -4492,22 +4567,9 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) // Set remove mode Aur->SetRemoveMode(mode); - // if unit currently update aura list then make safe update iterator shift to next - if (m_AurasUpdateIterator == i) - ++m_AurasUpdateIterator; - // some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura // remove aura from list before to prevent deleting it before - m_Auras.erase(i); - - // now aura removed from from list and can't be deleted by indirect call but can be referenced from callers - - // Statue unsummoned at aura remove - Totem* statue = NULL; - if(IsChanneledSpell(AurSpellInfo)) - if(Unit* caster = Aur->GetCaster()) - if(caster->GetTypeId()==TYPEID_UNIT && ((Creature*)caster)->isTotem() && ((Totem*)caster)->GetTotemType()==TOTEM_STATUE) - statue = ((Totem*)caster); + ///m_Auras.erase(i); DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); @@ -4528,12 +4590,7 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) else Aur->ApplyModifier(false,true); - if (Aur->_RemoveAura()) - { - // last aura in stack removed - if (mode != AURA_REMOVE_BY_DELETE && IsSpellLastAuraEffect(Aur->GetSpellProto(),Aur->GetEffIndex())) - Aur->HandleSpellSpecificBoosts(false); - } + Aur->GetHolder()->RemoveAura(Aur->GetEffIndex()); // If aura in use (removed from code that plan access to it data after return) // store it in aura list with delayed deletion @@ -4542,23 +4599,21 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode) else delete Aur; - if(statue) - statue->UnSummon(); // only way correctly remove all auras from list - if( m_Auras.empty() ) + /*if( m_Auras.empty() ) i = m_Auras.end(); else - i = m_Auras.begin(); + i = m_Auras.begin();*/ } void Unit::RemoveAllAuras(AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/) { - while (!m_Auras.empty()) + while (!m_spellAuraHolders.empty()) { - AuraMap::iterator iter = m_Auras.begin(); - RemoveAura(iter,mode); + SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); + RemoveSpellAuraHolder(iter->second,mode); } } @@ -4566,7 +4621,7 @@ void Unit::RemoveArenaAuras(bool onleave) { // in join, remove positive buffs, on end, remove negative // used to remove positive visible auras in arenas - for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) + for(SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();) { if (!(iter->second->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_UNK21) && // don't remove stances, shadowform, pally/hunter auras @@ -4575,7 +4630,10 @@ void Unit::RemoveArenaAuras(bool onleave) !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) && // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable) (iter->second->IsPositive() != onleave)) // remove positive buffs on enter, negative buffs on leave - RemoveAura(iter); + { + RemoveSpellAuraHolder(iter->second); + iter = m_spellAuraHolders.begin(); + } else ++iter; } @@ -4585,50 +4643,60 @@ void Unit::RemoveAllAurasOnDeath() { // used just after dieing to remove all visible auras // and disable the mods for the passive ones - for(AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();) + for(SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();) { if (!iter->second->IsPassive() && !iter->second->IsDeathPersistent()) - RemoveAura(iter, AURA_REMOVE_BY_DEATH); + { + RemoveSpellAuraHolder(iter->second, AURA_REMOVE_BY_DEATH); + iter = m_spellAuraHolders.begin(); + } else ++iter; } } -void Unit::DelayAura(uint32 spellId, SpellEffectIndex effindex, int32 delaytime) +void Unit::DelaySpellAuraHolder(uint32 spellId, int32 delaytime) { - AuraMap::const_iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); - if (iter != m_Auras.end()) + SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(spellId); + for (SpellAuraHolderMap::iterator iter = bounds.first; iter != bounds.second; ++iter) { - if (iter->second->GetAuraDuration() < delaytime) - iter->second->SetAuraDuration(0); - else - iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime); + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (Aura *aur = iter->second->GetAuraByEffectIndex(SpellEffectIndex(i))) + { + if (aur->GetAuraDuration() < delaytime) + aur->SetAuraDuration(0); + else + aur->SetAuraDuration(aur->GetAuraDuration() - delaytime); + + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u partially interrupted on unit %u, new duration: %u ms",spellId, GetGUIDLow(), aur->GetAuraDuration()); + } + } iter->second->SendAuraUpdate(false); - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration()); } } void Unit::_RemoveAllAuraMods() { - for (AuraMap::const_iterator i = m_Auras.begin(); i != m_Auras.end(); ++i) + for (SpellAuraHolderMap::const_iterator i = m_spellAuraHolders.begin(); i != m_spellAuraHolders.end(); ++i) { - (*i).second->ApplyModifier(false); + (*i).second->ApplyAuraModifiers(false); } } void Unit::_ApplyAllAuraMods() { - for (AuraMap::const_iterator i = m_Auras.begin(); i != m_Auras.end(); ++i) + for (SpellAuraHolderMap::const_iterator i = m_spellAuraHolders.begin(); i != m_spellAuraHolders.end(); ++i) { - (*i).second->ApplyModifier(true); + (*i).second->ApplyAuraModifiers(true); } } Aura* Unit::GetAura(uint32 spellId, SpellEffectIndex effindex) { - AuraMap::const_iterator iter = m_Auras.find(spellEffectPair(spellId, effindex)); - if (iter != m_Auras.end()) - return iter->second; + SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(spellId); + if (bounds.first != bounds.second) + return bounds.first->second->GetAuraByEffectIndex(effindex); return NULL; } @@ -4648,14 +4716,12 @@ Aura* Unit::GetAura(AuraType type, uint32 family, uint64 familyFlag, uint32 fami return NULL; } -bool Unit::HasAura(uint32 spellId) const -{ - for (int i = 0; i < MAX_EFFECT_INDEX ; ++i) - { - AuraMap::const_iterator iter = m_Auras.find(spellEffectPair(spellId, SpellEffectIndex(i))); - if (iter != m_Auras.end()) +bool Unit::HasAura(uint32 spellId, SpellEffectIndex effIndex) const +{ + for(SpellAuraHolderMap::const_iterator i_holder = m_spellAuraHolders.lower_bound(spellId); i_holder != m_spellAuraHolders.upper_bound(spellId); ++i_holder) + if (i_holder->second->GetAuraByEffectIndex(effIndex)) return true; - } + return false; } @@ -5006,3111 +5072,6 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 /*SwingType SendAttackStateUpdate(&dmgInfo); } -bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) -{ - SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto(); - - Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = 0; - Unit* target = pVictim; - int32 basepoints0 = 0; - - switch(hasteSpell->SpellFamilyName) - { - case SPELLFAMILY_ROGUE: - { - switch(hasteSpell->Id) - { - // Blade Flurry - case 13877: - case 33735: - { - target = SelectRandomUnfriendlyTarget(pVictim); - if(!target) - return false; - basepoints0 = damage; - triggered_spell_id = 22482; - break; - } - } - break; - } - } - - // processed charge only counting case - if(!triggered_spell_id) - return true; - - SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); - - if(!triggerEntry) - { - sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",hasteSpell->Id,triggered_spell_id); - return false; - } - - // default case - if(!target || target!=this && !target->isAlive()) - return false; - - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) - return false; - - if(basepoints0) - CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); - else - CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); - - if( cooldown && GetTypeId()==TYPEID_PLAYER ) - ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); - - return true; -} - -bool Unit::HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) -{ - SpellEntry const *triggeredByAuraSpell = triggeredByAura->GetSpellProto(); - - Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = 0; - Unit* target = pVictim; - int32 basepoints0 = 0; - - switch(triggeredByAuraSpell->SpellFamilyName) - { - case SPELLFAMILY_MAGE: - { - switch(triggeredByAuraSpell->Id) - { - // Focus Magic - case 54646: - { - Unit* caster = triggeredByAura->GetCaster(); - if(!caster) - return false; - - triggered_spell_id = 54648; - target = caster; - break; - } - } - } - } - - // processed charge only counting case - if(!triggered_spell_id) - return true; - - SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); - - if(!triggerEntry) - { - sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",triggeredByAuraSpell->Id,triggered_spell_id); - return false; - } - - // default case - if(!target || target!=this && !target->isAlive()) - return false; - - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) - return false; - - if(basepoints0) - CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); - else - CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); - - if( cooldown && GetTypeId()==TYPEID_PLAYER ) - ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); - - return true; -} - -bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) -{ - SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); - SpellEffectIndex effIndex = triggeredByAura->GetEffIndex(); - int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; - - Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - - // some dummy spells have trigger spell in spell data already (from 3.0.3) - uint32 triggered_spell_id = dummySpell->EffectApplyAuraName[effIndex] == SPELL_AURA_DUMMY ? dummySpell->EffectTriggerSpell[effIndex] : 0; - Unit* target = pVictim; - int32 basepoints[MAX_EFFECT_INDEX] = {0, 0, 0}; - - switch(dummySpell->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - { - switch (dummySpell->Id) - { - // Eye for an Eye - case 9799: - case 25988: - { - // return damage % to attacker but < 50% own total health - basepoints[0] = triggerAmount*int32(damage)/100; - if (basepoints[0] > (int32)GetMaxHealth()/2) - basepoints[0] = (int32)GetMaxHealth()/2; - - triggered_spell_id = 25997; - break; - } - // Sweeping Strikes (NPC spells may be) - case 18765: - case 35429: - { - // prevent chain of triggered spell from same triggered spell - if (procSpell && procSpell->Id == 26654) - return false; - - target = SelectRandomUnfriendlyTarget(pVictim); - if(!target) - return false; - - triggered_spell_id = 26654; - break; - } - // Twisted Reflection (boss spell) - case 21063: - triggered_spell_id = 21064; - break; - // Unstable Power - case 24658: - { - if (!procSpell || procSpell->Id == 24659) - return false; - // Need remove one 24659 aura - RemoveSingleSpellAurasFromStack(24659); - return true; - } - // Restless Strength - case 24661: - { - // Need remove one 24662 aura - RemoveSingleSpellAurasFromStack(24662); - return true; - } - // Adaptive Warding (Frostfire Regalia set) - case 28764: - { - if(!procSpell) - return false; - - // find Mage Armor - bool found = false; - AuraList const& mRegenInterupt = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); - for(AuraList::const_iterator iter = mRegenInterupt.begin(); iter != mRegenInterupt.end(); ++iter) - { - if(SpellEntry const* iterSpellProto = (*iter)->GetSpellProto()) - { - if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & UI64LIT(0x10000000))) - { - found=true; - break; - } - } - } - if(!found) - return false; - - switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) - { - case SPELL_SCHOOL_NORMAL: - case SPELL_SCHOOL_HOLY: - return false; // ignored - case SPELL_SCHOOL_FIRE: triggered_spell_id = 28765; break; - case SPELL_SCHOOL_NATURE: triggered_spell_id = 28768; break; - case SPELL_SCHOOL_FROST: triggered_spell_id = 28766; break; - case SPELL_SCHOOL_SHADOW: triggered_spell_id = 28769; break; - case SPELL_SCHOOL_ARCANE: triggered_spell_id = 28770; break; - default: - return false; - } - - target = this; - break; - } - // Obsidian Armor (Justice Bearer`s Pauldrons shoulder) - case 27539: - { - if(!procSpell) - return false; - - switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) - { - case SPELL_SCHOOL_NORMAL: - return false; // ignore - case SPELL_SCHOOL_HOLY: triggered_spell_id = 27536; break; - case SPELL_SCHOOL_FIRE: triggered_spell_id = 27533; break; - case SPELL_SCHOOL_NATURE: triggered_spell_id = 27538; break; - case SPELL_SCHOOL_FROST: triggered_spell_id = 27534; break; - case SPELL_SCHOOL_SHADOW: triggered_spell_id = 27535; break; - case SPELL_SCHOOL_ARCANE: triggered_spell_id = 27540; break; - default: - return false; - } - - target = this; - break; - } - // Mana Leech (Passive) (Priest Pet Aura) - case 28305: - { - // Cast on owner - target = GetOwner(); - if(!target) - return false; - - triggered_spell_id = 34650; - break; - } - // Divine purpose - case 31871: - case 31872: - { - // Roll chane - if (!roll_chance_i(triggerAmount)) - return false; - - // Remove any stun effect on target - AuraMap& Auras = pVictim->GetAuras(); - for(AuraMap::const_iterator iter = Auras.begin(); iter != Auras.end();) - { - SpellEntry const *spell = iter->second->GetSpellProto(); - if( spell->Mechanic == MECHANIC_STUN || - spell->EffectMechanic[iter->second->GetEffIndex()] == MECHANIC_STUN) - { - pVictim->RemoveAurasDueToSpell(spell->Id); - iter = Auras.begin(); - } - else - ++iter; - } - return true; - } - // Mark of Malice - case 33493: - { - // Cast finish spell at last charge - if (triggeredByAura->GetAuraCharges() > 1) - return false; - - target = this; - triggered_spell_id = 33494; - break; - } - // Vampiric Aura (boss spell) - case 38196: - { - basepoints[0] = 3 * damage; // 300% - if (basepoints[0] < 0) - return false; - - triggered_spell_id = 31285; - target = this; - break; - } - // Aura of Madness (Darkmoon Card: Madness trinket) - //===================================================== - // 39511 Sociopath: +35 strength (Paladin, Rogue, Druid, Warrior) - // 40997 Delusional: +70 attack power (Rogue, Hunter, Paladin, Warrior, Druid) - // 40998 Kleptomania: +35 agility (Warrior, Rogue, Paladin, Hunter, Druid) - // 40999 Megalomania: +41 damage/healing (Druid, Shaman, Priest, Warlock, Mage, Paladin) - // 41002 Paranoia: +35 spell/melee/ranged crit strike rating (All classes) - // 41005 Manic: +35 haste (spell, melee and ranged) (All classes) - // 41009 Narcissism: +35 intellect (Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter) - // 41011 Martyr Complex: +35 stamina (All classes) - // 41406 Dementia: Every 5 seconds either gives you +5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) - // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) - case 39446: - { - if(GetTypeId() != TYPEID_PLAYER) - return false; - - // Select class defined buff - switch (getClass()) - { - case CLASS_PALADIN: // 39511,40997,40998,40999,41002,41005,41009,41011,41409 - case CLASS_DRUID: // 39511,40997,40998,40999,41002,41005,41009,41011,41409 - { - uint32 RandomSpell[]={39511,40997,40998,40999,41002,41005,41009,41011,41409}; - triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; - break; - } - case CLASS_ROGUE: // 39511,40997,40998,41002,41005,41011 - case CLASS_WARRIOR: // 39511,40997,40998,41002,41005,41011 - { - uint32 RandomSpell[]={39511,40997,40998,41002,41005,41011}; - triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; - break; - } - case CLASS_PRIEST: // 40999,41002,41005,41009,41011,41406,41409 - case CLASS_SHAMAN: // 40999,41002,41005,41009,41011,41406,41409 - case CLASS_MAGE: // 40999,41002,41005,41009,41011,41406,41409 - case CLASS_WARLOCK: // 40999,41002,41005,41009,41011,41406,41409 - { - uint32 RandomSpell[]={40999,41002,41005,41009,41011,41406,41409}; - triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; - break; - } - case CLASS_HUNTER: // 40997,40999,41002,41005,41009,41011,41406,41409 - { - uint32 RandomSpell[]={40997,40999,41002,41005,41009,41011,41406,41409}; - triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; - break; - } - default: - return false; - } - - target = this; - if (roll_chance_i(10)) - ((Player*)this)->Say("This is Madness!", LANG_UNIVERSAL); - break; - } - // Sunwell Exalted Caster Neck (Shattered Sun Pendant of Acumen neck) - // cast 45479 Light's Wrath if Exalted by Aldor - // cast 45429 Arcane Bolt if Exalted by Scryers - case 45481: - { - if(GetTypeId() != TYPEID_PLAYER) - return false; - - // Get Aldor reputation rank - if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45479; - break; - } - // Get Scryers reputation rank - if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) - { - // triggered at positive/self casts also, current attack target used then - if(IsFriendlyTo(target)) - { - target = getVictim(); - if(!target) - { - uint64 selected_guid = ((Player *)this)->GetSelection(); - target = ObjectAccessor::GetUnit(*this,selected_guid); - if(!target) - return false; - } - if(IsFriendlyTo(target)) - return false; - } - - triggered_spell_id = 45429; - break; - } - return false; - } - // Sunwell Exalted Melee Neck (Shattered Sun Pendant of Might neck) - // cast 45480 Light's Strength if Exalted by Aldor - // cast 45428 Arcane Strike if Exalted by Scryers - case 45482: - { - if(GetTypeId() != TYPEID_PLAYER) - return false; - - // Get Aldor reputation rank - if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45480; - break; - } - // Get Scryers reputation rank - if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) - { - triggered_spell_id = 45428; - break; - } - return false; - } - // Sunwell Exalted Tank Neck (Shattered Sun Pendant of Resolve neck) - // cast 45431 Arcane Insight if Exalted by Aldor - // cast 45432 Light's Ward if Exalted by Scryers - case 45483: - { - if(GetTypeId() != TYPEID_PLAYER) - return false; - - // Get Aldor reputation rank - if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45432; - break; - } - // Get Scryers reputation rank - if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45431; - break; - } - return false; - } - // Sunwell Exalted Healer Neck (Shattered Sun Pendant of Restoration neck) - // cast 45478 Light's Salvation if Exalted by Aldor - // cast 45430 Arcane Surge if Exalted by Scryers - case 45484: - { - if(GetTypeId() != TYPEID_PLAYER) - return false; - - // Get Aldor reputation rank - if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) - { - target = this; - triggered_spell_id = 45478; - break; - } - // Get Scryers reputation rank - if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) - { - triggered_spell_id = 45430; - break; - } - return false; - } - /* - // Sunwell Exalted Caster Neck (??? neck) - // cast ??? Light's Wrath if Exalted by Aldor - // cast ??? Arcane Bolt if Exalted by Scryers*/ - case 46569: - return false; // old unused version - // Living Seed - case 48504: - { - triggered_spell_id = 48503; - basepoints[0] = triggerAmount; - target = this; - break; - } - // Vampiric Touch (generic, used by some boss) - case 52723: - case 60501: - { - triggered_spell_id = 52724; - basepoints[0] = damage / 2; - target = this; - break; - } - // Shadowfiend Death (Gain mana if pet dies with Glyph of Shadowfiend) - case 57989: - { - Unit *owner = GetOwner(); - if (!owner || owner->GetTypeId() != TYPEID_PLAYER) - return false; - - // Glyph of Shadowfiend (need cast as self cast for owner, no hidden cooldown) - owner->CastSpell(owner,58227,true,castItem,triggeredByAura); - return true; - } - // Glyph of Life Tap - case 63320: - triggered_spell_id = 63321; - break; - // Item - Shadowmourne Legendary - case 71903: - { - if (!roll_chance_i(triggerAmount)) - return false; - - Aura *aur = GetAura(71905, EFFECT_INDEX_0); - if (aur && uint32(aur->GetStackAmount() + 1) >= aur->GetSpellProto()->StackAmount) - { - RemoveAurasDueToSpell(71905); - CastSpell(this, 71904, true); // Chaos Bane - return true; - } - else - triggered_spell_id = 71905; - - break; - } - } - break; - } - case SPELLFAMILY_MAGE: - { - // Magic Absorption - if (dummySpell->SpellIconID == 459) // only this spell have SpellIconID == 459 and dummy aura - { - if (getPowerType() != POWER_MANA) - return false; - - // mana reward - basepoints[0] = (triggerAmount * GetMaxPower(POWER_MANA) / 100); - target = this; - triggered_spell_id = 29442; - break; - } - // Master of Elements - if (dummySpell->SpellIconID == 1920) - { - if(!procSpell) - return false; - - // mana cost save - int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost * triggerAmount/100; - if (basepoints[0] <=0) - return false; - - target = this; - triggered_spell_id = 29077; - break; - } - - // Arcane Potency - if (dummySpell->SpellIconID == 2120) - { - if(!procSpell) - return false; - - target = this; - switch (dummySpell->Id) - { - case 31571: triggered_spell_id = 57529; break; - case 31572: triggered_spell_id = 57531; break; - default: - sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u",dummySpell->Id); - return false; - } - break; - } - - // Hot Streak - if (dummySpell->SpellIconID == 2999) - { - if (effIndex != EFFECT_INDEX_0) - return true; - Aura *counter = GetAura(triggeredByAura->GetId(), EFFECT_INDEX_1); - if (!counter) - return true; - - // Count spell criticals in a row in second aura - Modifier *mod = counter->GetModifier(); - if (procEx & PROC_EX_CRITICAL_HIT) - { - mod->m_amount *=2; - if (mod->m_amount < 100) // not enough - return true; - // Crititcal counted -> roll chance - if (roll_chance_i(triggerAmount)) - CastSpell(this, 48108, true, castItem, triggeredByAura); - } - mod->m_amount = 25; - return true; - } - // Burnout - if (dummySpell->SpellIconID == 2998) - { - if(!procSpell) - return false; - - int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost * triggerAmount/100; - if (basepoints[0] <=0) - return false; - triggered_spell_id = 44450; - target = this; - break; - } - // Incanter's Regalia set (add trigger chance to Mana Shield) - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) - { - if (GetTypeId() != TYPEID_PLAYER) - return false; - - target = this; - triggered_spell_id = 37436; - break; - } - switch(dummySpell->Id) - { - // Ignite - case 11119: - case 11120: - case 12846: - case 12847: - case 12848: - { - switch (dummySpell->Id) - { - case 11119: basepoints[0] = int32(0.04f*damage); break; - case 11120: basepoints[0] = int32(0.08f*damage); break; - case 12846: basepoints[0] = int32(0.12f*damage); break; - case 12847: basepoints[0] = int32(0.16f*damage); break; - case 12848: basepoints[0] = int32(0.20f*damage); break; - default: - sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (IG)",dummySpell->Id); - return false; - } - - triggered_spell_id = 12654; - break; - } - // Combustion - case 11129: - { - //last charge and crit - if (triggeredByAura->GetAuraCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) ) - return true; // charge counting (will removed) - - CastSpell(this, 28682, true, castItem, triggeredByAura); - return (procEx & PROC_EX_CRITICAL_HIT); // charge update only at crit hits, no hidden cooldowns - } - // Glyph of Ice Block - case 56372: - { - if (GetTypeId() != TYPEID_PLAYER) - return false; - - // not 100% safe with client version switches but for 3.1.3 no spells with cooldown that can have mage player except Frost Nova. - ((Player*)this)->RemoveSpellCategoryCooldown(35, true); - return true; - } - // Glyph of Polymorph - case 56375: - { - if (!pVictim || !pVictim->isAlive()) - return false; - - pVictim->RemoveSpellsCausingAura(SPELL_AURA_PERIODIC_DAMAGE); - pVictim->RemoveSpellsCausingAura(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); - return true; - } - // Blessing of Ancient Kings - case 64411: - { - // for DOT procs - if (!IsPositiveSpell(procSpell->Id)) - return false; - - triggered_spell_id = 64413; - basepoints[0] = damage * 15 / 100; - break; - } - } - break; - } - case SPELLFAMILY_WARRIOR: - { - // Retaliation - if (dummySpell->SpellFamilyFlags == UI64LIT(0x0000000800000000)) - { - // check attack comes not from behind - if (!HasInArc(M_PI_F, pVictim)) - return false; - - triggered_spell_id = 22858; - break; - } - // Second Wind - if (dummySpell->SpellIconID == 1697) - { - // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example) - if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) - return false; - // Need stun or root mechanic - if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_ROOT_AND_STUN_MASK)) - return false; - - switch (dummySpell->Id) - { - case 29838: triggered_spell_id=29842; break; - case 29834: triggered_spell_id=29841; break; - case 42770: triggered_spell_id=42771; break; - default: - sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (SW)",dummySpell->Id); - return false; - } - - target = this; - break; - } - // Damage Shield - if (dummySpell->SpellIconID == 3214) - { - triggered_spell_id = 59653; - basepoints[0] = GetShieldBlockValue() * triggerAmount / 100; - break; - } - - // Sweeping Strikes - if (dummySpell->Id == 12328) - { - // prevent chain of triggered spell from same triggered spell - if(procSpell && procSpell->Id == 26654) - return false; - - target = SelectRandomUnfriendlyTarget(pVictim); - if(!target) - return false; - - triggered_spell_id = 26654; - break; - } - break; - } - case SPELLFAMILY_WARLOCK: - { - // Seed of Corruption - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) - { - Modifier* mod = triggeredByAura->GetModifier(); - // if damage is more than need or target die from damage deal finish spell - if( mod->m_amount <= (int32)damage || GetHealth() <= damage ) - { - // remember guid before aura delete - uint64 casterGuid = triggeredByAura->GetCasterGUID(); - - // Remove aura (before cast for prevent infinite loop handlers) - RemoveAurasDueToSpell(triggeredByAura->GetId()); - - // Cast finish spell (triggeredByAura already not exist!) - CastSpell(this, 27285, true, castItem, NULL, casterGuid); - return true; // no hidden cooldown - } - - // Damage counting - mod->m_amount-=damage; - return true; - } - // Seed of Corruption (Mobs cast) - no die req - if (dummySpell->SpellFamilyFlags == UI64LIT(0x0) && dummySpell->SpellIconID == 1932) - { - Modifier* mod = triggeredByAura->GetModifier(); - // if damage is more than need deal finish spell - if( mod->m_amount <= (int32)damage ) - { - // remember guid before aura delete - uint64 casterGuid = triggeredByAura->GetCasterGUID(); - - // Remove aura (before cast for prevent infinite loop handlers) - RemoveAurasDueToSpell(triggeredByAura->GetId()); - - // Cast finish spell (triggeredByAura already not exist!) - CastSpell(this, 32865, true, castItem, NULL, casterGuid); - return true; // no hidden cooldown - } - // Damage counting - mod->m_amount-=damage; - return true; - } - // Fel Synergy - if (dummySpell->SpellIconID == 3222) - { - target = GetPet(); - if (!target) - return false; - basepoints[0] = damage * triggerAmount / 100; - triggered_spell_id = 54181; - break; - } - switch(dummySpell->Id) - { - // Nightfall & Glyph of Corruption - case 18094: - case 18095: - case 56218: - { - target = this; - triggered_spell_id = 17941; - break; - } - //Soul Leech - case 30293: - case 30295: - case 30296: - { - // health - basepoints[0] = int32(damage*triggerAmount/100); - target = this; - triggered_spell_id = 30294; - break; - } - // Shadowflame (Voidheart Raiment set bonus) - case 37377: - { - triggered_spell_id = 37379; - break; - } - // Pet Healing (Corruptor Raiment or Rift Stalker Armor) - case 37381: - { - target = GetPet(); - if (!target) - return false; - - // heal amount - basepoints[0] = damage * triggerAmount/100; - triggered_spell_id = 37382; - break; - } - // Shadowflame Hellfire (Voidheart Raiment set bonus) - case 39437: - { - triggered_spell_id = 37378; - break; - } - // Siphon Life - case 63108: - { - if (triggeredByAura->GetEffIndex() != EFFECT_INDEX_0) - return false; - - // Glyph of Siphon Life - if (Aura *aur = GetAura(56216, EFFECT_INDEX_0)) - triggerAmount += triggerAmount * aur->GetModifier()->m_amount / 100; - - basepoints[0] = int32(damage * triggerAmount / 100); - triggered_spell_id = 63106; - break; - } - } - break; - } - case SPELLFAMILY_PRIEST: - { - // Vampiric Touch - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) - { - if(!pVictim || !pVictim->isAlive()) - return false; - - // pVictim is caster of aura - if(triggeredByAura->GetCasterGUID() != pVictim->GetGUID()) - return false; - - // Energize 0.25% of max. mana - pVictim->CastSpell(pVictim,57669,true,castItem,triggeredByAura); - return true; // no hidden cooldown - } - - switch(dummySpell->SpellIconID) - { - // Improved Shadowform - case 217: - { - if(!roll_chance_i(triggerAmount)) - return false; - - RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); - RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED); - break; - } - // Divine Aegis - case 2820: - { - basepoints[0] = damage * triggerAmount/100; - triggered_spell_id = 47753; - break; - } - // Empowered Renew - case 3021: - { - if (!procSpell) - return false; - - // avoid double triggering from 2 auras - if (triggeredByAura->GetEffIndex() != EFFECT_INDEX_1) - return false; - - - // Renew - Aura* healingAura = pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_PRIEST, UI64LIT(0x40), 0, GetGUID()); - if (!healingAura) - return false; - - int32 healingfromticks = healingAura->GetModifier()->m_amount * GetSpellAuraMaxTicks(procSpell); - - basepoints[0] = healingfromticks * triggerAmount / 100; - triggered_spell_id = 63544; - break; - } - // Improved Devouring Plague - case 3790: - { - if (!procSpell) - return false; - - if (triggeredByAura->GetEffIndex() != EFFECT_INDEX_1) - return false; - - Aura* leachAura = pVictim->GetAura(SPELL_AURA_PERIODIC_LEECH, SPELLFAMILY_PRIEST, UI64LIT(0x02000000), NULL, GetGUID()); - if (!leachAura) - return false; - - int32 damagefromticks = leachAura->GetModifier()->m_amount * GetSpellAuraMaxTicks(procSpell); - basepoints[0] = damagefromticks * triggerAmount / 100; - triggered_spell_id = 63675; - break; - } - } - - switch(dummySpell->Id) - { - // Vampiric Embrace - case 15286: - { - // Return if self damage - if (this == pVictim) - return false; - - // Heal amount - Self/Team - int32 team = triggerAmount*damage/500; - int32 self = triggerAmount*damage/100 - team; - CastCustomSpell(this,15290,&team,&self,NULL,true,castItem,triggeredByAura); - return true; // no hidden cooldown - } - // Priest Tier 6 Trinket (Ashtongue Talisman of Acumen) - case 40438: - { - // Shadow Word: Pain - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) - triggered_spell_id = 40441; - // Renew - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) - triggered_spell_id = 40440; - else - return false; - - target = this; - break; - } - // Oracle Healing Bonus ("Garments of the Oracle" set) - case 26169: - { - // heal amount - basepoints[0] = int32(damage * 10/100); - target = this; - triggered_spell_id = 26170; - break; - } - // Frozen Shadoweave (Shadow's Embrace set) warning! its not only priest set - case 39372: - { - if(!procSpell || (GetSpellSchoolMask(procSpell) & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW))==0 ) - return false; - - // heal amount - basepoints[0] = damage * triggerAmount/100; - target = this; - triggered_spell_id = 39373; - break; - } - // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus) - case 28809: - { - triggered_spell_id = 28810; - break; - } - // Glyph of Dispel Magic - case 55677: - { - if(!target->IsFriendlyTo(this)) - return false; - - basepoints[0] = int32(target->GetMaxHealth() * triggerAmount / 100); - // triggered_spell_id in spell data - break; - } - } - break; - } - case SPELLFAMILY_DRUID: - { - switch(dummySpell->Id) - { - // Leader of the Pack - case 24932: - { - // dummy m_amount store health percent (!=0 if Improved Leader of the Pack applied) - int32 heal_percent = triggeredByAura->GetModifier()->m_amount; - if (!heal_percent) - return false; - - // check explicitly only to prevent mana cast when halth cast cooldown - if (cooldown && ((Player*)this)->HasSpellCooldown(34299)) - return false; - - // health - triggered_spell_id = 34299; - basepoints[0] = GetMaxHealth() * heal_percent / 100; - target = this; - - // mana to caster - if (triggeredByAura->GetCasterGUID() == GetGUID()) - { - if (SpellEntry const* manaCastEntry = sSpellStore.LookupEntry(60889)) - { - int32 mana_percent = manaCastEntry->CalculateSimpleValue(EFFECT_INDEX_0) * heal_percent; - CastCustomSpell(this, manaCastEntry, &mana_percent, NULL, NULL, true, castItem, triggeredByAura); - } - } - break; - } - // Healing Touch (Dreamwalker Raiment set) - case 28719: - { - // mana back - basepoints[0] = int32(procSpell->manaCost * 30 / 100); - target = this; - triggered_spell_id = 28742; - break; - } - // Healing Touch Refund (Idol of Longevity trinket) - case 28847: - { - target = this; - triggered_spell_id = 28848; - break; - } - // Mana Restore (Malorne Raiment set / Malorne Regalia set) - case 37288: - case 37295: - { - target = this; - triggered_spell_id = 37238; - break; - } - // Druid Tier 6 Trinket - case 40442: - { - float chance; - - // Starfire - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) - { - triggered_spell_id = 40445; - chance = 25.0f; - } - // Rejuvenation - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) - { - triggered_spell_id = 40446; - chance = 25.0f; - } - // Mangle (Bear) and Mangle (Cat) - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000044000000000)) - { - triggered_spell_id = 40452; - chance = 40.0f; - } - else - return false; - - if (!roll_chance_f(chance)) - return false; - - target = this; - break; - } - // Maim Interrupt - case 44835: - { - // Deadly Interrupt Effect - triggered_spell_id = 32747; - break; - } - // Glyph of Rejuvenation - case 54754: - { - // less 50% health - if (pVictim->GetMaxHealth() < 2 * pVictim->GetHealth()) - return false; - basepoints[0] = triggerAmount * damage / 100; - triggered_spell_id = 54755; - break; - } - // Item - Druid T10 Restoration 4P Bonus (Rejuvenation) - case 70664: - { - if (!procSpell || GetTypeId() != TYPEID_PLAYER) - return false; - - float radius; - if (procSpell->EffectRadiusIndex[EFFECT_INDEX_0]) - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(procSpell->EffectRadiusIndex[EFFECT_INDEX_0])); - else - radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(procSpell->rangeIndex)); - - ((Player*)this)->ApplySpellMod(procSpell->Id, SPELLMOD_RADIUS, radius,NULL); - - Unit *second = pVictim->SelectRandomFriendlyTarget(pVictim, radius); - - if (!second) - return false; - - pVictim->CastSpell(second, procSpell, true, NULL, triggeredByAura, GetGUID()); - return true; - } - } - // Eclipse - if (dummySpell->SpellIconID == 2856) - { - if (!procSpell) - return false; - // Only 0 aura can proc - if (effIndex != EFFECT_INDEX_0) - return true; - // Wrath crit - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) - { - if (HasAura(48517)) - return false; - if (!roll_chance_i(60)) - return false; - triggered_spell_id = 48518; - target = this; - break; - } - // Starfire crit - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) - { - if (HasAura(48518)) - return false; - triggered_spell_id = 48517; - target = this; - break; - } - return false; - } - // Living Seed - else if (dummySpell->SpellIconID == 2860) - { - triggered_spell_id = 48504; - basepoints[0] = triggerAmount * damage / 100; - break; - } - break; - } - case SPELLFAMILY_ROGUE: - { - switch(dummySpell->Id) - { - // Deadly Throw Interrupt - case 32748: - { - // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw - if (this == pVictim) - return false; - - triggered_spell_id = 32747; - break; - } - } - // Cut to the Chase - if (dummySpell->SpellIconID == 2909) - { - // "refresh your Slice and Dice duration to its 5 combo point maximum" - // lookup Slice and Dice - AuraList const& sd = GetAurasByType(SPELL_AURA_MOD_HASTE); - for(AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr) - { - SpellEntry const *spellProto = (*itr)->GetSpellProto(); - if (spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && - (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000040000))) - { - (*itr)->SetAuraMaxDuration(GetSpellMaxDuration(spellProto)); - (*itr)->RefreshAura(); - return true; - } - } - return false; - } - // Deadly Brew - if (dummySpell->SpellIconID == 2963) - { - triggered_spell_id = 44289; - break; - } - // Quick Recovery - if (dummySpell->SpellIconID == 2116) - { - if(!procSpell) - return false; - - // energy cost save - basepoints[0] = procSpell->manaCost * triggerAmount/100; - if (basepoints[0] <= 0) - return false; - - target = this; - triggered_spell_id = 31663; - break; - } - break; - } - case SPELLFAMILY_HUNTER: - { - // Aspect of the Viper - if (dummySpell->SpellFamilyFlags & UI64LIT(0x4000000000000)) - { - uint32 maxmana = GetMaxPower(POWER_MANA); - basepoints[0] = int32(maxmana* GetAttackTime(RANGED_ATTACK)/1000.0f/100.0f); - - target = this; - triggered_spell_id = 34075; - break; - } - // Thrill of the Hunt - if (dummySpell->SpellIconID == 2236) - { - if (!procSpell) - return false; - - // mana cost save - int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = mana * 40/100; - if (basepoints[0] <= 0) - return false; - - target = this; - triggered_spell_id = 34720; - break; - } - // Hunting Party - if (dummySpell->SpellIconID == 3406) - { - triggered_spell_id = 57669; - target = this; - break; - } - // Lock and Load - if ( dummySpell->SpellIconID == 3579 ) - { - // Proc only from periodic (from trap activation proc another aura of this spell) - if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC) || !roll_chance_i(triggerAmount)) - return false; - triggered_spell_id = 56453; - target = this; - break; - } - // Rapid Recuperation - if ( dummySpell->SpellIconID == 3560 ) - { - // This effect only from Rapid Killing (mana regen) - if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0100000000000000))) - return false; - - target = this; - - switch(dummySpell->Id) - { - case 53228: // Rank 1 - triggered_spell_id = 56654; - break; - case 53232: // Rank 2 - triggered_spell_id = 58882; - break; - } - break; - } - // Glyph of Mend Pet - if(dummySpell->Id == 57870) - { - pVictim->CastSpell(pVictim, 57894, true, NULL, NULL, GetGUID()); - return true; - } - break; - } - case SPELLFAMILY_PALADIN: - { - // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) - if ((dummySpell->SpellFamilyFlags & UI64LIT(0x000000008000000)) && effIndex == EFFECT_INDEX_0) - { - triggered_spell_id = 25742; - float ap = GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); - if (holy < 0) - holy = 0; - basepoints[0] = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000; - break; - } - // Righteous Vengeance - if (dummySpell->SpellIconID == 3025) - { - // 4 damage tick - basepoints[0] = triggerAmount*damage/400; - triggered_spell_id = 61840; - break; - } - // Sheath of Light - if (dummySpell->SpellIconID == 3030) - { - // 4 healing tick - basepoints[0] = triggerAmount*damage/400; - triggered_spell_id = 54203; - break; - } - switch(dummySpell->Id) - { - // Judgement of Light - case 20185: - { - basepoints[0] = int32( pVictim->GetMaxHealth() * triggeredByAura->GetModifier()->m_amount / 100 ); - pVictim->CastCustomSpell(pVictim, 20267, &basepoints[0], NULL, NULL, true, NULL, triggeredByAura); - return true; - } - // Judgement of Wisdom - case 20186: - { - if (pVictim->getPowerType() == POWER_MANA) - { - // 2% of maximum base mana - basepoints[0] = int32(pVictim->GetCreateMana() * 2 / 100); - pVictim->CastCustomSpell(pVictim, 20268, &basepoints[0], NULL, NULL, true, NULL, triggeredByAura); - } - return true; - } - // Heart of the Crusader (Rank 1) - case 20335: - triggered_spell_id = 21183; - break; - // Heart of the Crusader (Rank 2) - case 20336: - triggered_spell_id = 54498; - break; - // Heart of the Crusader (Rank 3) - case 20337: - triggered_spell_id = 54499; - break; - case 20911: // Blessing of Sanctuary - case 25899: // Greater Blessing of Sanctuary - { - target = this; - switch (target->getPowerType()) - { - case POWER_MANA: - triggered_spell_id = 57319; - break; - default: - return false; - } - break; - } - // Holy Power (Redemption Armor set) - case 28789: - { - if(!pVictim) - return false; - - // Set class defined buff - switch (pVictim->getClass()) - { - case CLASS_PALADIN: - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_DRUID: - triggered_spell_id = 28795; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. - break; - case CLASS_MAGE: - case CLASS_WARLOCK: - triggered_spell_id = 28793; // Increases the friendly target's spell damage and healing by up to $s1 for $d. - break; - case CLASS_HUNTER: - case CLASS_ROGUE: - triggered_spell_id = 28791; // Increases the friendly target's attack power by $s1 for $d. - break; - case CLASS_WARRIOR: - triggered_spell_id = 28790; // Increases the friendly target's armor - break; - default: - return false; - } - break; - } - // Spiritual Attunement - case 31785: - case 33776: - { - // if healed by another unit (pVictim) - if (this == pVictim) - return false; - - // heal amount - basepoints[0] = triggerAmount*damage/100; - target = this; - triggered_spell_id = 31786; - break; - } - // Seal of Vengeance (damage calc on apply aura) - case 31801: - { - if (effIndex != EFFECT_INDEX_0) // effect 1,2 used by seal unleashing code - return false; - - // At melee attack or Hammer of the Righteous spell damage considered as melee attack - if ((procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT) || (procSpell && procSpell->Id == 53595) ) - triggered_spell_id = 31803; // Holy Vengeance - - // Add 5-stack effect from Holy Vengeance - int8 stacks = 0; - AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) - { - if( ((*itr)->GetId() == 31803) && (*itr)->GetCasterGUID()==GetGUID()) - { - stacks = (*itr)->GetStackAmount(); - break; - } - } - if(stacks >= 5) - CastSpell(target,42463,true,NULL,triggeredByAura); - break; - } - // Judgements of the Wise - case 31876: - case 31877: - case 31878: - // triggered only at casted Judgement spells, not at additional Judgement effects - if(!procSpell || procSpell->Category != 1210) - return false; - - target = this; - triggered_spell_id = 31930; - - // Replenishment - CastSpell(this, 57669, true, NULL, triggeredByAura); - break; - // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) - case 40470: - { - if (!procSpell) - return false; - - float chance; - - // Flash of light/Holy light - if (procSpell->SpellFamilyFlags & UI64LIT(0x00000000C0000000)) - { - triggered_spell_id = 40471; - chance = 15.0f; - } - // Judgement (any) - else if (GetSpellSpecific(procSpell->Id)==SPELL_JUDGEMENT) - { - triggered_spell_id = 40472; - chance = 50.0f; - } - else - return false; - - if (!roll_chance_f(chance)) - return false; - - break; - } - // Light's Beacon (heal target area aura) - case 53651: - { - // not do bonus heal for explicit beacon focus healing - if (GetGUID() == triggeredByAura->GetCasterGUID()) - return false; - - // beacon - Unit* beacon = triggeredByAura->GetCaster(); - if (!beacon) - return false; - - // find caster main aura at beacon - Aura* dummy = NULL; - Unit::AuraList const& baa = beacon->GetAurasByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL); - for(Unit::AuraList::const_iterator i = baa.begin(); i != baa.end(); ++i) - { - if ((*i)->GetId() == 53563 && (*i)->GetCasterGUID() == pVictim->GetGUID()) - { - dummy = (*i); - break; - } - } - - // original heal must be form beacon caster - if (!dummy) - return false; - - triggered_spell_id = 53652; // Beacon of Light - basepoints[0] = triggeredByAura->GetModifier()->m_amount*damage/100; - - // cast with original caster set but beacon to beacon for apply caster mods and avoid LoS check - beacon->CastCustomSpell(beacon,triggered_spell_id,&basepoints[0],NULL,NULL,true,castItem,triggeredByAura,pVictim->GetGUID()); - return true; - } - // Seal of Corruption (damage calc on apply aura) - case 53736: - { - if (effIndex != EFFECT_INDEX_0) // effect 1,2 used by seal unleashing code - return false; - - // At melee attack or Hammer of the Righteous spell damage considered as melee attack - if ((procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT) || (procSpell && procSpell->Id == 53595)) - triggered_spell_id = 53742; // Blood Corruption - - // Add 5-stack effect from Blood Corruption - int8 stacks = 0; - AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) - { - if( ((*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==GetGUID()) - { - stacks = (*itr)->GetStackAmount(); - break; - } - } - if(stacks >= 5) - CastSpell(target,53739,true,NULL,triggeredByAura); - break; - } - // Glyph of Holy Light - case 54937: - { - triggered_spell_id = 54968; - basepoints[0] = triggerAmount*damage/100; - break; - } - // Glyph of Divinity - case 54939: - { - // Lookup base amount mana restore - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - { - if (procSpell->Effect[i] == SPELL_EFFECT_ENERGIZE) - { - int32 mana = procSpell->CalculateSimpleValue(SpellEffectIndex(i)); - CastCustomSpell(this, 54986, NULL, &mana, NULL, true, castItem, triggeredByAura); - break; - } - } - return true; - } - // Sacred Shield (buff) - case 58597: - { - triggered_spell_id = 66922; - SpellEntry const* triggeredEntry = sSpellStore.LookupEntry(triggered_spell_id); - if (!triggeredEntry) - return false; - - basepoints[0] = int32(damage / (GetSpellDuration(triggeredEntry) / triggeredEntry->EffectAmplitude[EFFECT_INDEX_0])); - target = this; - break; - } - // Sacred Shield (talent rank) - case 53601: - { - // triggered_spell_id in spell data - target = this; - break; - } - } - break; - } - case SPELLFAMILY_SHAMAN: - { - switch(dummySpell->Id) - { - // Totemic Power (The Earthshatterer set) - case 28823: - { - if( !pVictim ) - return false; - - // Set class defined buff - switch (pVictim->getClass()) - { - case CLASS_PALADIN: - case CLASS_PRIEST: - case CLASS_SHAMAN: - case CLASS_DRUID: - triggered_spell_id = 28824; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. - break; - case CLASS_MAGE: - case CLASS_WARLOCK: - triggered_spell_id = 28825; // Increases the friendly target's spell damage and healing by up to $s1 for $d. - break; - case CLASS_HUNTER: - case CLASS_ROGUE: - triggered_spell_id = 28826; // Increases the friendly target's attack power by $s1 for $d. - break; - case CLASS_WARRIOR: - triggered_spell_id = 28827; // Increases the friendly target's armor - break; - default: - return false; - } - break; - } - // Lesser Healing Wave (Totem of Flowing Water Relic) - case 28849: - { - target = this; - triggered_spell_id = 28850; - break; - } - // Windfury Weapon (Passive) 1-5 Ranks - case 33757: - { - if(GetTypeId()!=TYPEID_PLAYER) - return false; - - if(!castItem || !castItem->IsEquipped()) - return false; - - // custom cooldown processing case - if( cooldown && ((Player*)this)->HasSpellCooldown(dummySpell->Id)) - return false; - - // Now amount of extra power stored in 1 effect of Enchant spell - // Get it by item enchant id - uint32 spellId; - switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT))) - { - case 283: spellId = 8232; break; // 1 Rank - case 284: spellId = 8235; break; // 2 Rank - case 525: spellId = 10486; break; // 3 Rank - case 1669:spellId = 16362; break; // 4 Rank - case 2636:spellId = 25505; break; // 5 Rank - case 3785:spellId = 58801; break; // 6 Rank - case 3786:spellId = 58803; break; // 7 Rank - case 3787:spellId = 58804; break; // 8 Rank - default: - { - sLog.outError("Unit::HandleDummyAuraProc: non handled item enchantment (rank?) %u for spell id: %u (Windfury)", - castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)),dummySpell->Id); - return false; - } - } - - SpellEntry const* windfurySpellEntry = sSpellStore.LookupEntry(spellId); - if(!windfurySpellEntry) - { - sLog.outError("Unit::HandleDummyAuraProc: non existed spell id: %u (Windfury)",spellId); - return false; - } - - int32 extra_attack_power = CalculateSpellDamage(pVictim, windfurySpellEntry, EFFECT_INDEX_1); - - // Off-Hand case - if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND) - { - // Value gained from additional AP - basepoints[0] = int32(extra_attack_power/14.0f * GetAttackTime(OFF_ATTACK)/1000/2); - triggered_spell_id = 33750; - } - // Main-Hand case - else - { - // Value gained from additional AP - basepoints[0] = int32(extra_attack_power/14.0f * GetAttackTime(BASE_ATTACK)/1000); - triggered_spell_id = 25504; - } - - // apply cooldown before cast to prevent processing itself - if( cooldown ) - ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); - - // Attack Twice - for ( uint32 i = 0; i<2; ++i ) - CastCustomSpell(pVictim,triggered_spell_id,&basepoints[0],NULL,NULL,true,castItem,triggeredByAura); - - return true; - } - // Shaman Tier 6 Trinket - case 40463: - { - if( !procSpell ) - return false; - - float chance; - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) - { - triggered_spell_id = 40465; // Lightning Bolt - chance = 15.0f; - } - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) - { - triggered_spell_id = 40465; // Lesser Healing Wave - chance = 10.0f; - } - else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) - { - triggered_spell_id = 40466; // Stormstrike - chance = 50.0f; - } - else - return false; - - if (!roll_chance_f(chance)) - return false; - - target = this; - break; - } - // Glyph of Healing Wave - case 55440: - { - // Not proc from self heals - if (this==pVictim) - return false; - basepoints[0] = triggerAmount * damage / 100; - target = this; - triggered_spell_id = 55533; - break; - } - // Spirit Hunt - case 58877: - { - // Cast on owner - target = GetOwner(); - if (!target) - return false; - basepoints[0] = triggerAmount * damage / 100; - triggered_spell_id = 58879; - break; - } - // Glyph of Totem of Wrath - case 63280: - { - Totem* totem = GetTotem(TOTEM_SLOT_FIRE); - if (!totem) - return false; - - // find totem aura bonus - AuraList const& spellPower = totem->GetAurasByType(SPELL_AURA_NONE); - for(AuraList::const_iterator i = spellPower.begin();i != spellPower.end(); ++i) - { - // select proper aura for format aura type in spell proto - if ((*i)->GetTarget()==totem && (*i)->GetSpellProto()->EffectApplyAuraName[(*i)->GetEffIndex()] == SPELL_AURA_MOD_HEALING_DONE && - (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000004000000)) - { - basepoints[0] = triggerAmount * (*i)->GetModifier()->m_amount / 100; - break; - } - } - - if (!basepoints[0]) - return false; - - basepoints[1] = basepoints[0]; - triggered_spell_id = 63283; // Totem of Wrath, caster bonus - target = this; - break; - } - // Shaman T8 Elemental 4P Bonus - case 64928: - { - basepoints[0] = int32( triggerAmount * damage / 100 ); - triggered_spell_id = 64930; // Electrified - break; - } - // Shaman T9 Elemental 4P Bonus - case 67228: - { - basepoints[0] = int32( triggerAmount * damage / 100 ); - triggered_spell_id = 71824; - break; - } - } - // Storm, Earth and Fire - if (dummySpell->SpellIconID == 3063) - { - // Earthbind Totem summon only - if(procSpell->Id != 2484) - return false; - - if (!roll_chance_i(triggerAmount)) - return false; - - triggered_spell_id = 64695; - break; - } - // Ancestral Awakening - if (dummySpell->SpellIconID == 3065) - { - triggered_spell_id = 52759; - basepoints[0] = triggerAmount * damage / 100; - target = this; - break; - } - // Earth Shield - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) - { - target = this; - basepoints[0] = triggerAmount; - - // Glyph of Earth Shield - if (Aura* aur = GetDummyAura(63279)) - { - int32 aur_mod = aur->GetModifier()->m_amount; - basepoints[0] = int32(basepoints[0] * (aur_mod + 100.0f) / 100.0f); - } - - triggered_spell_id = 379; - break; - } - // Improved Water Shield - if (dummySpell->SpellIconID == 2287) - { - // Lesser Healing Wave need aditional 60% roll - if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(60)) - return false; - // Chain Heal needs additional 30% roll - if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100)) && !roll_chance_i(30)) - return false; - // lookup water shield - AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); - for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) - { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000002000000000))) - { - uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; - CastSpell(this, spell, true, castItem, triggeredByAura); - return true; - } - } - return false; - } - // Lightning Overload - if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura - { - if(!procSpell || GetTypeId() != TYPEID_PLAYER || !pVictim ) - return false; - - // custom cooldown processing case - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(dummySpell->Id)) - return false; - - uint32 spellId = 0; - // Every Lightning Bolt and Chain Lightning spell have duplicate vs half damage and zero cost - switch (procSpell->Id) - { - // Lightning Bolt - case 403: spellId = 45284; break; // Rank 1 - case 529: spellId = 45286; break; // Rank 2 - case 548: spellId = 45287; break; // Rank 3 - case 915: spellId = 45288; break; // Rank 4 - case 943: spellId = 45289; break; // Rank 5 - case 6041: spellId = 45290; break; // Rank 6 - case 10391: spellId = 45291; break; // Rank 7 - case 10392: spellId = 45292; break; // Rank 8 - case 15207: spellId = 45293; break; // Rank 9 - case 15208: spellId = 45294; break; // Rank 10 - case 25448: spellId = 45295; break; // Rank 11 - case 25449: spellId = 45296; break; // Rank 12 - case 49237: spellId = 49239; break; // Rank 13 - case 49238: spellId = 49240; break; // Rank 14 - // Chain Lightning - case 421: spellId = 45297; break; // Rank 1 - case 930: spellId = 45298; break; // Rank 2 - case 2860: spellId = 45299; break; // Rank 3 - case 10605: spellId = 45300; break; // Rank 4 - case 25439: spellId = 45301; break; // Rank 5 - case 25442: spellId = 45302; break; // Rank 6 - case 49270: spellId = 49268; break; // Rank 7 - case 49271: spellId = 49269; break; // Rank 8 - default: - sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id); - return false; - } - // No thread generated mod - // TODO: exist special flag in spell attributes for this, need found and use! - SpellModifier *mod = new SpellModifier(SPELLMOD_THREAT,SPELLMOD_PCT,-100,triggeredByAura); - - ((Player*)this)->AddSpellMod(mod, true); - - // Remove cooldown (Chain Lightning - have Category Recovery time) - if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000002)) - ((Player*)this)->RemoveSpellCooldown(spellId); - - CastSpell(pVictim, spellId, true, castItem, triggeredByAura); - - ((Player*)this)->AddSpellMod(mod, false); - - if( cooldown && GetTypeId()==TYPEID_PLAYER ) - ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); - - return true; - } - // Static Shock - if(dummySpell->SpellIconID == 3059) - { - // lookup Lightning Shield - AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); - for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) - { - if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && - ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400))) - { - uint32 spell = 0; - switch ((*itr)->GetId()) - { - case 324: spell = 26364; break; - case 325: spell = 26365; break; - case 905: spell = 26366; break; - case 945: spell = 26367; break; - case 8134: spell = 26369; break; - case 10431: spell = 26370; break; - case 10432: spell = 26363; break; - case 25469: spell = 26371; break; - case 25472: spell = 26372; break; - case 49280: spell = 49278; break; - case 49281: spell = 49279; break; - default: - return false; - } - CastSpell(target, spell, true, castItem, triggeredByAura); - if ((*itr)->DropAuraCharge()) - RemoveSingleSpellAurasFromStack((*itr)->GetId()); - return true; - } - } - return false; - } - // Frozen Power - if (dummySpell->SpellIconID == 3780) - { - Unit *caster = triggeredByAura->GetCaster(); - - if (!procSpell || !caster) - return false; - - float distance = caster->GetDistance(pVictim); - int32 chance = triggerAmount; - - if (distance < 15.0f || !roll_chance_i(chance)) - return false; - - // make triggered cast apply after current damage spell processing for prevent remove by it - if(Spell* spell = GetCurrentSpell(CURRENT_GENERIC_SPELL)) - spell->AddTriggeredSpell(63685); - return true; - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Butchery - if (dummySpell->SpellIconID == 2664) - { - basepoints[0] = triggerAmount; - triggered_spell_id = 50163; - target = this; - break; - } - // Dancing Rune Weapon - if (dummySpell->Id == 49028) - { - // 1 dummy aura for dismiss rune blade - if (effIndex != EFFECT_INDEX_2) - return false; - // TODO: wite script for this "fights on its own, doing the same attacks" - // NOTE: Trigger here on every attack and spell cast - return false; - } - // Mark of Blood - if (dummySpell->Id == 49005) - { - // TODO: need more info (cooldowns/PPM) - triggered_spell_id = 61607; - break; - } - // Vendetta - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000010000)) - { - basepoints[0] = triggerAmount * GetMaxHealth() / 100; - triggered_spell_id = 50181; - target = this; - break; - } - // Necrosis - if (dummySpell->SpellIconID == 2709) - { - // only melee auto attack affected and Rune Strike - if (procSpell && procSpell->Id != 56815) - return false; - - basepoints[0] = triggerAmount * damage / 100; - triggered_spell_id = 51460; - break; - } - // Threat of Thassarian - if (dummySpell->SpellIconID == 2023) - { - // Must Dual Wield - if (!procSpell || !haveOffhandWeapon()) - return false; - // Chance as basepoints for dummy aura - if (!roll_chance_i(triggerAmount)) - return false; - - switch (procSpell->Id) - { - // Obliterate - case 49020: // Rank 1 - triggered_spell_id = 66198; break; - case 51423: // Rank 2 - triggered_spell_id = 66972; break; - case 51424: // Rank 3 - triggered_spell_id = 66973; break; - case 51425: // Rank 4 - triggered_spell_id = 66974; break; - // Frost Strike - case 49143: // Rank 1 - triggered_spell_id = 66196; break; - case 51416: // Rank 2 - triggered_spell_id = 66958; break; - case 51417: // Rank 3 - triggered_spell_id = 66959; break; - case 51418: // Rank 4 - triggered_spell_id = 66960; break; - case 51419: // Rank 5 - triggered_spell_id = 66961; break; - case 55268: // Rank 6 - triggered_spell_id = 66962; break; - // Plague Strike - case 45462: // Rank 1 - triggered_spell_id = 66216; break; - case 49917: // Rank 2 - triggered_spell_id = 66988; break; - case 49918: // Rank 3 - triggered_spell_id = 66989; break; - case 49919: // Rank 4 - triggered_spell_id = 66990; break; - case 49920: // Rank 5 - triggered_spell_id = 66991; break; - case 49921: // Rank 6 - triggered_spell_id = 66992; break; - // Death Strike - case 49998: // Rank 1 - triggered_spell_id = 66188; break; - case 49999: // Rank 2 - triggered_spell_id = 66950; break; - case 45463: // Rank 3 - triggered_spell_id = 66951; break; - case 49923: // Rank 4 - triggered_spell_id = 66952; break; - case 49924: // Rank 5 - triggered_spell_id = 66953; break; - // Rune Strike - case 56815: - triggered_spell_id = 66217; break; - // Blood Strike - case 45902: // Rank 1 - triggered_spell_id = 66215; break; - case 49926: // Rank 2 - triggered_spell_id = 66975; break; - case 49927: // Rank 3 - triggered_spell_id = 66976; break; - case 49928: // Rank 4 - triggered_spell_id = 66977; break; - case 49929: // Rank 5 - triggered_spell_id = 66978; break; - case 49930: // Rank 6 - triggered_spell_id = 66979; break; - default: - return false; - } - break; - } - // Runic Power Back on Snare/Root - if (dummySpell->Id == 61257) - { - // only for spells and hit/crit (trigger start always) and not start from self casted spells - if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) - return false; - // Need snare or root mechanic - if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_ROOT_AND_SNARE_MASK)) - return false; - triggered_spell_id = 61258; - target = this; - break; - } - // Wandering Plague - if (dummySpell->SpellIconID == 1614) - { - if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim))) - return false; - basepoints[0] = triggerAmount * damage / 100; - triggered_spell_id = 50526; - break; - } - // Blood-Caked Blade - if (dummySpell->SpellIconID == 138) - { - // only main hand melee auto attack affected and Rune Strike - if ((procFlag & PROC_FLAG_SUCCESSFUL_OFFHAND_HIT) || procSpell && procSpell->Id != 56815) - return false; - - // triggered_spell_id in spell data - break; - } - break; - } - default: - break; - } - - // processed charge only counting case - if(!triggered_spell_id) - return true; - - SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); - - if(!triggerEntry) - { - sLog.outError("Unit::HandleDummyAuraProc: Spell %u have not existed triggered spell %u",dummySpell->Id,triggered_spell_id); - return false; - } - - // default case - if(!target || target!=this && !target->isAlive()) - return false; - - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) - return false; - - if (basepoints[EFFECT_INDEX_0] || basepoints[EFFECT_INDEX_1] || basepoints[EFFECT_INDEX_2]) - CastCustomSpell(target, triggered_spell_id, - basepoints[EFFECT_INDEX_0] ? &basepoints[EFFECT_INDEX_0] : NULL, - basepoints[EFFECT_INDEX_1] ? &basepoints[EFFECT_INDEX_1] : NULL, - basepoints[EFFECT_INDEX_2] ? &basepoints[EFFECT_INDEX_2] : NULL, - true, castItem, triggeredByAura); - else - CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura); - - if (cooldown && GetTypeId()==TYPEID_PLAYER) - ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); - - return true; -} - -bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown) -{ - // Get triggered aura spell info - SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto(); - - // Basepoints of trigger aura - int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; - - // Set trigger spell id, target, custom basepoints - uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; - Unit* target = NULL; - int32 basepoints[MAX_EFFECT_INDEX] = {0, 0, 0}; - - if(triggeredByAura->GetModifier()->m_auraname == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE) - basepoints[0] = triggerAmount; - - Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - - // Try handle unknown trigger spells - // Custom requirements (not listed in procEx) Warning! damage dealing after this - // Custom triggered spells - switch (auraSpellInfo->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - switch(auraSpellInfo->Id) - { - //case 191: // Elemental Response - // switch (procSpell->School) - // { - // case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192; break; - // case SPELL_SCHOOL_FROST: trigger_spell_id = 34193; break; - // case SPELL_SCHOOL_ARCANE:trigger_spell_id = 34194; break; - // case SPELL_SCHOOL_NATURE:trigger_spell_id = 34195; break; - // case SPELL_SCHOOL_SHADOW:trigger_spell_id = 34196; break; - // case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197; break; - // case SPELL_SCHOOL_NORMAL:trigger_spell_id = 34198; break; - // } - // break; - //case 5301: break; // Defensive State (DND) - //case 7137: break: // Shadow Charge (Rank 1) - //case 7377: break: // Take Immune Periodic Damage - //case 13358: break; // Defensive State (DND) - //case 16092: break; // Defensive State (DND) - //case 18943: break; // Double Attack - //case 19194: break; // Double Attack - //case 19817: break; // Double Attack - //case 19818: break; // Double Attack - //case 22835: break; // Drunken Rage - // trigger_spell_id = 14822; break; - case 23780: // Aegis of Preservation (Aegis of Preservation trinket) - trigger_spell_id = 23781; - break; - //case 24949: break; // Defensive State 2 (DND) - case 27522: // Mana Drain Trigger - case 40336: // Mana Drain Trigger - // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target. - if (isAlive()) - CastSpell(this, 29471, true, castItem, triggeredByAura); - if (pVictim && pVictim->isAlive()) - CastSpell(pVictim, 27526, true, castItem, triggeredByAura); - return true; - case 31255: // Deadly Swiftness (Rank 1) - // whenever you deal damage to a target who is below 20% health. - if (pVictim->GetHealth() > pVictim->GetMaxHealth() / 5) - return false; - - target = this; - trigger_spell_id = 22588; - break; - //case 33207: break; // Gossip NPC Periodic - Fidget - case 33896: // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher) - trigger_spell_id = 33898; - break; - //case 34082: break; // Advantaged State (DND) - //case 34783: break: // Spell Reflection - //case 35205: break: // Vanish - //case 35321: break; // Gushing Wound - //case 36096: break: // Spell Reflection - //case 36207: break: // Steal Weapon - //case 36576: break: // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger - //case 37030: break; // Chaotic Temperament - //case 38363: break; // Gushing Wound - //case 39215: break; // Gushing Wound - //case 40250: break; // Improved Duration - //case 40329: break; // Demo Shout Sensor - //case 40364: break; // Entangling Roots Sensor - //case 41054: break; // Copy Weapon - // trigger_spell_id = 41055; break; - //case 41248: break; // Consuming Strikes - // trigger_spell_id = 41249; break; - //case 42730: break: // Woe Strike - //case 43453: break: // Rune Ward - //case 43504: break; // Alterac Valley OnKill Proc Aura - //case 44326: break: // Pure Energy Passive - //case 44526: break; // Hate Monster (Spar) (30 sec) - //case 44527: break; // Hate Monster (Spar Buddy) (30 sec) - //case 44819: break; // Hate Monster (Spar Buddy) (>30% Health) - //case 44820: break; // Hate Monster (Spar) (<30%) - case 45057: // Evasive Maneuvers (Commendation of Kael`thas trinket) - // reduce you below $s1% health - if (GetHealth() - damage > GetMaxHealth() * triggerAmount / 100) - return false; - break; - //case 45903: break: // Offensive State - //case 46146: break: // [PH] Ahune Spanky Hands - //case 46939: break; // Black Bow of the Betrayer - // trigger_spell_id = 29471; - gain mana - // 27526; - drain mana if possible - case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket) - // Pct value stored in dummy - basepoints[0] = pVictim->GetCreateHealth() * auraSpellInfo->CalculateSimpleValue(EFFECT_INDEX_1) / 100; - target = pVictim; - break; - //case 45205: break; // Copy Offhand Weapon - //case 45343: break; // Dark Flame Aura - //case 47300: break; // Dark Flame Aura - //case 48876: break; // Beast's Mark - // trigger_spell_id = 48877; break; - //case 49059: break; // Horde, Hate Monster (Spar Buddy) (>30% Health) - //case 50051: break; // Ethereal Pet Aura - //case 50689: break; // Blood Presence (Rank 1) - //case 50844: break; // Blood Mirror - //case 52856: break; // Charge - //case 54072: break; // Knockback Ball Passive - //case 54476: break; // Blood Presence - //case 54775: break; // Abandon Vehicle on Poly - case 57345: // Darkmoon Card: Greatness - { - float stat = 0.0f; - // strength - if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229;stat = GetStat(STAT_STRENGTH); } - // agility - if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233;stat = GetStat(STAT_AGILITY); } - // intellect - if (GetStat(STAT_INTELLECT)> stat) { trigger_spell_id = 60234;stat = GetStat(STAT_INTELLECT);} - // spirit - if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235; } - break; - } - //case 55580: break: // Mana Link - //case 57587: break: // Steal Ranged () - //case 57594: break; // Copy Ranged Weapon - //case 59237: break; // Beast's Mark - // trigger_spell_id = 59233; break; - //case 59288: break; // Infra-Green Shield - //case 59532: break; // Abandon Passengers on Poly - //case 59735: break: // Woe Strike - case 64415: // // Val'anyr Hammer of Ancient Kings - Equip Effect - { - // for DOT procs - if (!IsPositiveSpell(procSpell->Id)) - return false; - break; - } - case 67702: // Death's Choice, Item - Coliseum 25 Normal Melee Trinket - { - float stat = 0.0f; - // strength - if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67708;stat = GetStat(STAT_STRENGTH); } - // agility - if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67703; } - break; - } - case 67771: // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket - { - float stat = 0.0f; - // strength - if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67773;stat = GetStat(STAT_STRENGTH); } - // agility - if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67772; } - break; - } - } - break; - case SPELLFAMILY_MAGE: - if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed - { - switch (auraSpellInfo->Id) - { - case 31641: // Rank 1 - case 31642: // Rank 2 - trigger_spell_id = 31643; - break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id); - return false; - } - } - // Persistent Shield (Scarab Brooch trinket) - else if(auraSpellInfo->Id == 26467) - { - // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect) - basepoints[0] = damage * 15 / 100; - target = pVictim; - trigger_spell_id = 26470; - } - break; - case SPELLFAMILY_WARRIOR: - // Deep Wounds (replace triggered spells to directly apply DoT), dot spell have finilyflags - if (auraSpellInfo->SpellFamilyFlags == UI64LIT(0x0) && auraSpellInfo->SpellIconID == 243) - { - float weaponDamage; - // DW should benefit of attack power, damage percent mods etc. - // TODO: check if using offhand damage is correct and if it should be divided by 2 - if (haveOffhandWeapon() && getAttackTimer(BASE_ATTACK) > getAttackTimer(OFF_ATTACK)) - weaponDamage = (GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE))/2; - else - weaponDamage = (GetFloatValue(UNIT_FIELD_MINDAMAGE) + GetFloatValue(UNIT_FIELD_MAXDAMAGE))/2; - - switch (auraSpellInfo->Id) - { - case 12834: basepoints[0] = int32(weaponDamage * 16 / 100); break; - case 12849: basepoints[0] = int32(weaponDamage * 32 / 100); break; - case 12867: basepoints[0] = int32(weaponDamage * 48 / 100); break; - // Impossible case - default: - sLog.outError("Unit::HandleProcTriggerSpell: DW unknown spell rank %u",auraSpellInfo->Id); - return false; - } - - // 1 tick/sec * 6 sec = 6 ticks - basepoints[0] /= 6; - - trigger_spell_id = 12721; - break; - } - if (auraSpellInfo->Id == 50421) // Scent of Blood - trigger_spell_id = 50422; - break; - case SPELLFAMILY_WARLOCK: - { - // Drain Soul - if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) - { - // search for "Improved Drain Soul" dummy aura - Unit::AuraList const& mDummyAura = GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator i = mDummyAura.begin(); i != mDummyAura.end(); ++i) - { - if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*i)->GetSpellProto()->SpellIconID == 113) - { - // basepoints of trigger spell stored in dummyeffect of spellProto - int32 basepoints = GetMaxPower(POWER_MANA) * (*i)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_2) / 100; - CastCustomSpell(this, 18371, &basepoints, NULL, NULL, true, castItem, triggeredByAura); - break; - } - } - // Not remove charge (aura removed on death in any cases) - // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura - return false; - } - // Nether Protection - else if (auraSpellInfo->SpellIconID == 1985) - { - if (!procSpell) - return false; - switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) - { - case SPELL_SCHOOL_NORMAL: - return false; // ignore - case SPELL_SCHOOL_HOLY: trigger_spell_id = 54370; break; - case SPELL_SCHOOL_FIRE: trigger_spell_id = 54371; break; - case SPELL_SCHOOL_NATURE: trigger_spell_id = 54375; break; - case SPELL_SCHOOL_FROST: trigger_spell_id = 54372; break; - case SPELL_SCHOOL_SHADOW: trigger_spell_id = 54374; break; - case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break; - default: - return false; - } - } - // Cheat Death - else if (auraSpellInfo->Id == 28845) - { - // When your health drops below 20% .... - if (GetHealth() - damage > GetMaxHealth() / 5 || GetHealth() < GetMaxHealth() / 5) - return false; - } - // Decimation - else if (auraSpellInfo->Id == 63156 || auraSpellInfo->Id == 63158) - { - // Looking for dummy effect - Aura *aur = GetAura(auraSpellInfo->Id, EFFECT_INDEX_1); - if (!aur) - return false; - - // If target's health is not below equal certain value (35%) not proc - if (int32(pVictim->GetHealth() * 100 / pVictim->GetMaxHealth()) > aur->GetModifier()->m_amount) - return false; - } - break; - } - case SPELLFAMILY_PRIEST: - { - // Greater Heal Refund (Avatar Raiment set) - if (auraSpellInfo->Id==37594) - { - // Not give if target already have full health - if (pVictim->GetHealth() == pVictim->GetMaxHealth()) - return false; - // If your Greater Heal brings the target to full health, you gain $37595s1 mana. - if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth()) - return false; - trigger_spell_id = 37595; - } - // Blessed Recovery - else if (auraSpellInfo->SpellIconID == 1875) - { - switch (auraSpellInfo->Id) - { - case 27811: trigger_spell_id = 27813; break; - case 27815: trigger_spell_id = 27817; break; - case 27816: trigger_spell_id = 27818; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id); - return false; - } - basepoints[0] = damage * triggerAmount / 100 / 3; - target = this; - } - break; - } - case SPELLFAMILY_DRUID: - { - // Druid Forms Trinket - if (auraSpellInfo->Id==37336) - { - switch(m_form) - { - case FORM_NONE: trigger_spell_id = 37344;break; - case FORM_CAT: trigger_spell_id = 37341;break; - case FORM_BEAR: - case FORM_DIREBEAR: trigger_spell_id = 37340;break; - case FORM_TREE: trigger_spell_id = 37342;break; - case FORM_MOONKIN: trigger_spell_id = 37343;break; - default: - return false; - } - } - // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) - else if (auraSpellInfo->Id==67353) - { - switch(m_form) - { - case FORM_CAT: trigger_spell_id = 67355; break; - case FORM_BEAR: - case FORM_DIREBEAR: trigger_spell_id = 67354; break; - default: - return false; - } - } - break; - } - case SPELLFAMILY_HUNTER: - // Piercing Shots - if (auraSpellInfo->SpellIconID == 3247 && auraSpellInfo->SpellVisual[0] == 0) - { - basepoints[0] = damage * triggerAmount / 100 / 8; - trigger_spell_id = 63468; - target = pVictim; - } - // Rapid Recuperation - else if (auraSpellInfo->Id == 53228 || auraSpellInfo->Id == 53232) - { - // This effect only from Rapid Fire (ability cast) - if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020))) - return false; - } - // Lock and Load - else if (auraSpellInfo->SpellIconID == 3579) - { - // Check for Lock and Load Marker - if (HasAura(67544)) - return false; - } - break; - case SPELLFAMILY_PALADIN: - { - /* - // Blessed Life - if (auraSpellInfo->SpellIconID == 2137) - { - switch (auraSpellInfo->Id) - { - case 31828: // Rank 1 - case 31829: // Rank 2 - case 31830: // Rank 3 - break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Blessed Life", auraSpellInfo->Id); - return false; - } - } - */ - // Healing Discount - if (auraSpellInfo->Id==37705) - { - trigger_spell_id = 37706; - target = this; - } - // Soul Preserver - if (auraSpellInfo->Id==60510) - { - trigger_spell_id = 60515; - target = this; - } - // Illumination - else if (auraSpellInfo->SpellIconID==241) - { - if(!procSpell) - return false; - // procspell is triggered spell but we need mana cost of original casted spell - uint32 originalSpellId = procSpell->Id; - // Holy Shock heal - if (procSpell->SpellFamilyFlags & UI64LIT(0x0001000000000000)) - { - switch(procSpell->Id) - { - case 25914: originalSpellId = 20473; break; - case 25913: originalSpellId = 20929; break; - case 25903: originalSpellId = 20930; break; - case 27175: originalSpellId = 27174; break; - case 33074: originalSpellId = 33072; break; - case 48820: originalSpellId = 48824; break; - case 48821: originalSpellId = 48825; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id); - return false; - } - } - SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); - if(!originalSpell) - { - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId); - return false; - } - // percent stored in effect 1 (class scripts) base points - int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints[0] = cost*auraSpellInfo->CalculateSimpleValue(EFFECT_INDEX_1)/100; - trigger_spell_id = 20272; - target = this; - } - // Lightning Capacitor - else if (auraSpellInfo->Id==37657) - { - if(!pVictim || !pVictim->isAlive()) - return false; - // stacking - CastSpell(this, 37658, true, NULL, triggeredByAura); - - Aura * dummy = GetDummyAura(37658); - // release at 3 aura in stack (cont contain in basepoint of trigger aura) - if(!dummy || dummy->GetStackAmount() < triggerAmount) - return false; - - RemoveAurasDueToSpell(37658); - trigger_spell_id = 37661; - target = pVictim; - } - // Bonus Healing (Crystal Spire of Karabor mace) - else if (auraSpellInfo->Id == 40971) - { - // If your target is below $s1% health - if (pVictim->GetHealth() > pVictim->GetMaxHealth() * triggerAmount / 100) - return false; - } - // Thunder Capacitor - else if (auraSpellInfo->Id == 54841) - { - if(!pVictim || !pVictim->isAlive()) - return false; - // stacking - CastSpell(this, 54842, true, NULL, triggeredByAura); - - // counting - Aura * dummy = GetDummyAura(54842); - // release at 3 aura in stack (cont contain in basepoint of trigger aura) - if(!dummy || dummy->GetStackAmount() < triggerAmount) - return false; - - RemoveAurasDueToSpell(54842); - trigger_spell_id = 54843; - target = pVictim; - } - break; - } - case SPELLFAMILY_SHAMAN: - { - // Lightning Shield (overwrite non existing triggered spell call in spell.dbc - if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) - { - switch(auraSpellInfo->Id) - { - case 324: // Rank 1 - trigger_spell_id = 26364; break; - case 325: // Rank 2 - trigger_spell_id = 26365; break; - case 905: // Rank 3 - trigger_spell_id = 26366; break; - case 945: // Rank 4 - trigger_spell_id = 26367; break; - case 8134: // Rank 5 - trigger_spell_id = 26369; break; - case 10431: // Rank 6 - trigger_spell_id = 26370; break; - case 10432: // Rank 7 - trigger_spell_id = 26363; break; - case 25469: // Rank 8 - trigger_spell_id = 26371; break; - case 25472: // Rank 9 - trigger_spell_id = 26372; break; - case 49280: // Rank 10 - trigger_spell_id = 49278; break; - case 49281: // Rank 11 - trigger_spell_id = 49279; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id); - return false; - } - } - // Lightning Shield (The Ten Storms set) - else if (auraSpellInfo->Id == 23551) - { - trigger_spell_id = 23552; - target = pVictim; - } - // Damage from Lightning Shield (The Ten Storms set) - else if (auraSpellInfo->Id == 23552) - trigger_spell_id = 27635; - // Mana Surge (The Earthfury set) - else if (auraSpellInfo->Id == 23572) - { - if(!procSpell) - return false; - basepoints[0] = procSpell->manaCost * 35 / 100; - trigger_spell_id = 23571; - target = this; - } - // Nature's Guardian - else if (auraSpellInfo->SpellIconID == 2013) - { - // Check health condition - should drop to less 30% (damage deal after this!) - if (!(10*(int32(GetHealth() - damage)) < int32(3 * GetMaxHealth()))) - return false; - - if(pVictim && pVictim->isAlive()) - pVictim->getThreatManager().modifyThreatPercent(this,-10); - - basepoints[0] = triggerAmount * GetMaxHealth() / 100; - trigger_spell_id = 31616; - target = this; - } - break; - } - case SPELLFAMILY_DEATHKNIGHT: - { - // Acclimation - if (auraSpellInfo->SpellIconID == 1930) - { - if (!procSpell) - return false; - switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) - { - case SPELL_SCHOOL_NORMAL: - return false; // ignore - case SPELL_SCHOOL_HOLY: trigger_spell_id = 50490; break; - case SPELL_SCHOOL_FIRE: trigger_spell_id = 50362; break; - case SPELL_SCHOOL_NATURE: trigger_spell_id = 50488; break; - case SPELL_SCHOOL_FROST: trigger_spell_id = 50485; break; - case SPELL_SCHOOL_SHADOW: trigger_spell_id = 50489; break; - case SPELL_SCHOOL_ARCANE: trigger_spell_id = 50486; break; - default: - return false; - } - } - // Blade Barrier - else if (auraSpellInfo->SpellIconID == 85) - { - if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT || - !((Player*)this)->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) - return false; - } - // Improved Blood Presence - else if (auraSpellInfo->Id == 63611) - { - if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim) || !damage) - return false; - basepoints[0] = triggerAmount * damage / 100; - trigger_spell_id = 50475; - } - break; - } - default: - break; - } - - // All ok. Check current trigger spell - SpellEntry const* triggerEntry = sSpellStore.LookupEntry(trigger_spell_id); - if (!triggerEntry) - { - // Not cast unknown spell - // sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex()); - return false; - } - - // not allow proc extra attack spell at extra attack - if (m_extraAttacks && IsSpellHaveEffect(triggerEntry, SPELL_EFFECT_ADD_EXTRA_ATTACKS)) - return false; - - // Custom basepoints/target for exist spell - // dummy basepoints or other customs - switch(trigger_spell_id) - { - // Cast positive spell on enemy target - case 7099: // Curse of Mending - case 39647: // Curse of Mending - case 29494: // Temptation - case 20233: // Improved Lay on Hands (cast on target) - { - target = pVictim; - break; - } - // Combo points add triggers (need add combopoint only for main target, and after possible combopoints reset) - case 15250: // Rogue Setup - { - if(!pVictim || pVictim != getVictim()) // applied only for main target - return false; - break; // continue normal case - } - // Finish movies that add combo - case 14189: // Seal Fate (Netherblade set) - case 14157: // Ruthlessness - { - // Need add combopoint AFTER finish movie (or they dropped in finish phase) - break; - } - // Bloodthirst (($m/100)% of max health) - case 23880: - { - basepoints[0] = int32(GetMaxHealth() * triggerAmount / 100); - break; - } - // Shamanistic Rage triggered spell - case 30824: - { - basepoints[0] = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100); - break; - } - // Enlightenment (trigger only from mana cost spells) - case 35095: - { - if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0) - return false; - break; - } - // Demonic Pact - case 48090: - { - // As the spell is proced from pet's attack - find owner - Unit* owner = GetOwner(); - if (!owner || owner->GetTypeId() != TYPEID_PLAYER) - return false; - - // This spell doesn't stack, but refreshes duration. So we receive current bonuses to minus them later. - int32 curBonus = 0; - if (Aura* aur = owner->GetAura(48090, EFFECT_INDEX_0)) - curBonus = aur->GetModifier()->m_amount; - int32 spellDamage = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) - curBonus; - if(spellDamage <= 0) - return false; - - // percent stored in owner talent dummy - AuraList const& dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY); - for (AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) - { - if ((*i)->GetSpellProto()->SpellIconID == 3220) - { - basepoints[0] = basepoints[1] = int32(spellDamage * (*i)->GetModifier()->m_amount / 100); - break; - } - } - break; - } - // Sword and Board - case 50227: - { - // Remove cooldown on Shield Slam - if (GetTypeId() == TYPEID_PLAYER) - ((Player*)this)->RemoveSpellCategoryCooldown(1209, true); - break; - } - // Maelstrom Weapon - case 53817: - { - // have rank dependent proc chance, ignore too often cases - // PPM = 2.5 * (rank of talent), - uint32 rank = sSpellMgr.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 - case 57761: - { - if(!procSpell) - return false; - // For trigger from Blizzard need exist Improved Blizzard - if (procSpell->SpellFamilyName==SPELLFAMILY_MAGE && (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080))) - { - bool found = false; - AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) - { - int32 script = (*i)->GetModifier()->m_miscvalue; - if(script==836 || script==988 || script==989) - { - found=true; - break; - } - } - if(!found) - return false; - } - break; - } - // Astral Shift - case 52179: - { - if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) - return false; - - // Need stun, fear or silence mechanic - if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_SILENCE_AND_STUN_AND_FEAR_MASK)) - return false; - break; - } - // Burning Determination - case 54748: - { - if(!procSpell) - return false; - // Need Interrupt or Silenced mechanic - if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_INTERRUPT_AND_SILENCE_MASK)) - return false; - break; - } - // Lock and Load - case 56453: - { - // Proc only from trap activation (from periodic proc another aura of this spell) - if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION) || !roll_chance_i(triggerAmount)) - return false; - break; - } - // Freezing Fog (Rime triggered) - case 59052: - { - // Howling Blast cooldown reset - if (GetTypeId() == TYPEID_PLAYER) - ((Player*)this)->RemoveSpellCategoryCooldown(1248, true); - break; - } - // Druid - Savage Defense - case 62606: - { - basepoints[0] = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100); - break; - } - } - - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(trigger_spell_id)) - return false; - - // try detect target manually if not set - if (target == NULL) - target = !(procFlags & PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL) && IsPositiveSpell(trigger_spell_id) ? this : pVictim; - - // default case - if (!target || target!=this && !target->isAlive()) - return false; - - if (basepoints[EFFECT_INDEX_0] || basepoints[EFFECT_INDEX_1] || basepoints[EFFECT_INDEX_2]) - CastCustomSpell(target,trigger_spell_id, - basepoints[EFFECT_INDEX_0] ? &basepoints[EFFECT_INDEX_0] : NULL, - basepoints[EFFECT_INDEX_1] ? &basepoints[EFFECT_INDEX_1] : NULL, - basepoints[EFFECT_INDEX_2] ? &basepoints[EFFECT_INDEX_2] : NULL, - true, castItem, triggeredByAura); - else - CastSpell(target,trigger_spell_id,true,castItem,triggeredByAura); - - if( cooldown && GetTypeId()==TYPEID_PLAYER ) - ((Player*)this)->AddSpellCooldown(trigger_spell_id,0,time(NULL) + cooldown); - - return true; -} - -bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 /*damage*/, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 cooldown) -{ - int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; - - if(!pVictim || !pVictim->isAlive()) - return false; - - Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - - // Basepoints of trigger aura - int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; - - uint32 triggered_spell_id = 0; - - switch(scriptId) - { - case 836: // Improved Blizzard (Rank 1) - { - if (!procSpell || procSpell->SpellVisual[0]!=9487) - return false; - triggered_spell_id = 12484; - break; - } - case 988: // Improved Blizzard (Rank 2) - { - if (!procSpell || procSpell->SpellVisual[0]!=9487) - return false; - triggered_spell_id = 12485; - break; - } - case 989: // Improved Blizzard (Rank 3) - { - if (!procSpell || procSpell->SpellVisual[0]!=9487) - return false; - triggered_spell_id = 12486; - break; - } - case 4086: // Improved Mend Pet (Rank 1) - case 4087: // Improved Mend Pet (Rank 2) - { - if(!roll_chance_i(triggerAmount)) - return false; - - triggered_spell_id = 24406; - break; - } - case 4533: // Dreamwalker Raiment 2 pieces bonus - { - // Chance 50% - if (!roll_chance_i(50)) - return false; - - switch (pVictim->getPowerType()) - { - case POWER_MANA: triggered_spell_id = 28722; break; - case POWER_RAGE: triggered_spell_id = 28723; break; - case POWER_ENERGY: triggered_spell_id = 28724; break; - default: - return false; - } - break; - } - case 4537: // Dreamwalker Raiment 6 pieces bonus - triggered_spell_id = 28750; // Blessing of the Claw - break; - case 5497: // Improved Mana Gems (Serpent-Coil Braid) - triggered_spell_id = 37445; // Mana Surge - break; - case 6953: // Warbringer - RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK,0,true); - return true; - case 7010: // Revitalize (rank 1) - case 7011: // Revitalize (rank 2) - case 7012: // Revitalize (rank 3) - { - if(!roll_chance_i(triggerAmount)) - return false; - - switch( pVictim->getPowerType() ) - { - case POWER_MANA: triggered_spell_id = 48542; break; - case POWER_RAGE: triggered_spell_id = 48541; break; - case POWER_ENERGY: triggered_spell_id = 48540; break; - case POWER_RUNIC_POWER: triggered_spell_id = 48543; break; - default: return false; - } - break; - } - } - - // not processed - if(!triggered_spell_id) - return false; - - // standard non-dummy case - SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); - - if(!triggerEntry) - { - sLog.outError("Unit::HandleOverrideClassScriptAuraProc: Spell %u triggering for class script id %u",triggered_spell_id,scriptId); - return false; - } - - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) - return false; - - CastSpell(pVictim, triggered_spell_id, true, castItem, triggeredByAura); - - if( cooldown && GetTypeId()==TYPEID_PLAYER ) - ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); - - return true; -} - void Unit::setPowerType(Powers new_powertype) { SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype); @@ -8646,12 +5607,15 @@ void Unit::ModifyAuraState(AuraState flag, bool apply) if (flag != AURA_STATE_ENRAGE) // enrage aura state triggering continues auras { - Unit::AuraMap& tAuras = GetAuras(); - for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();) + Unit::SpellAuraHolderMap& tAuras = GetSpellAuraHolderMap(); + for (Unit::SpellAuraHolderMap::iterator itr = tAuras.begin(); itr != tAuras.end();) { SpellEntry const* spellProto = (*itr).second->GetSpellProto(); if (spellProto->CasterAuraState == flag) - RemoveAura(itr); + { + RemoveSpellAuraHolder(itr->second); + itr = tAuras.begin(); + } else ++itr; } @@ -9060,8 +6024,8 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u int32 stepPercent = CalculateSpellDamage(this, (*i)->GetSpellProto(), EFFECT_INDEX_0); // count affliction effects and calc additional damage in percentage int32 modPercent = 0; - AuraMap const& victimAuras = pVictim->GetAuras(); - for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) + SpellAuraHolderMap const& victimAuras = pVictim->GetSpellAuraHolderMap(); + for (SpellAuraHolderMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) { SpellEntry const* m_spell = itr->second->GetSpellProto(); if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags & UI64LIT(0x0004071B8044C402))) @@ -9234,8 +6198,8 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u { // search disease bool found = false; - Unit::AuraMap const& auras = pVictim->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = pVictim->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE) { @@ -10130,8 +7094,8 @@ uint32 Unit::MeleeDamageBonusDone(Unit *pVictim, uint32 pdamage,WeaponAttackType { // search disease bool found = false; - Unit::AuraMap const& auras = pVictim->GetAuras(); - for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + Unit::SpellAuraHolderMap const& auras = pVictim->GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) { if(itr->second->GetSpellProto()->Dispel == DISPEL_DISEASE) { @@ -12344,67 +9308,16 @@ bool Unit::isFrozen() const struct ProcTriggeredData { - ProcTriggeredData(SpellProcEventEntry const * _spellProcEvent, Aura* _triggeredByAura) - : spellProcEvent(_spellProcEvent), triggeredByAura(_triggeredByAura), - triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())) + ProcTriggeredData(SpellProcEventEntry const * _spellProcEvent, SpellAuraHolder* _triggeredByHolder) + : spellProcEvent(_spellProcEvent), triggeredByHolder(_triggeredByHolder) {} SpellProcEventEntry const *spellProcEvent; - Aura* triggeredByAura; - Unit::spellEffectPair triggeredByAura_SpellPair; + SpellAuraHolder* triggeredByHolder; }; typedef std::list< ProcTriggeredData > ProcTriggeredList; typedef std::list< uint32> RemoveSpellList; -// List of auras that CAN be trigger but may not exist in spell_proc_event -// in most case need for drop charges -// in some types of aura need do additional check -// for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic -bool InitTriggerAuraData() -{ - for (int i=0;isecond->IsDeleted()) continue; SpellProcEventEntry const* spellProcEvent = NULL; - if(!IsTriggeredAtSpellProcEvent(pTarget, itr->second, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), spellProcEvent)) + if(!IsTriggeredAtSpellProcEvent(pTarget, itr->second, procSpell, procFlag, procExtra, attType, isVictim, spellProcEvent)) continue; - itr->second->SetInUse(true); // prevent aura deletion + itr->second->SetInUse(true); // prevent holder deletion procTriggered.push_back( ProcTriggeredData(spellProcEvent, itr->second) ); } @@ -12536,182 +9449,63 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag for(ProcTriggeredList::const_iterator i = procTriggered.begin(); i != procTriggered.end(); ++i) { // Some auras can be deleted in function called in this loop (except first, ofc) - Aura *triggeredByAura = i->triggeredByAura; - if(triggeredByAura->IsDeleted()) + SpellAuraHolder *triggeredByHolder = i->triggeredByHolder; + if(triggeredByHolder->IsDeleted()) continue; SpellProcEventEntry const *spellProcEvent = i->spellProcEvent; - Modifier *auraModifier = triggeredByAura->GetModifier(); - SpellEntry const *spellInfo = triggeredByAura->GetSpellProto(); - bool useCharges = triggeredByAura->GetAuraCharges() > 0; + SpellEntry const *spellInfo = triggeredByHolder->GetSpellProto(); + bool useCharges = triggeredByHolder->GetAuraCharges() > 0; + bool procSuccess = true; + bool anyAuraProc = false; + // For players set spell cooldown if need uint32 cooldown = 0; if (GetTypeId() == TYPEID_PLAYER && spellProcEvent && spellProcEvent->cooldown) cooldown = spellProcEvent->cooldown; - switch(auraModifier->m_auraname) + for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - case SPELL_AURA_PROC_TRIGGER_SPELL: - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - // Don`t drop charge or add cooldown for not started trigger - if (!HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - } - case SPELL_AURA_PROC_TRIGGER_DAMAGE: - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", auraModifier->m_amount, spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - SpellNonMeleeDamage damageInfo(this, pTarget, spellInfo->Id, SpellSchoolMask(spellInfo->SchoolMask)); - CalculateSpellDamage(&damageInfo, auraModifier->m_amount, spellInfo); - damageInfo.target->CalculateAbsorbResistBlock(this, &damageInfo, spellInfo); - DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb); - SendSpellNonMeleeDamageLog(&damageInfo); - DealSpellDamage(&damageInfo, true); - break; - } - case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: - case SPELL_AURA_MANA_SHIELD: - case SPELL_AURA_OBS_MOD_MANA: - case SPELL_AURA_ADD_PCT_MODIFIER: - case SPELL_AURA_DUMMY: - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (!HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - } - case SPELL_AURA_MOD_HASTE: - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (!HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - } - case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (!HandleOverrideClassScriptAuraProc(pTarget, damage, triggeredByAura, procSpell, cooldown)) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - } - case SPELL_AURA_PRAYER_OF_MENDING: - { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)", - (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); + Aura *triggeredByAura = triggeredByHolder->GetAuraByEffectIndex(SpellEffectIndex(i)); + if (!triggeredByAura) + continue; - HandleMendingAuraProc(triggeredByAura); - break; - } - case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE: + Modifier *auraModifier = triggeredByAura->GetModifier(); + + if (procSpell) { - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - - if (!HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) + if (spellProcEvent) { - triggeredByAura->SetInUse(false); - continue; + if (spellProcEvent->spellFamilyMask[i] || spellProcEvent->spellFamilyMask2[i]) + { + if ((spellProcEvent->spellFamilyMask[i] & procSpell->SpellFamilyFlags ) == 0 && + (spellProcEvent->spellFamilyMask2[i] & procSpell->SpellFamilyFlags2) == 0) + continue; + } + else if (!spellProcEvent->schoolMask && !triggeredByAura->isAffectedOnSpell(procSpell)) + continue; } - break; + else if (!triggeredByAura->isAffectedOnSpell(procSpell)) + continue; } - case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: - // Skip melee hits or instant cast spells - if (procSpell == NULL || GetSpellCastTime(procSpell) == 0) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_REFLECT_SPELLS_SCHOOL: - // Skip Melee hits and spells ws wrong school - if (procSpell == NULL || (auraModifier->m_miscvalue & procSpell->SchoolMask) == 0) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: - case SPELL_AURA_MOD_POWER_COST_SCHOOL: - // Skip melee hits and spells ws wrong school or zero cost - if (procSpell == NULL || - (procSpell->manaCost == 0 && procSpell->ManaCostPercentage == 0) || // Cost check - (auraModifier->m_miscvalue & procSpell->SchoolMask) == 0) // School check - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_MECHANIC_IMMUNITY: - // Compare mechanic - if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_MOD_MECHANIC_RESISTANCE: - // Compare mechanic - if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: - // Compare casters - if (triggeredByAura->GetCasterGUID() != pTarget->GetGUID()) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: - if (!procSpell) - { - triggeredByAura->SetInUse(false); - continue; - } - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - if (!HandleSpellCritChanceAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) - { - triggeredByAura->SetInUse(false); - continue; - } - break; - case SPELL_AURA_MAELSTROM_WEAPON: - DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: casting spell id %u (triggered by %s maelstrom aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); - // remove all stack; - RemoveSpellsCausingAura(SPELL_AURA_MAELSTROM_WEAPON); - triggeredByAura->SetInUse(false); // this safe, aura locked - continue; // avoid re-remove attempts - default: - // nothing do, just charges counter - break; + if (!(*this.*AuraProcHandler[auraModifier->m_auraname])(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) + procSuccess = false; + + anyAuraProc = true; + triggeredByAura->SetInUse(false); } - // Remove charge (aura can be removed by triggers) - if(useCharges && !triggeredByAura->IsDeleted()) + if(useCharges && procSuccess && anyAuraProc && !triggeredByHolder->IsDeleted()) { // If last charge dropped add spell to remove list - if(triggeredByAura->DropAuraCharge()) - removedSpells.push_back(triggeredByAura->GetId()); + if(triggeredByHolder->DropAuraCharge()) + removedSpells.push_back(triggeredByHolder->GetId()); } - triggeredByAura->SetInUse(false); + triggeredByHolder->SetInUse(false); } + if (!removedSpells.empty()) { // Sort spells and remove dublicates @@ -12719,7 +9513,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag removedSpells.unique(); // Remove auras from removedAuras for(RemoveSpellList::const_iterator i = removedSpells.begin(); i != removedSpells.end();++i) - RemoveSingleSpellAurasFromStack(*i); + RemoveSingleAuraHolderFromStack(*i); } } @@ -13158,7 +9952,7 @@ Unit* Unit::SelectRandomFriendlyTarget(Unit* except /*= NULL*/, float radius /*= bool Unit::hasNegativeAuraWithInterruptFlag(uint32 flag) { - for (AuraMap::const_iterator iter = m_Auras.begin(); iter != m_Auras.end(); ++iter) + for (SpellAuraHolderMap::const_iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end(); ++iter) { if (!iter->second->IsPositive() && iter->second->GetSpellProto()->AuraInterruptFlags & flag) return true; @@ -13330,149 +10124,10 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) return pet; } -bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ) -{ - SpellEntry const* spellProto = aura->GetSpellProto (); - - // Get proc Event Entry - spellProcEvent = sSpellMgr.GetSpellProcEvent(spellProto->Id); - - // Aura info stored here - Modifier *mod = aura->GetModifier(); - // Skip this auras - if (isNonTriggerAura[mod->m_auraname]) - return false; - // If not trigger by default and spellProcEvent==NULL - skip - if (!isTriggerAura[mod->m_auraname] && spellProcEvent==NULL) - return false; - - // Get EventProcFlag - uint32 EventProcFlag; - if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags - EventProcFlag = spellProcEvent->procFlags; - else - EventProcFlag = spellProto->procFlags; // else get from spell proto - // Continue if no trigger exist - if (!EventProcFlag) - return false; - - // Check spellProcEvent data requirements - if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active)) - return false; - - // In most cases req get honor or XP from kill - if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER) - { - bool allow = ((Player*)this)->isHonorOrXPTarget(pVictim); - // Shadow Word: Death - can trigger from every kill - if (aura->GetId() == 32409) - allow = true; - if (!allow) - return false; - } - // Aura added by spell can`t trogger from self (prevent drop charges/do triggers) - // But except periodic triggers (can triggered from self) - if(procSpell && procSpell->Id == spellProto->Id && !(spellProto->procFlags & PROC_FLAG_ON_TAKE_PERIODIC)) - return false; - - // Check if current equipment allows aura to proc - if(!isVictim && GetTypeId() == TYPEID_PLAYER) - { - if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) - { - Item *item = NULL; - if(attType == BASE_ATTACK) - item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - else if (attType == OFF_ATTACK) - item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - else - item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); - - if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) - return false; - } - else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) - { - // Check if player is wearing shield - Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); - if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) - return false; - } - } - // Get chance from spell - float chance = (float)spellProto->procChance; - // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance; - if(spellProcEvent && spellProcEvent->customChance) - chance = spellProcEvent->customChance; - // If PPM exist calculate chance from PPM - if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0) - { - uint32 WeaponSpeed = GetAttackTime(attType); - chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); - } - // Apply chance modifer aura - if(Player* modOwner = GetSpellModOwner()) - { - modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); - modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_FREQUENCY_OF_SUCCESS,chance); - } - - return roll_chance_f(chance); -} - -bool Unit::HandleMendingAuraProc( Aura* triggeredByAura ) -{ - // aura can be deleted at casts - SpellEntry const* spellProto = triggeredByAura->GetSpellProto(); - SpellEffectIndex effIdx = triggeredByAura->GetEffIndex(); - int32 heal = triggeredByAura->GetModifier()->m_amount; - uint64 caster_guid = triggeredByAura->GetCasterGUID(); - - // jumps - int32 jumps = triggeredByAura->GetAuraCharges()-1; - - // current aura expire - triggeredByAura->SetAuraCharges(1); // will removed at next charges decrease - - // next target selection - if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) - { - float radius; - if (spellProto->EffectRadiusIndex[effIdx]) - radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); - else - radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); - - if(Player* caster = ((Player*)triggeredByAura->GetCaster())) - { - caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); - - if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) - { - // aura will applied from caster, but spell casted from current aura holder - SpellModifier *mod = new SpellModifier(SPELLMOD_CHARGES,SPELLMOD_FLAT,jumps-5,spellProto->Id,spellProto->SpellFamilyFlags,spellProto->SpellFamilyFlags2); - - // remove before apply next (locked against deleted) - triggeredByAura->SetInUse(true); - RemoveAurasByCasterSpell(spellProto->Id,caster->GetGUID()); - - caster->AddSpellMod(mod, true); - CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); - caster->AddSpellMod(mod, false); - triggeredByAura->SetInUse(false); - } - } - } - - // heal - CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); - return true; -} - void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive /*= false*/) { - Unit::AuraMap& auras = GetAuras(); - for(Unit::AuraMap::iterator iter = auras.begin(); iter != auras.end();) + Unit::SpellAuraHolderMap& auras = GetSpellAuraHolderMap(); + for(Unit::SpellAuraHolderMap::iterator iter = auras.begin(); iter != auras.end();) { SpellEntry const *spell = iter->second->GetSpellProto(); if (spell->Id == exceptSpellId) @@ -13481,14 +10136,15 @@ void Unit::RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, ++iter; else if (spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) ++iter; - else if (GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechMask) + else if (iter->second->HasAuraAndMechanicEffectMask(mechMask)) { RemoveAurasDueToSpell(spell->Id); + if(auras.empty()) break; else iter = auras.begin(); - } + } else ++iter; } @@ -13777,6 +10433,10 @@ void Unit::StopAttackFaction(uint32 faction_id) void Unit::CleanupDeletedAuras() { + for (SpellAuraHolderList::const_iterator iter = m_deletedHolders.begin(); iter != m_deletedHolders.end(); ++iter) + delete *iter; + m_deletedHolders.clear(); + // really delete auras "deleted" while processing its ApplyModify code for(AuraList::const_iterator itr = m_deletedAuras.begin(); itr != m_deletedAuras.end(); ++itr) delete *itr; @@ -13792,4 +10452,14 @@ bool Unit::CheckAndIncreaseCastCounter() ++m_castCounter; return true; +} + +SpellAuraHolder* Unit::GetSpellAuraHolder (uint32 spellid, uint64 casterGUID) +{ + SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(spellid); + for (SpellAuraHolderMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter) + if (!casterGUID || iter->second->GetCasterGUID() == casterGUID) + return iter->second; + + return NULL; } \ No newline at end of file diff --git a/src/game/Unit.h b/src/game/Unit.h index 9fbb2774e..22046e06c 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -294,6 +294,7 @@ struct SpellEntry; struct SpellEntryExt; class Aura; +class SpellAuraHolder; class Creature; class Spell; class DynamicObject; @@ -931,6 +932,9 @@ struct SpellPeriodicAuraLogInfo uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition); +typedef bool(Unit::*pAuraProcHandler)(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); +extern pAuraProcHandler AuraProcHandler[TOTAL_AURAS]; + #define MAX_DECLINED_NAME_CASES 5 struct DeclinedName @@ -1096,8 +1100,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject { public: typedef std::set AttackerSet; - typedef std::pair spellEffectPair; - typedef std::multimap< spellEffectPair, Aura*> AuraMap; + typedef std::multimap< uint32, SpellAuraHolder*> SpellAuraHolderMap; + typedef std::pair SpellAuraHolderBounds; + typedef std::list SpellAuraHolderList; typedef std::list AuraList; typedef std::list Diminishing; typedef std::set ComboPointHolderSet; @@ -1348,12 +1353,17 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void ClearInCombat(); uint32 GetCombatTimer() const { return m_CombatTimer; } - bool HasAuraType(AuraType auraType) const; - bool HasAura(uint32 spellId, SpellEffectIndex effIndex) const + SpellAuraHolderBounds GetSpellAuraHolderBounds(uint32 spell_id) { - return m_Auras.find(spellEffectPair(spellId, effIndex)) != m_Auras.end(); + return SpellAuraHolderBounds(m_spellAuraHolders.lower_bound(spell_id), m_spellAuraHolders.upper_bound(spell_id)); + } + + bool HasAuraType(AuraType auraType) const; + bool HasAura(uint32 spellId, SpellEffectIndex effIndex) const; + bool HasAura(uint32 spellId) const + { + return m_spellAuraHolders.find(spellId) != m_spellAuraHolders.end(); } - bool HasAura(uint32 spellId) const; bool virtual HasSpell(uint32 /*spellID*/) const { return false; } @@ -1493,18 +1503,19 @@ class MANGOS_DLL_SPEC Unit : public WorldObject template bool CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) const; - bool AddAura(Aura *aur); + bool AddSpellAuraHolder(SpellAuraHolder *holder); // removing specific aura stack void RemoveAura(Aura* aura, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveAura(uint32 spellId, SpellEffectIndex effindex, Aura* except = NULL, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveAura(uint32 spellId, SpellEffectIndex effindex, Aura* except = NULL); + void RemoveSpellAuraHolder(SpellAuraHolder *holder, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleAuraFromSpellAuraHolder(SpellAuraHolder *holder, SpellEffectIndex index, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleAuraFromSpellAuraHolder(uint32 id, SpellEffectIndex index, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); // removing specific aura stacks by diff reasons and selections - void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveAurasDueToSpell(uint32 spellId, SpellAuraHolder* except = NULL, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId); void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID); - void RemoveAurasByCasterSpell(uint32 spellId, SpellEffectIndex effindex, uint64 casterGUID); void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer); void RemoveAurasDueToSpellByCancel(uint32 spellId); @@ -1513,24 +1524,18 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false); void RemoveSpellsCausingAura(AuraType auraType); void RemoveRankAurasDueToSpell(uint32 spellId); - bool RemoveNoStackAurasDueToAura(Aura *Aur); + bool RemoveNoStackAurasDueToAuraHolder(SpellAuraHolder *holder); void RemoveAurasWithInterruptFlags(uint32 flags); void RemoveAurasWithDispelType( DispelType type ); void RemoveAllAuras(AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveArenaAuras(bool onleave = false); void RemoveAllAurasOnDeath(); - // removing specific aura FROM stack - void RemoveSingleAuraFromStack(uint32 spellId, SpellEffectIndex effindex, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveSingleAuraFromStack(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - // removing specific aura FROM stack by diff reasons and selections - void RemoveSingleSpellAurasFromStack(uint32 spellId, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveSingleSpellAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveSingleAuraByCasterSpell(uint32 spellId, SpellEffectIndex effindex, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); - void RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); + void RemoveSingleAuraHolderFromStack(uint32 spellId, uint64 casterGUID = 0, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + void RemoveSingleAuraHolderDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler); - void DelayAura(uint32 spellId, SpellEffectIndex effindex, int32 delaytime); + void DelaySpellAuraHolder(uint32 spellId, int32 delaytime); float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); } void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); } @@ -1639,8 +1644,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0; bool isInvisibleForAlive() const; - AuraList & GetSingleCastAuras() { return m_scAuras; } - AuraList const& GetSingleCastAuras() const { return m_scAuras; } + SpellAuraHolderList & GetSingleCastSpellAuraHolders() { return m_scSpellAuraHolders; } + SpellAuraHolderList const& GetSingleCastSpellAuraHolders() const { return m_scSpellAuraHolders; } SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; // Threat related methods @@ -1676,9 +1681,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject Aura* GetAura(uint32 spellId, SpellEffectIndex effindex); Aura* GetAura(AuraType type, uint32 family, uint64 familyFlag, uint32 familyFlag2 = 0, uint64 casterGUID = 0); + SpellAuraHolder* GetSpellAuraHolder (uint32 spellid, uint64 casterGUID = 0); - AuraMap & GetAuras() { return m_Auras; } - AuraMap const& GetAuras() const { return m_Auras; } + SpellAuraHolderMap & GetSpellAuraHolderMap() { return m_spellAuraHolders; } + SpellAuraHolderMap const& GetSpellAuraHolderMap() const { return m_spellAuraHolders; } AuraList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; } void ApplyAuraProcTriggerDamage(Aura* aura, bool apply); @@ -1752,6 +1758,34 @@ class MANGOS_DLL_SPEC Unit : public WorldObject uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); uint32 SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim); + bool IsTriggeredAtSpellProcEvent(Unit *pVictim, SpellAuraHolder* holder, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, SpellProcEventEntry const*& spellProcEvent ); + // Aura proc handlers + bool HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleProcTriggerSpellAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleProcTriggerDamageAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleMendingAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleModCastingSpeedNotStackAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleReflectSpellsSchoolAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleModPowerCostSchoolAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleMechanicImmuneResistanceAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleModDamageFromCasterAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleMaelstromWeaponAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleAddPctModifierAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleModDamagePercentDoneAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleNULLProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) + { + // no proc handler for this aura type + return true; + } + bool HandleCantTrigger(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) + { + // this aura type can't proc + return false; + } + void SetLastManaUse() { if (GetTypeId() == TYPEID_PLAYER && !IsUnderLastManaUseEffect()) @@ -1856,11 +1890,12 @@ class MANGOS_DLL_SPEC Unit : public WorldObject DeathState m_deathState; - AuraMap m_Auras; - AuraMap::iterator m_AurasUpdateIterator; // != end() in Unit::m_Auras update and point to next element - AuraList m_deletedAuras; // auras removed while in ApplyModifier and waiting deleted + SpellAuraHolderMap m_spellAuraHolders; + SpellAuraHolderMap::iterator m_spellAuraHoldersUpdateIterator; // != end() in Unit::m_spellAuraHolders update and point to next element + AuraList m_deletedAuras; // auras removed while in ApplyModifier and waiting deleted + SpellAuraHolderList m_deletedHolders; - AuraList m_scAuras; // casted by unit single per-caster auras + SpellAuraHolderList m_scSpellAuraHolders; // casted by unit single per-caster auras typedef std::list DynObjectGUIDs; DynObjectGUIDs m_dynObjGUIDs; @@ -1892,14 +1927,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject private: void CleanupDeletedAuras(); - bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ); - bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleSpellCritChanceAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); - bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown); - bool HandleMendingAuraProc(Aura* triggeredByAura); - // player or player's pet float GetCombatRatingReduction(CombatRating cr) const; uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const; diff --git a/src/game/UnitAuraProcHandler.cpp b/src/game/UnitAuraProcHandler.cpp new file mode 100644 index 000000000..8835a1f0e --- /dev/null +++ b/src/game/UnitAuraProcHandler.cpp @@ -0,0 +1,3664 @@ +/* + * Copyright (C) 2005-2010 MaNGOS + * + * 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 "Common.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Player.h" +#include "Unit.h" +#include "Spell.h" +#include "SpellAuras.h" +#include "Totem.h" +#include "Creature.h" +#include "Formulas.h" +#include "CreatureAI.h" +#include "ScriptCalls.h" +#include "Util.h" + +pAuraProcHandler AuraProcHandler[TOTAL_AURAS]= +{ + &Unit::HandleNULLProc, // 0 SPELL_AURA_NONE + &Unit::HandleNULLProc, // 1 SPELL_AURA_BIND_SIGHT + &Unit::HandleNULLProc, // 2 SPELL_AURA_MOD_POSSESS + &Unit::HandleNULLProc, // 3 SPELL_AURA_PERIODIC_DAMAGE + &Unit::HandleDummyAuraProc, // 4 SPELL_AURA_DUMMY + &Unit::HandleNULLProc, // 5 SPELL_AURA_MOD_CONFUSE + &Unit::HandleNULLProc, // 6 SPELL_AURA_MOD_CHARM + &Unit::HandleNULLProc, // 7 SPELL_AURA_MOD_FEAR + &Unit::HandleNULLProc, // 8 SPELL_AURA_PERIODIC_HEAL + &Unit::HandleNULLProc, // 9 SPELL_AURA_MOD_ATTACKSPEED + &Unit::HandleNULLProc, // 10 SPELL_AURA_MOD_THREAT + &Unit::HandleNULLProc, // 11 SPELL_AURA_MOD_TAUNT + &Unit::HandleNULLProc, // 12 SPELL_AURA_MOD_STUN + &Unit::HandleNULLProc, // 13 SPELL_AURA_MOD_DAMAGE_DONE + &Unit::HandleNULLProc, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN + &Unit::HandleNULLProc, // 15 SPELL_AURA_DAMAGE_SHIELD + &Unit::HandleNULLProc, // 16 SPELL_AURA_MOD_STEALTH + &Unit::HandleNULLProc, // 17 SPELL_AURA_MOD_STEALTH_DETECT + &Unit::HandleNULLProc, // 18 SPELL_AURA_MOD_INVISIBILITY + &Unit::HandleNULLProc, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION + &Unit::HandleNULLProc, // 20 SPELL_AURA_OBS_MOD_HEALTH + &Unit::HandleNULLProc, // 21 SPELL_AURA_OBS_MOD_MANA + &Unit::HandleNULLProc, // 22 SPELL_AURA_MOD_RESISTANCE + &Unit::HandleNULLProc, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL + &Unit::HandleNULLProc, // 24 SPELL_AURA_PERIODIC_ENERGIZE + &Unit::HandleNULLProc, // 25 SPELL_AURA_MOD_PACIFY + &Unit::HandleNULLProc, // 26 SPELL_AURA_MOD_ROOT + &Unit::HandleNULLProc, // 27 SPELL_AURA_MOD_SILENCE + &Unit::HandleNULLProc, // 28 SPELL_AURA_REFLECT_SPELLS + &Unit::HandleNULLProc, // 29 SPELL_AURA_MOD_STAT + &Unit::HandleNULLProc, // 30 SPELL_AURA_MOD_SKILL + &Unit::HandleNULLProc, // 31 SPELL_AURA_MOD_INCREASE_SPEED + &Unit::HandleNULLProc, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED + &Unit::HandleNULLProc, // 33 SPELL_AURA_MOD_DECREASE_SPEED + &Unit::HandleNULLProc, // 34 SPELL_AURA_MOD_INCREASE_HEALTH + &Unit::HandleNULLProc, // 35 SPELL_AURA_MOD_INCREASE_ENERGY + &Unit::HandleNULLProc, // 36 SPELL_AURA_MOD_SHAPESHIFT + &Unit::HandleNULLProc, // 37 SPELL_AURA_EFFECT_IMMUNITY + &Unit::HandleNULLProc, // 38 SPELL_AURA_STATE_IMMUNITY + &Unit::HandleNULLProc, // 39 SPELL_AURA_SCHOOL_IMMUNITY + &Unit::HandleNULLProc, // 40 SPELL_AURA_DAMAGE_IMMUNITY + &Unit::HandleNULLProc, // 41 SPELL_AURA_DISPEL_IMMUNITY + &Unit::HandleProcTriggerSpellAuraProc, // 42 SPELL_AURA_PROC_TRIGGER_SPELL + &Unit::HandleProcTriggerDamageAuraProc, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE + &Unit::HandleNULLProc, // 44 SPELL_AURA_TRACK_CREATURES + &Unit::HandleNULLProc, // 45 SPELL_AURA_TRACK_RESOURCES + &Unit::HandleNULLProc, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a-3.2.2a) + &Unit::HandleNULLProc, // 47 SPELL_AURA_MOD_PARRY_PERCENT + &Unit::HandleNULLProc, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect) + &Unit::HandleNULLProc, // 49 SPELL_AURA_MOD_DODGE_PERCENT + &Unit::HandleNULLProc, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT + &Unit::HandleNULLProc, // 51 SPELL_AURA_MOD_BLOCK_PERCENT + &Unit::HandleNULLProc, // 52 SPELL_AURA_MOD_CRIT_PERCENT + &Unit::HandleNULLProc, // 53 SPELL_AURA_PERIODIC_LEECH + &Unit::HandleNULLProc, // 54 SPELL_AURA_MOD_HIT_CHANCE + &Unit::HandleNULLProc, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE + &Unit::HandleNULLProc, // 56 SPELL_AURA_TRANSFORM + &Unit::HandleSpellCritChanceAuraProc, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE + &Unit::HandleNULLProc, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED + &Unit::HandleNULLProc, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE + &Unit::HandleNULLProc, // 60 SPELL_AURA_MOD_PACIFY_SILENCE + &Unit::HandleNULLProc, // 61 SPELL_AURA_MOD_SCALE + &Unit::HandleNULLProc, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL + &Unit::HandleNULLProc, // 63 unused (3.0.8a-3.2.2a) old SPELL_AURA_PERIODIC_MANA_FUNNEL + &Unit::HandleNULLProc, // 64 SPELL_AURA_PERIODIC_MANA_LEECH + &Unit::HandleModCastingSpeedNotStackAuraProc, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK + &Unit::HandleNULLProc, // 66 SPELL_AURA_FEIGN_DEATH + &Unit::HandleNULLProc, // 67 SPELL_AURA_MOD_DISARM + &Unit::HandleNULLProc, // 68 SPELL_AURA_MOD_STALKED + &Unit::HandleNULLProc, // 69 SPELL_AURA_SCHOOL_ABSORB + &Unit::HandleNULLProc, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell 41560 that has only visual effect (3.2.2a) + &Unit::HandleNULLProc, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL + &Unit::HandleModPowerCostSchoolAuraProc, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT + &Unit::HandleModPowerCostSchoolAuraProc, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL + &Unit::HandleReflectSpellsSchoolAuraProc, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL + &Unit::HandleNULLProc, // 75 SPELL_AURA_MOD_LANGUAGE + &Unit::HandleNULLProc, // 76 SPELL_AURA_FAR_SIGHT + &Unit::HandleMechanicImmuneResistanceAuraProc, // 77 SPELL_AURA_MECHANIC_IMMUNITY + &Unit::HandleNULLProc, // 78 SPELL_AURA_MOUNTED + &Unit::HandleModDamagePercentDoneAuraProc, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE + &Unit::HandleNULLProc, // 80 SPELL_AURA_MOD_PERCENT_STAT + &Unit::HandleNULLProc, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT + &Unit::HandleNULLProc, // 82 SPELL_AURA_WATER_BREATHING + &Unit::HandleNULLProc, // 83 SPELL_AURA_MOD_BASE_RESISTANCE + &Unit::HandleNULLProc, // 84 SPELL_AURA_MOD_REGEN + &Unit::HandleCantTrigger, // 85 SPELL_AURA_MOD_POWER_REGEN + &Unit::HandleNULLProc, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM + &Unit::HandleNULLProc, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN + &Unit::HandleNULLProc, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT + &Unit::HandleNULLProc, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT + &Unit::HandleNULLProc, // 90 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_RESIST_CHANCE + &Unit::HandleNULLProc, // 91 SPELL_AURA_MOD_DETECT_RANGE + &Unit::HandleNULLProc, // 92 SPELL_AURA_PREVENTS_FLEEING + &Unit::HandleNULLProc, // 93 SPELL_AURA_MOD_UNATTACKABLE + &Unit::HandleNULLProc, // 94 SPELL_AURA_INTERRUPT_REGEN + &Unit::HandleNULLProc, // 95 SPELL_AURA_GHOST + &Unit::HandleNULLProc, // 96 SPELL_AURA_SPELL_MAGNET + &Unit::HandleNULLProc, // 97 SPELL_AURA_MANA_SHIELD + &Unit::HandleNULLProc, // 98 SPELL_AURA_MOD_SKILL_TALENT + &Unit::HandleNULLProc, // 99 SPELL_AURA_MOD_ATTACK_POWER + &Unit::HandleNULLProc, //100 SPELL_AURA_AURAS_VISIBLE obsolete 3.x? all player can see all auras now, but still have 2 spells including GM-spell (1852,2855) + &Unit::HandleNULLProc, //101 SPELL_AURA_MOD_RESISTANCE_PCT + &Unit::HandleNULLProc, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS + &Unit::HandleNULLProc, //103 SPELL_AURA_MOD_TOTAL_THREAT + &Unit::HandleNULLProc, //104 SPELL_AURA_WATER_WALK + &Unit::HandleNULLProc, //105 SPELL_AURA_FEATHER_FALL + &Unit::HandleNULLProc, //106 SPELL_AURA_HOVER + &Unit::HandleNULLProc, //107 SPELL_AURA_ADD_FLAT_MODIFIER + &Unit::HandleAddPctModifierAuraProc, //108 SPELL_AURA_ADD_PCT_MODIFIER + &Unit::HandleNULLProc, //109 SPELL_AURA_ADD_TARGET_TRIGGER + &Unit::HandleNULLProc, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT + &Unit::HandleNULLProc, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER + &Unit::HandleOverrideClassScriptAuraProc, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS + &Unit::HandleNULLProc, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN + &Unit::HandleNULLProc, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT + &Unit::HandleNULLProc, //115 SPELL_AURA_MOD_HEALING + &Unit::HandleNULLProc, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT + &Unit::HandleMechanicImmuneResistanceAuraProc, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE + &Unit::HandleNULLProc, //118 SPELL_AURA_MOD_HEALING_PCT + &Unit::HandleNULLProc, //119 unused (3.0.8a-3.2.2a) old SPELL_AURA_SHARE_PET_TRACKING + &Unit::HandleNULLProc, //120 SPELL_AURA_UNTRACKABLE + &Unit::HandleNULLProc, //121 SPELL_AURA_EMPATHY + &Unit::HandleNULLProc, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT + &Unit::HandleNULLProc, //123 SPELL_AURA_MOD_TARGET_RESISTANCE + &Unit::HandleNULLProc, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER + &Unit::HandleNULLProc, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN + &Unit::HandleNULLProc, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT + &Unit::HandleNULLProc, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS + &Unit::HandleNULLProc, //128 SPELL_AURA_MOD_POSSESS_PET + &Unit::HandleNULLProc, //129 SPELL_AURA_MOD_SPEED_ALWAYS + &Unit::HandleNULLProc, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS + &Unit::HandleNULLProc, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS + &Unit::HandleNULLProc, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT + &Unit::HandleNULLProc, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT + &Unit::HandleNULLProc, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT + &Unit::HandleNULLProc, //135 SPELL_AURA_MOD_HEALING_DONE + &Unit::HandleNULLProc, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT + &Unit::HandleNULLProc, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE + &Unit::HandleHasteAuraProc, //138 SPELL_AURA_MOD_HASTE + &Unit::HandleNULLProc, //139 SPELL_AURA_FORCE_REACTION + &Unit::HandleNULLProc, //140 SPELL_AURA_MOD_RANGED_HASTE + &Unit::HandleNULLProc, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE + &Unit::HandleNULLProc, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT + &Unit::HandleNULLProc, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE + &Unit::HandleNULLProc, //144 SPELL_AURA_SAFE_FALL + &Unit::HandleNULLProc, //145 SPELL_AURA_MOD_PET_TALENT_POINTS + &Unit::HandleNULLProc, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE + &Unit::HandleNULLProc, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK + &Unit::HandleNULLProc, //148 SPELL_AURA_RETAIN_COMBO_POINTS + &Unit::HandleCantTrigger, //149 SPELL_AURA_REDUCE_PUSHBACK + &Unit::HandleNULLProc, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT + &Unit::HandleNULLProc, //151 SPELL_AURA_TRACK_STEALTHED + &Unit::HandleNULLProc, //152 SPELL_AURA_MOD_DETECTED_RANGE + &Unit::HandleNULLProc, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT + &Unit::HandleNULLProc, //154 SPELL_AURA_MOD_STEALTH_LEVEL + &Unit::HandleNULLProc, //155 SPELL_AURA_MOD_WATER_BREATHING + &Unit::HandleNULLProc, //156 SPELL_AURA_MOD_REPUTATION_GAIN + &Unit::HandleNULLProc, //157 SPELL_AURA_PET_DAMAGE_MULTI (single test like spell 20782, also single for 214 aura) + &Unit::HandleNULLProc, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE + &Unit::HandleNULLProc, //159 SPELL_AURA_NO_PVP_CREDIT + &Unit::HandleNULLProc, //160 SPELL_AURA_MOD_AOE_AVOIDANCE + &Unit::HandleNULLProc, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT + &Unit::HandleNULLProc, //162 SPELL_AURA_POWER_BURN_MANA + &Unit::HandleNULLProc, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS + &Unit::HandleNULLProc, //164 unused (3.0.8a-3.2.2a), only one test spell 10654 + &Unit::HandleNULLProc, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS + &Unit::HandleNULLProc, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT + &Unit::HandleNULLProc, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT + &Unit::HandleNULLProc, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS + &Unit::HandleNULLProc, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS + &Unit::HandleNULLProc, //170 SPELL_AURA_DETECT_AMORE different spells that ignore transformation effects + &Unit::HandleNULLProc, //171 SPELL_AURA_MOD_SPEED_NOT_STACK + &Unit::HandleNULLProc, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK + &Unit::HandleNULLProc, //173 unused (3.0.8a-3.2.2a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell + &Unit::HandleNULLProc, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT + &Unit::HandleNULLProc, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT + &Unit::HandleNULLProc, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end + &Unit::HandleNULLProc, //177 SPELL_AURA_AOE_CHARM (22 spells) + &Unit::HandleNULLProc, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE + &Unit::HandleNULLProc, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE + &Unit::HandleNULLProc, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS + &Unit::HandleNULLProc, //181 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS + &Unit::HandleNULLProc, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT + &Unit::HandleNULLProc, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746 + &Unit::HandleNULLProc, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE + &Unit::HandleNULLProc, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE + &Unit::HandleNULLProc, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE + &Unit::HandleNULLProc, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE + &Unit::HandleNULLProc, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE + &Unit::HandleNULLProc, //189 SPELL_AURA_MOD_RATING + &Unit::HandleNULLProc, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN + &Unit::HandleNULLProc, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED + &Unit::HandleNULLProc, //192 SPELL_AURA_HASTE_MELEE + &Unit::HandleNULLProc, //193 SPELL_AURA_HASTE_ALL (in fact combat (any type attack) speed pct) + &Unit::HandleNULLProc, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL + &Unit::HandleNULLProc, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL + &Unit::HandleNULLProc, //196 SPELL_AURA_MOD_COOLDOWN (single spell 24818 in 3.2.2a) + &Unit::HandleNULLProc, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCEe + &Unit::HandleNULLProc, //198 unused (3.0.8a-3.2.2a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS + &Unit::HandleNULLProc, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT + &Unit::HandleNULLProc, //200 SPELL_AURA_MOD_KILL_XP_PCT + &Unit::HandleNULLProc, //201 SPELL_AURA_FLY this aura enable flight mode... + &Unit::HandleNULLProc, //202 SPELL_AURA_CANNOT_BE_DODGED + &Unit::HandleNULLProc, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE + &Unit::HandleNULLProc, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE + &Unit::HandleNULLProc, //205 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_DAMAGE + &Unit::HandleNULLProc, //206 SPELL_AURA_MOD_FLIGHT_SPEED + &Unit::HandleNULLProc, //207 SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED + &Unit::HandleNULLProc, //208 SPELL_AURA_MOD_FLIGHT_SPEED_STACKING + &Unit::HandleNULLProc, //209 SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED_STACKING + &Unit::HandleNULLProc, //210 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACKING + &Unit::HandleNULLProc, //211 SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED_NOT_STACKING + &Unit::HandleNULLProc, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT + &Unit::HandleNULLProc, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage + &Unit::HandleNULLProc, //214 Tamed Pet Passive (single test like spell 20782, also single for 157 aura) + &Unit::HandleNULLProc, //215 SPELL_AURA_ARENA_PREPARATION + &Unit::HandleNULLProc, //216 SPELL_AURA_HASTE_SPELLS + &Unit::HandleNULLProc, //217 unused (3.0.8a-3.2.2a) + &Unit::HandleNULLProc, //218 SPELL_AURA_HASTE_RANGED + &Unit::HandleNULLProc, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT + &Unit::HandleNULLProc, //220 SPELL_AURA_MOD_RATING_FROM_STAT + &Unit::HandleNULLProc, //221 ignored + &Unit::HandleNULLProc, //222 unused (3.0.8a-3.2.2a) only for spell 44586 that not used in real spell cast + &Unit::HandleNULLProc, //223 dummy code (cast damage spell to attacker) and another dymmy (jump to another nearby raid member) + &Unit::HandleNULLProc, //224 unused (3.0.8a-3.2.2a) + &Unit::HandleMendingAuraProc, //225 SPELL_AURA_PRAYER_OF_MENDING + &Unit::HandleNULLProc, //226 SPELL_AURA_PERIODIC_DUMMY + &Unit::HandleNULLProc, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE + &Unit::HandleNULLProc, //228 SPELL_AURA_DETECT_STEALTH + &Unit::HandleNULLProc, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE + &Unit::HandleNULLProc, //230 Commanding Shout + &Unit::HandleProcTriggerSpellAuraProc, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE + &Unit::HandleNULLProc, //232 SPELL_AURA_MECHANIC_DURATION_MOD + &Unit::HandleNULLProc, //233 set model id to the one of the creature with id m_modifier.m_miscvalue + &Unit::HandleNULLProc, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK + &Unit::HandleNULLProc, //235 SPELL_AURA_MOD_DISPEL_RESIST + &Unit::HandleNULLProc, //236 SPELL_AURA_CONTROL_VEHICLE + &Unit::HandleNULLProc, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER + &Unit::HandleNULLProc, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER + &Unit::HandleNULLProc, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61 + &Unit::HandleNULLProc, //240 SPELL_AURA_MOD_EXPERTISE + &Unit::HandleNULLProc, //241 Forces the player to move forward + &Unit::HandleNULLProc, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING (only 2 test spels in 3.2.2a) + &Unit::HandleNULLProc, //243 faction reaction override spells + &Unit::HandleNULLProc, //244 SPELL_AURA_COMPREHEND_LANGUAGE + &Unit::HandleNULLProc, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS + &Unit::HandleNULLProc, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL + &Unit::HandleNULLProc, //247 target to become a clone of the caster + &Unit::HandleNULLProc, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE + &Unit::HandleNULLProc, //249 SPELL_AURA_CONVERT_RUNE + &Unit::HandleNULLProc, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2 + &Unit::HandleNULLProc, //251 SPELL_AURA_MOD_ENEMY_DODGE + &Unit::HandleNULLProc, //252 SPELL_AURA_SLOW_ALL + &Unit::HandleNULLProc, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE + &Unit::HandleNULLProc, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield + &Unit::HandleNULLProc, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT + &Unit::HandleNULLProc, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select + &Unit::HandleNULLProc, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select + &Unit::HandleNULLProc, //258 SPELL_AURA_MOD_SPELL_VISUAL + &Unit::HandleNULLProc, //259 corrupt healing over time spell + &Unit::HandleNULLProc, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code + &Unit::HandleNULLProc, //261 SPELL_AURA_PHASE undetectable invisibility? + &Unit::HandleNULLProc, //262 ignore combat/aura state? + &Unit::HandleNULLProc, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask + &Unit::HandleNULLProc, //264 unused (3.0.8a-3.2.2a) + &Unit::HandleNULLProc, //265 unused (3.0.8a-3.2.2a) + &Unit::HandleNULLProc, //266 unused (3.0.8a-3.2.2a) + &Unit::HandleNULLProc, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL + &Unit::HandleNULLProc, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT + &Unit::HandleNULLProc, //269 SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL + &Unit::HandleNULLProc, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST (unused in 3.2.2a) + &Unit::HandleModDamageFromCasterAuraProc, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER + &Unit::HandleMaelstromWeaponAuraProc, //272 SPELL_AURA_MAELSTROM_WEAPON (unclear use for aura, it used in (3.2.2a...3.3.0) in single spell 53817 that spellmode stacked and charged spell expected to be drop as stack + &Unit::HandleNULLProc, //273 SPELL_AURA_X_RAY (client side implementation) + &Unit::HandleNULLProc, //274 proc free shot? + &Unit::HandleNULLProc, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select + &Unit::HandleNULLProc, //276 mod damage % mechanic? + &Unit::HandleNULLProc, //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select + &Unit::HandleNULLProc, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon + &Unit::HandleNULLProc, //279 visual effects? 58836 and 57507 + &Unit::HandleNULLProc, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT + &Unit::HandleNULLProc, //281 SPELL_AURA_MOD_HONOR_GAIN + &Unit::HandleNULLProc, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT + &Unit::HandleNULLProc, //283 SPELL_AURA_MOD_HEALING_RECEIVED + &Unit::HandleNULLProc, //284 51 spells + &Unit::HandleNULLProc, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR + &Unit::HandleNULLProc, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT + &Unit::HandleNULLProc, //287 SPELL_AURA_DEFLECT_SPELLS + &Unit::HandleNULLProc, //288 increase parry/deflect, prevent attack (single spell used 67801) + &Unit::HandleNULLProc, //289 unused (3.2.2a) + &Unit::HandleNULLProc, //290 SPELL_AURA_MOD_ALL_CRIT_CHANCE + &Unit::HandleNULLProc, //291 SPELL_AURA_MOD_QUEST_XP_PCT + &Unit::HandleNULLProc, //292 call stabled pet + &Unit::HandleNULLProc, //293 3 spells + &Unit::HandleNULLProc, //294 2 spells, possible prevent mana regen + &Unit::HandleNULLProc, //295 unused (3.2.2a) + &Unit::HandleNULLProc, //296 2 spells + &Unit::HandleNULLProc, //297 1 spell (counter spell school?) + &Unit::HandleNULLProc, //298 unused (3.2.2a) + &Unit::HandleNULLProc, //299 unused (3.2.2a) + &Unit::HandleNULLProc, //300 3 spells (share damage?) + &Unit::HandleNULLProc, //301 5 spells + &Unit::HandleNULLProc, //302 unused (3.2.2a) + &Unit::HandleNULLProc, //303 17 spells + &Unit::HandleNULLProc, //304 2 spells (alcohol effect?) + &Unit::HandleNULLProc, //305 SPELL_AURA_MOD_MINIMUM_SPEED + &Unit::HandleNULLProc, //306 1 spell + &Unit::HandleNULLProc, //307 absorb healing? + &Unit::HandleNULLProc, //308 new aura for hunter traps + &Unit::HandleNULLProc, //309 absorb healing? + &Unit::HandleNULLProc, //310 pet avoidance passive? + &Unit::HandleNULLProc, //311 0 spells in 3.3 + &Unit::HandleNULLProc, //312 0 spells in 3.3 + &Unit::HandleNULLProc, //313 0 spells in 3.3 + &Unit::HandleNULLProc, //314 1 test spell (reduce duration of silince/magic) + &Unit::HandleNULLProc, //315 underwater walking + &Unit::HandleNULLProc //316 makes haste affect HOT/DOT ticks +}; + +bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, SpellAuraHolder* holder, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, SpellProcEventEntry const*& spellProcEvent ) +{ + SpellEntry const* spellProto = holder->GetSpellProto (); + + // Get proc Event Entry + spellProcEvent = sSpellMgr.GetSpellProcEvent(spellProto->Id); + + // Get EventProcFlag + uint32 EventProcFlag; + if (spellProcEvent && spellProcEvent->procFlags) // if exist get custom spellProcEvent->procFlags + EventProcFlag = spellProcEvent->procFlags; + else + EventProcFlag = spellProto->procFlags; // else get from spell proto + // Continue if no trigger exist + if (!EventProcFlag) + return false; + + // Check spellProcEvent data requirements + if(!SpellMgr::IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra)) + return false; + + // In most cases req get honor or XP from kill + if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER) + { + bool allow = ((Player*)this)->isHonorOrXPTarget(pVictim); + // Shadow Word: Death - can trigger from every kill + if (holder->GetId() == 32409) + allow = true; + if (!allow) + return false; + } + // Aura added by spell can`t trogger from self (prevent drop charges/do triggers) + // But except periodic triggers (can triggered from self) + if(procSpell && procSpell->Id == spellProto->Id && !(spellProto->procFlags & PROC_FLAG_ON_TAKE_PERIODIC)) + return false; + + // Check if current equipment allows aura to proc + if(!isVictim && GetTypeId() == TYPEID_PLAYER) + { + if(spellProto->EquippedItemClass == ITEM_CLASS_WEAPON) + { + Item *item = NULL; + if(attType == BASE_ATTACK) + item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + else if (attType == OFF_ATTACK) + item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + else + item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED); + + if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_WEAPON || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + return false; + } + else if(spellProto->EquippedItemClass == ITEM_CLASS_ARMOR) + { + // Check if player is wearing shield + Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); + if(!item || item->IsBroken() || item->GetProto()->Class != ITEM_CLASS_ARMOR || !((1<GetProto()->SubClass) & spellProto->EquippedItemSubClassMask)) + return false; + } + } + // Get chance from spell + float chance = (float)spellProto->procChance; + // If in spellProcEvent exist custom chance, chance = spellProcEvent->customChance; + if(spellProcEvent && spellProcEvent->customChance) + chance = spellProcEvent->customChance; + // If PPM exist calculate chance from PPM + if(!isVictim && spellProcEvent && spellProcEvent->ppmRate != 0) + { + uint32 WeaponSpeed = GetAttackTime(attType); + chance = GetPPMProcChance(WeaponSpeed, spellProcEvent->ppmRate); + } + // Apply chance modifer aura + if(Player* modOwner = GetSpellModOwner()) + { + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_CHANCE_OF_SUCCESS,chance); + modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_FREQUENCY_OF_SUCCESS,chance); + } + + return roll_chance_f(chance); +} + +bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) +{ + SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto(); + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = 0; + Unit* target = pVictim; + int32 basepoints0 = 0; + + switch(hasteSpell->SpellFamilyName) + { + case SPELLFAMILY_ROGUE: + { + switch(hasteSpell->Id) + { + // Blade Flurry + case 13877: + case 33735: + { + target = SelectRandomUnfriendlyTarget(pVictim); + if(!target) + return false; + basepoints0 = damage; + triggered_spell_id = 22482; + break; + } + } + break; + } + } + + // processed charge only counting case + if(!triggered_spell_id) + return true; + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",hasteSpell->Id,triggered_spell_id); + return false; + } + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + if(basepoints0) + CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + else + CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) +{ + if (!procSpell) + return false; + + SpellEntry const *triggeredByAuraSpell = triggeredByAura->GetSpellProto(); + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = 0; + Unit* target = pVictim; + int32 basepoints0 = 0; + + switch(triggeredByAuraSpell->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + { + switch(triggeredByAuraSpell->Id) + { + // Focus Magic + case 54646: + { + Unit* caster = triggeredByAura->GetCaster(); + if(!caster) + return false; + + triggered_spell_id = 54648; + target = caster; + break; + } + } + } + } + + // processed charge only counting case + if(!triggered_spell_id) + return true; + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",triggeredByAuraSpell->Id,triggered_spell_id); + return false; + } + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + if(basepoints0) + CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + else + CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) +{ + SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); + SpellEffectIndex effIndex = triggeredByAura->GetEffIndex(); + int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + // some dummy spells have trigger spell in spell data already (from 3.0.3) + uint32 triggered_spell_id = dummySpell->EffectApplyAuraName[effIndex] == SPELL_AURA_DUMMY ? dummySpell->EffectTriggerSpell[effIndex] : 0; + Unit* target = pVictim; + int32 basepoints[MAX_EFFECT_INDEX] = {0, 0, 0}; + + switch(dummySpell->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + { + switch (dummySpell->Id) + { + // Eye for an Eye + case 9799: + case 25988: + { + // return damage % to attacker but < 50% own total health + basepoints[0] = triggerAmount*int32(damage)/100; + if (basepoints[0] > (int32)GetMaxHealth()/2) + basepoints[0] = (int32)GetMaxHealth()/2; + + triggered_spell_id = 25997; + break; + } + // Sweeping Strikes (NPC spells may be) + case 18765: + case 35429: + { + // prevent chain of triggered spell from same triggered spell + if (procSpell && procSpell->Id == 26654) + return false; + + target = SelectRandomUnfriendlyTarget(pVictim); + if(!target) + return false; + + triggered_spell_id = 26654; + break; + } + // Twisted Reflection (boss spell) + case 21063: + triggered_spell_id = 21064; + break; + // Unstable Power + case 24658: + { + if (!procSpell || procSpell->Id == 24659) + return false; + // Need remove one 24659 aura + RemoveSingleAuraHolderFromStack(24659); + return true; + } + // Restless Strength + case 24661: + { + // Need remove one 24662 aura + RemoveSingleAuraHolderFromStack(24662); + return true; + } + // Adaptive Warding (Frostfire Regalia set) + case 28764: + { + if(!procSpell) + return false; + + // find Mage Armor + bool found = false; + AuraList const& mRegenInterupt = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); + for(AuraList::const_iterator iter = mRegenInterupt.begin(); iter != mRegenInterupt.end(); ++iter) + { + if(SpellEntry const* iterSpellProto = (*iter)->GetSpellProto()) + { + if(iterSpellProto->SpellFamilyName==SPELLFAMILY_MAGE && (iterSpellProto->SpellFamilyFlags & UI64LIT(0x10000000))) + { + found=true; + break; + } + } + } + if(!found) + return false; + + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + case SPELL_SCHOOL_NORMAL: + case SPELL_SCHOOL_HOLY: + return false; // ignored + case SPELL_SCHOOL_FIRE: triggered_spell_id = 28765; break; + case SPELL_SCHOOL_NATURE: triggered_spell_id = 28768; break; + case SPELL_SCHOOL_FROST: triggered_spell_id = 28766; break; + case SPELL_SCHOOL_SHADOW: triggered_spell_id = 28769; break; + case SPELL_SCHOOL_ARCANE: triggered_spell_id = 28770; break; + default: + return false; + } + + target = this; + break; + } + // Obsidian Armor (Justice Bearer`s Pauldrons shoulder) + case 27539: + { + if(!procSpell) + return false; + + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + case SPELL_SCHOOL_NORMAL: + return false; // ignore + case SPELL_SCHOOL_HOLY: triggered_spell_id = 27536; break; + case SPELL_SCHOOL_FIRE: triggered_spell_id = 27533; break; + case SPELL_SCHOOL_NATURE: triggered_spell_id = 27538; break; + case SPELL_SCHOOL_FROST: triggered_spell_id = 27534; break; + case SPELL_SCHOOL_SHADOW: triggered_spell_id = 27535; break; + case SPELL_SCHOOL_ARCANE: triggered_spell_id = 27540; break; + default: + return false; + } + + target = this; + break; + } + // Mana Leech (Passive) (Priest Pet Aura) + case 28305: + { + // Cast on owner + target = GetOwner(); + if(!target) + return false; + + triggered_spell_id = 34650; + break; + } + // Divine purpose + case 31871: + case 31872: + { + // Roll chance + if (!roll_chance_i(triggerAmount)) + return false; + + // Remove any stun effect on target + SpellAuraHolderMap& Auras = pVictim->GetSpellAuraHolderMap(); + for(SpellAuraHolderMap::const_iterator iter = Auras.begin(); iter != Auras.end();) + { + SpellEntry const *spell = iter->second->GetSpellProto(); + + if( spell->Mechanic == MECHANIC_STUN || + iter->second->HasAuraAndMechanicEffect(MECHANIC_STUN)) + { + pVictim->RemoveAurasDueToSpell(spell->Id); + iter = Auras.begin(); + } + else + ++iter; + } + return true; + } + // Mark of Malice + case 33493: + { + // Cast finish spell at last charge + if (triggeredByAura->GetHolder()->GetAuraCharges() > 1) + return false; + + target = this; + triggered_spell_id = 33494; + break; + } + // Vampiric Aura (boss spell) + case 38196: + { + basepoints[0] = 3 * damage; // 300% + if (basepoints[0] < 0) + return false; + + triggered_spell_id = 31285; + target = this; + break; + } + // Aura of Madness (Darkmoon Card: Madness trinket) + //===================================================== + // 39511 Sociopath: +35 strength (Paladin, Rogue, Druid, Warrior) + // 40997 Delusional: +70 attack power (Rogue, Hunter, Paladin, Warrior, Druid) + // 40998 Kleptomania: +35 agility (Warrior, Rogue, Paladin, Hunter, Druid) + // 40999 Megalomania: +41 damage/healing (Druid, Shaman, Priest, Warlock, Mage, Paladin) + // 41002 Paranoia: +35 spell/melee/ranged crit strike rating (All classes) + // 41005 Manic: +35 haste (spell, melee and ranged) (All classes) + // 41009 Narcissism: +35 intellect (Druid, Shaman, Priest, Warlock, Mage, Paladin, Hunter) + // 41011 Martyr Complex: +35 stamina (All classes) + // 41406 Dementia: Every 5 seconds either gives you +5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) + // 41409 Dementia: Every 5 seconds either gives you -5% damage/healing. (Druid, Shaman, Priest, Warlock, Mage, Paladin) + case 39446: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Select class defined buff + switch (getClass()) + { + case CLASS_PALADIN: // 39511,40997,40998,40999,41002,41005,41009,41011,41409 + case CLASS_DRUID: // 39511,40997,40998,40999,41002,41005,41009,41011,41409 + { + uint32 RandomSpell[]={39511,40997,40998,40999,41002,41005,41009,41011,41409}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + case CLASS_ROGUE: // 39511,40997,40998,41002,41005,41011 + case CLASS_WARRIOR: // 39511,40997,40998,41002,41005,41011 + { + uint32 RandomSpell[]={39511,40997,40998,41002,41005,41011}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + case CLASS_PRIEST: // 40999,41002,41005,41009,41011,41406,41409 + case CLASS_SHAMAN: // 40999,41002,41005,41009,41011,41406,41409 + case CLASS_MAGE: // 40999,41002,41005,41009,41011,41406,41409 + case CLASS_WARLOCK: // 40999,41002,41005,41009,41011,41406,41409 + { + uint32 RandomSpell[]={40999,41002,41005,41009,41011,41406,41409}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + case CLASS_HUNTER: // 40997,40999,41002,41005,41009,41011,41406,41409 + { + uint32 RandomSpell[]={40997,40999,41002,41005,41009,41011,41406,41409}; + triggered_spell_id = RandomSpell[ irand(0, sizeof(RandomSpell)/sizeof(uint32) - 1) ]; + break; + } + default: + return false; + } + + target = this; + if (roll_chance_i(10)) + ((Player*)this)->Say("This is Madness!", LANG_UNIVERSAL); + break; + } + // Sunwell Exalted Caster Neck (Shattered Sun Pendant of Acumen neck) + // cast 45479 Light's Wrath if Exalted by Aldor + // cast 45429 Arcane Bolt if Exalted by Scryers + case 45481: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45479; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + // triggered at positive/self casts also, current attack target used then + if(IsFriendlyTo(target)) + { + target = getVictim(); + if(!target) + { + uint64 selected_guid = ((Player *)this)->GetSelection(); + target = ObjectAccessor::GetUnit(*this,selected_guid); + if(!target) + return false; + } + if(IsFriendlyTo(target)) + return false; + } + + triggered_spell_id = 45429; + break; + } + return false; + } + // Sunwell Exalted Melee Neck (Shattered Sun Pendant of Might neck) + // cast 45480 Light's Strength if Exalted by Aldor + // cast 45428 Arcane Strike if Exalted by Scryers + case 45482: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45480; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45428; + break; + } + return false; + } + // Sunwell Exalted Tank Neck (Shattered Sun Pendant of Resolve neck) + // cast 45431 Arcane Insight if Exalted by Aldor + // cast 45432 Light's Ward if Exalted by Scryers + case 45483: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45432; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45431; + break; + } + return false; + } + // Sunwell Exalted Healer Neck (Shattered Sun Pendant of Restoration neck) + // cast 45478 Light's Salvation if Exalted by Aldor + // cast 45430 Arcane Surge if Exalted by Scryers + case 45484: + { + if(GetTypeId() != TYPEID_PLAYER) + return false; + + // Get Aldor reputation rank + if (((Player *)this)->GetReputationRank(932) == REP_EXALTED) + { + target = this; + triggered_spell_id = 45478; + break; + } + // Get Scryers reputation rank + if (((Player *)this)->GetReputationRank(934) == REP_EXALTED) + { + triggered_spell_id = 45430; + break; + } + return false; + } + /* + // Sunwell Exalted Caster Neck (??? neck) + // cast ??? Light's Wrath if Exalted by Aldor + // cast ??? Arcane Bolt if Exalted by Scryers*/ + case 46569: + return false; // old unused version + // Living Seed + case 48504: + { + triggered_spell_id = 48503; + basepoints[0] = triggerAmount; + target = this; + break; + } + // Vampiric Touch (generic, used by some boss) + case 52723: + case 60501: + { + triggered_spell_id = 52724; + basepoints[0] = damage / 2; + target = this; + break; + } + // Shadowfiend Death (Gain mana if pet dies with Glyph of Shadowfiend) + case 57989: + { + Unit *owner = GetOwner(); + if (!owner || owner->GetTypeId() != TYPEID_PLAYER) + return false; + + // Glyph of Shadowfiend (need cast as self cast for owner, no hidden cooldown) + owner->CastSpell(owner,58227,true,castItem,triggeredByAura); + return true; + } + // Glyph of Life Tap + case 63320: + triggered_spell_id = 63321; + break; + // Item - Shadowmourne Legendary + case 71903: + { + if (!roll_chance_i(triggerAmount)) + return false; + + Aura *aur = GetAura(71905, EFFECT_INDEX_0); + if (aur && uint32(aur->GetStackAmount() + 1) >= aur->GetSpellProto()->StackAmount) + { + RemoveAurasDueToSpell(71905); + CastSpell(this, 71904, true); // Chaos Bane + return true; + } + else + triggered_spell_id = 71905; + + break; + } + } + break; + } + case SPELLFAMILY_MAGE: + { + // Magic Absorption + if (dummySpell->SpellIconID == 459) // only this spell have SpellIconID == 459 and dummy aura + { + if (getPowerType() != POWER_MANA) + return false; + + // mana reward + basepoints[0] = (triggerAmount * GetMaxPower(POWER_MANA) / 100); + target = this; + triggered_spell_id = 29442; + break; + } + // Master of Elements + if (dummySpell->SpellIconID == 1920) + { + if(!procSpell) + return false; + + // mana cost save + int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; + basepoints[0] = cost * triggerAmount/100; + if (basepoints[0] <=0) + return false; + + target = this; + triggered_spell_id = 29077; + break; + } + + // Arcane Potency + if (dummySpell->SpellIconID == 2120) + { + if(!procSpell) + return false; + + target = this; + switch (dummySpell->Id) + { + case 31571: triggered_spell_id = 57529; break; + case 31572: triggered_spell_id = 57531; break; + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u",dummySpell->Id); + return false; + } + break; + } + + // Hot Streak + if (dummySpell->SpellIconID == 2999) + { + if (effIndex != EFFECT_INDEX_0) + return true; + Aura *counter = GetAura(triggeredByAura->GetId(), EFFECT_INDEX_1); + if (!counter) + return true; + + // Count spell criticals in a row in second aura + Modifier *mod = counter->GetModifier(); + if (procEx & PROC_EX_CRITICAL_HIT) + { + mod->m_amount *=2; + if (mod->m_amount < 100) // not enough + return true; + // Crititcal counted -> roll chance + if (roll_chance_i(triggerAmount)) + CastSpell(this, 48108, true, castItem, triggeredByAura); + } + mod->m_amount = 25; + return true; + } + // Burnout + if (dummySpell->SpellIconID == 2998) + { + if(!procSpell) + return false; + + int32 cost = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; + basepoints[0] = cost * triggerAmount/100; + if (basepoints[0] <=0) + return false; + triggered_spell_id = 44450; + target = this; + break; + } + // Incanter's Regalia set (add trigger chance to Mana Shield) + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + target = this; + triggered_spell_id = 37436; + break; + } + switch(dummySpell->Id) + { + // Ignite + case 11119: + case 11120: + case 12846: + case 12847: + case 12848: + { + switch (dummySpell->Id) + { + case 11119: basepoints[0] = int32(0.04f*damage); break; + case 11120: basepoints[0] = int32(0.08f*damage); break; + case 12846: basepoints[0] = int32(0.12f*damage); break; + case 12847: basepoints[0] = int32(0.16f*damage); break; + case 12848: basepoints[0] = int32(0.20f*damage); break; + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (IG)",dummySpell->Id); + return false; + } + + triggered_spell_id = 12654; + break; + } + // Glyph of Ice Block + case 56372: + { + if (GetTypeId() != TYPEID_PLAYER) + return false; + + // not 100% safe with client version switches but for 3.1.3 no spells with cooldown that can have mage player except Frost Nova. + ((Player*)this)->RemoveSpellCategoryCooldown(35, true); + return true; + } + // Glyph of Polymorph + case 56375: + { + if (!pVictim || !pVictim->isAlive()) + return false; + + pVictim->RemoveSpellsCausingAura(SPELL_AURA_PERIODIC_DAMAGE); + pVictim->RemoveSpellsCausingAura(SPELL_AURA_PERIODIC_DAMAGE_PERCENT); + return true; + } + // Blessing of Ancient Kings + case 64411: + { + // for DOT procs + if (!IsPositiveSpell(procSpell->Id)) + return false; + + triggered_spell_id = 64413; + basepoints[0] = damage * 15 / 100; + break; + } + } + break; + } + case SPELLFAMILY_WARRIOR: + { + // Retaliation + if (dummySpell->SpellFamilyFlags == UI64LIT(0x0000000800000000)) + { + // check attack comes not from behind + if (!HasInArc(M_PI_F, pVictim)) + return false; + + triggered_spell_id = 22858; + break; + } + // Second Wind + if (dummySpell->SpellIconID == 1697) + { + // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example) + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) + return false; + // Need stun or root mechanic + if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_ROOT_AND_STUN_MASK)) + return false; + + switch (dummySpell->Id) + { + case 29838: triggered_spell_id=29842; break; + case 29834: triggered_spell_id=29841; break; + case 42770: triggered_spell_id=42771; break; + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (SW)",dummySpell->Id); + return false; + } + + target = this; + break; + } + // Damage Shield + if (dummySpell->SpellIconID == 3214) + { + triggered_spell_id = 59653; + basepoints[0] = GetShieldBlockValue() * triggerAmount / 100; + break; + } + + // Sweeping Strikes + if (dummySpell->Id == 12328) + { + // prevent chain of triggered spell from same triggered spell + if(procSpell && procSpell->Id == 26654) + return false; + + target = SelectRandomUnfriendlyTarget(pVictim); + if(!target) + return false; + + triggered_spell_id = 26654; + break; + } + break; + } + case SPELLFAMILY_WARLOCK: + { + // Seed of Corruption + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) + { + Modifier* mod = triggeredByAura->GetModifier(); + // if damage is more than need or target die from damage deal finish spell + if( mod->m_amount <= (int32)damage || GetHealth() <= damage ) + { + // remember guid before aura delete + uint64 casterGuid = triggeredByAura->GetCasterGUID(); + + // Remove aura (before cast for prevent infinite loop handlers) + RemoveAurasDueToSpell(triggeredByAura->GetId()); + + // Cast finish spell (triggeredByAura already not exist!) + CastSpell(this, 27285, true, castItem, NULL, casterGuid); + return true; // no hidden cooldown + } + + // Damage counting + mod->m_amount-=damage; + return true; + } + // Seed of Corruption (Mobs cast) - no die req + if (dummySpell->SpellFamilyFlags == UI64LIT(0x0) && dummySpell->SpellIconID == 1932) + { + Modifier* mod = triggeredByAura->GetModifier(); + // if damage is more than need deal finish spell + if( mod->m_amount <= (int32)damage ) + { + // remember guid before aura delete + uint64 casterGuid = triggeredByAura->GetCasterGUID(); + + // Remove aura (before cast for prevent infinite loop handlers) + RemoveAurasDueToSpell(triggeredByAura->GetId()); + + // Cast finish spell (triggeredByAura already not exist!) + CastSpell(this, 32865, true, castItem, NULL, casterGuid); + return true; // no hidden cooldown + } + // Damage counting + mod->m_amount-=damage; + return true; + } + // Fel Synergy + if (dummySpell->SpellIconID == 3222) + { + target = GetPet(); + if (!target) + return false; + basepoints[0] = damage * triggerAmount / 100; + triggered_spell_id = 54181; + break; + } + switch(dummySpell->Id) + { + // Nightfall & Glyph of Corruption + case 18094: + case 18095: + case 56218: + { + target = this; + triggered_spell_id = 17941; + break; + } + //Soul Leech + case 30293: + case 30295: + case 30296: + { + // health + basepoints[0] = int32(damage*triggerAmount/100); + target = this; + triggered_spell_id = 30294; + break; + } + // Shadowflame (Voidheart Raiment set bonus) + case 37377: + { + triggered_spell_id = 37379; + break; + } + // Pet Healing (Corruptor Raiment or Rift Stalker Armor) + case 37381: + { + target = GetPet(); + if (!target) + return false; + + // heal amount + basepoints[0] = damage * triggerAmount/100; + triggered_spell_id = 37382; + break; + } + // Shadowflame Hellfire (Voidheart Raiment set bonus) + case 39437: + { + triggered_spell_id = 37378; + break; + } + // Siphon Life + case 63108: + { + if (triggeredByAura->GetEffIndex() != EFFECT_INDEX_0) + return false; + + // Glyph of Siphon Life + if (Aura *aur = GetAura(56216, EFFECT_INDEX_0)) + triggerAmount += triggerAmount * aur->GetModifier()->m_amount / 100; + + basepoints[0] = int32(damage * triggerAmount / 100); + triggered_spell_id = 63106; + break; + } + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Vampiric Touch + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + { + if(!pVictim || !pVictim->isAlive()) + return false; + + // pVictim is caster of aura + if(triggeredByAura->GetCasterGUID() != pVictim->GetGUID()) + return false; + + // Energize 0.25% of max. mana + pVictim->CastSpell(pVictim,57669,true,castItem,triggeredByAura); + return true; // no hidden cooldown + } + + switch(dummySpell->SpellIconID) + { + // Improved Shadowform + case 217: + { + if(!roll_chance_i(triggerAmount)) + return false; + + RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); + RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED); + break; + } + // Divine Aegis + case 2820: + { + basepoints[0] = damage * triggerAmount/100; + triggered_spell_id = 47753; + break; + } + // Empowered Renew + case 3021: + { + if (!procSpell) + return false; + + // avoid double triggering from 2 auras + if (triggeredByAura->GetEffIndex() != EFFECT_INDEX_1) + return false; + + + // Renew + Aura* healingAura = pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_PRIEST, UI64LIT(0x40), 0, GetGUID()); + if (!healingAura) + return false; + + int32 healingfromticks = healingAura->GetModifier()->m_amount * GetSpellAuraMaxTicks(procSpell); + + basepoints[0] = healingfromticks * triggerAmount / 100; + triggered_spell_id = 63544; + break; + } + // Improved Devouring Plague + case 3790: + { + if (!procSpell) + return false; + + if (triggeredByAura->GetEffIndex() != EFFECT_INDEX_1) + return false; + + Aura* leachAura = pVictim->GetAura(SPELL_AURA_PERIODIC_LEECH, SPELLFAMILY_PRIEST, UI64LIT(0x02000000), NULL, GetGUID()); + if (!leachAura) + return false; + + int32 damagefromticks = leachAura->GetModifier()->m_amount * GetSpellAuraMaxTicks(procSpell); + basepoints[0] = damagefromticks * triggerAmount / 100; + triggered_spell_id = 63675; + break; + } + } + + switch(dummySpell->Id) + { + // Vampiric Embrace + case 15286: + { + // Return if self damage + if (this == pVictim) + return false; + + // Heal amount - Self/Team + int32 team = triggerAmount*damage/500; + int32 self = triggerAmount*damage/100 - team; + CastCustomSpell(this,15290,&team,&self,NULL,true,castItem,triggeredByAura); + return true; // no hidden cooldown + } + // Priest Tier 6 Trinket (Ashtongue Talisman of Acumen) + case 40438: + { + // Shadow Word: Pain + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000008000)) + triggered_spell_id = 40441; + // Renew + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) + triggered_spell_id = 40440; + else + return false; + + target = this; + break; + } + // Oracle Healing Bonus ("Garments of the Oracle" set) + case 26169: + { + // heal amount + basepoints[0] = int32(damage * 10/100); + target = this; + triggered_spell_id = 26170; + break; + } + // Frozen Shadoweave (Shadow's Embrace set) warning! its not only priest set + case 39372: + { + if(!procSpell || (GetSpellSchoolMask(procSpell) & (SPELL_SCHOOL_MASK_FROST | SPELL_SCHOOL_MASK_SHADOW))==0 ) + return false; + + // heal amount + basepoints[0] = damage * triggerAmount/100; + target = this; + triggered_spell_id = 39373; + break; + } + // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus) + case 28809: + { + triggered_spell_id = 28810; + break; + } + // Glyph of Dispel Magic + case 55677: + { + if(!target->IsFriendlyTo(this)) + return false; + + basepoints[0] = int32(target->GetMaxHealth() * triggerAmount / 100); + // triggered_spell_id in spell data + break; + } + } + break; + } + case SPELLFAMILY_DRUID: + { + switch(dummySpell->Id) + { + // Leader of the Pack + case 24932: + { + // dummy m_amount store health percent (!=0 if Improved Leader of the Pack applied) + int32 heal_percent = triggeredByAura->GetModifier()->m_amount; + if (!heal_percent) + return false; + + // check explicitly only to prevent mana cast when halth cast cooldown + if (cooldown && ((Player*)this)->HasSpellCooldown(34299)) + return false; + + // health + triggered_spell_id = 34299; + basepoints[0] = GetMaxHealth() * heal_percent / 100; + target = this; + + // mana to caster + if (triggeredByAura->GetCasterGUID() == GetGUID()) + { + if (SpellEntry const* manaCastEntry = sSpellStore.LookupEntry(60889)) + { + int32 mana_percent = manaCastEntry->CalculateSimpleValue(EFFECT_INDEX_0) * heal_percent; + CastCustomSpell(this, manaCastEntry, &mana_percent, NULL, NULL, true, castItem, triggeredByAura); + } + } + break; + } + // Healing Touch (Dreamwalker Raiment set) + case 28719: + { + // mana back + basepoints[0] = int32(procSpell->manaCost * 30 / 100); + target = this; + triggered_spell_id = 28742; + break; + } + // Healing Touch Refund (Idol of Longevity trinket) + case 28847: + { + target = this; + triggered_spell_id = 28848; + break; + } + // Mana Restore (Malorne Raiment set / Malorne Regalia set) + case 37288: + case 37295: + { + target = this; + triggered_spell_id = 37238; + break; + } + // Druid Tier 6 Trinket + case 40442: + { + float chance; + + // Starfire + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) + { + triggered_spell_id = 40445; + chance = 25.0f; + } + // Rejuvenation + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000010)) + { + triggered_spell_id = 40446; + chance = 25.0f; + } + // Mangle (Bear) and Mangle (Cat) + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000044000000000)) + { + triggered_spell_id = 40452; + chance = 40.0f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + target = this; + break; + } + // Maim Interrupt + case 44835: + { + // Deadly Interrupt Effect + triggered_spell_id = 32747; + break; + } + // Glyph of Rejuvenation + case 54754: + { + // less 50% health + if (pVictim->GetMaxHealth() < 2 * pVictim->GetHealth()) + return false; + basepoints[0] = triggerAmount * damage / 100; + triggered_spell_id = 54755; + break; + } + // Item - Druid T10 Restoration 4P Bonus (Rejuvenation) + case 70664: + { + if (!procSpell || GetTypeId() != TYPEID_PLAYER) + return false; + + float radius; + if (procSpell->EffectRadiusIndex[EFFECT_INDEX_0]) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(procSpell->EffectRadiusIndex[EFFECT_INDEX_0])); + else + radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(procSpell->rangeIndex)); + + ((Player*)this)->ApplySpellMod(procSpell->Id, SPELLMOD_RADIUS, radius,NULL); + + Unit *second = pVictim->SelectRandomFriendlyTarget(pVictim, radius); + + if (!second) + return false; + + pVictim->CastSpell(second, procSpell, true, NULL, triggeredByAura, GetGUID()); + return true; + } + } + // Eclipse + if (dummySpell->SpellIconID == 2856) + { + if (!procSpell) + return false; + // Only 0 aura can proc + if (effIndex != EFFECT_INDEX_0) + return true; + // Wrath crit + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) + { + if (HasAura(48517)) + return false; + if (!roll_chance_i(60)) + return false; + triggered_spell_id = 48518; + target = this; + break; + } + // Starfire crit + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000004)) + { + if (HasAura(48518)) + return false; + triggered_spell_id = 48517; + target = this; + break; + } + return false; + } + // Living Seed + else if (dummySpell->SpellIconID == 2860) + { + triggered_spell_id = 48504; + basepoints[0] = triggerAmount * damage / 100; + break; + } + break; + } + case SPELLFAMILY_ROGUE: + { + switch(dummySpell->Id) + { + // Deadly Throw Interrupt + case 32748: + { + // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw + if (this == pVictim) + return false; + + triggered_spell_id = 32747; + break; + } + } + // Cut to the Chase + if (dummySpell->SpellIconID == 2909) + { + // "refresh your Slice and Dice duration to its 5 combo point maximum" + // lookup Slice and Dice + AuraList const& sd = GetAurasByType(SPELL_AURA_MOD_HASTE); + for(AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr) + { + SpellEntry const *spellProto = (*itr)->GetSpellProto(); + if (spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && + (spellProto->SpellFamilyFlags & UI64LIT(0x0000000000040000))) + (*itr)->GetHolder()->RefreshHolder(); + return true; + } + return false; + } + // Deadly Brew + if (dummySpell->SpellIconID == 2963) + { + triggered_spell_id = 44289; + break; + } + // Quick Recovery + if (dummySpell->SpellIconID == 2116) + { + if(!procSpell) + return false; + + // energy cost save + basepoints[0] = procSpell->manaCost * triggerAmount/100; + if (basepoints[0] <= 0) + return false; + + target = this; + triggered_spell_id = 31663; + break; + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Thrill of the Hunt + if (dummySpell->SpellIconID == 2236) + { + if (!procSpell) + return false; + + // mana cost save + int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; + basepoints[0] = mana * 40/100; + if (basepoints[0] <= 0) + return false; + + target = this; + triggered_spell_id = 34720; + break; + } + // Hunting Party + if (dummySpell->SpellIconID == 3406) + { + triggered_spell_id = 57669; + target = this; + break; + } + // Lock and Load + if ( dummySpell->SpellIconID == 3579 ) + { + // Proc only from periodic (from trap activation proc another aura of this spell) + if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC) || !roll_chance_i(triggerAmount)) + return false; + triggered_spell_id = 56453; + target = this; + break; + } + // Rapid Recuperation + if ( dummySpell->SpellIconID == 3560 ) + { + // This effect only from Rapid Killing (mana regen) + if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0100000000000000))) + return false; + + target = this; + + switch(dummySpell->Id) + { + case 53228: // Rank 1 + triggered_spell_id = 56654; + break; + case 53232: // Rank 2 + triggered_spell_id = 58882; + break; + } + break; + } + // Glyph of Mend Pet + if(dummySpell->Id == 57870) + { + pVictim->CastSpell(pVictim, 57894, true, NULL, NULL, GetGUID()); + return true; + } + break; + } + case SPELLFAMILY_PALADIN: + { + // Seal of Righteousness - melee proc dummy (addition ${$MWS*(0.022*$AP+0.044*$SPH)} damage) + if ((dummySpell->SpellFamilyFlags & UI64LIT(0x000000008000000)) && effIndex == EFFECT_INDEX_0) + { + triggered_spell_id = 25742; + float ap = GetTotalAttackPowerValue(BASE_ATTACK); + int32 holy = SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); + if (holy < 0) + holy = 0; + basepoints[0] = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000; + break; + } + // Righteous Vengeance + if (dummySpell->SpellIconID == 3025) + { + // 4 damage tick + basepoints[0] = triggerAmount*damage/400; + triggered_spell_id = 61840; + break; + } + // Sheath of Light + if (dummySpell->SpellIconID == 3030) + { + // 4 healing tick + basepoints[0] = triggerAmount*damage/400; + triggered_spell_id = 54203; + break; + } + switch(dummySpell->Id) + { + // Judgement of Light + case 20185: + { + basepoints[0] = int32( pVictim->GetMaxHealth() * triggeredByAura->GetModifier()->m_amount / 100 ); + pVictim->CastCustomSpell(pVictim, 20267, &basepoints[0], NULL, NULL, true, NULL, triggeredByAura); + return true; + } + // Judgement of Wisdom + case 20186: + { + if (pVictim->getPowerType() == POWER_MANA) + { + // 2% of maximum base mana + basepoints[0] = int32(pVictim->GetCreateMana() * 2 / 100); + pVictim->CastCustomSpell(pVictim, 20268, &basepoints[0], NULL, NULL, true, NULL, triggeredByAura); + } + return true; + } + // Heart of the Crusader (Rank 1) + case 20335: + triggered_spell_id = 21183; + break; + // Heart of the Crusader (Rank 2) + case 20336: + triggered_spell_id = 54498; + break; + // Heart of the Crusader (Rank 3) + case 20337: + triggered_spell_id = 54499; + break; + case 20911: // Blessing of Sanctuary + case 25899: // Greater Blessing of Sanctuary + { + target = this; + switch (target->getPowerType()) + { + case POWER_MANA: + triggered_spell_id = 57319; + break; + default: + return false; + } + break; + } + // Holy Power (Redemption Armor set) + case 28789: + { + if(!pVictim) + return false; + + // Set class defined buff + switch (pVictim->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + triggered_spell_id = 28795; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + triggered_spell_id = 28793; // Increases the friendly target's spell damage and healing by up to $s1 for $d. + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + triggered_spell_id = 28791; // Increases the friendly target's attack power by $s1 for $d. + break; + case CLASS_WARRIOR: + triggered_spell_id = 28790; // Increases the friendly target's armor + break; + default: + return false; + } + break; + } + // Spiritual Attunement + case 31785: + case 33776: + { + // if healed by another unit (pVictim) + if (this == pVictim) + return false; + + // heal amount + basepoints[0] = triggerAmount*damage/100; + target = this; + triggered_spell_id = 31786; + break; + } + // Seal of Vengeance (damage calc on apply aura) + case 31801: + { + if (effIndex != EFFECT_INDEX_0) // effect 1,2 used by seal unleashing code + return false; + + // At melee attack or Hammer of the Righteous spell damage considered as melee attack + if ((procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT) || (procSpell && procSpell->Id == 53595) ) + triggered_spell_id = 31803; // Holy Vengeance + + // Add 5-stack effect from Holy Vengeance + int8 stacks = 0; + AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + { + if( ((*itr)->GetId() == 31803) && (*itr)->GetCasterGUID()==GetGUID()) + { + stacks = (*itr)->GetStackAmount(); + break; + } + } + if(stacks >= 5) + CastSpell(target,42463,true,NULL,triggeredByAura); + break; + } + // Judgements of the Wise + case 31876: + case 31877: + case 31878: + // triggered only at casted Judgement spells, not at additional Judgement effects + if(!procSpell || procSpell->Category != 1210) + return false; + + target = this; + triggered_spell_id = 31930; + + // Replenishment + CastSpell(this, 57669, true, NULL, triggeredByAura); + break; + // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) + case 40470: + { + if (!procSpell) + return false; + + float chance; + + // Flash of light/Holy light + if (procSpell->SpellFamilyFlags & UI64LIT(0x00000000C0000000)) + { + triggered_spell_id = 40471; + chance = 15.0f; + } + // Judgement (any) + else if (GetSpellSpecific(procSpell->Id)==SPELL_JUDGEMENT) + { + triggered_spell_id = 40472; + chance = 50.0f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + break; + } + // Light's Beacon (heal target area aura) + case 53651: + { + // not do bonus heal for explicit beacon focus healing + if (GetGUID() == triggeredByAura->GetCasterGUID()) + return false; + + // beacon + Unit* beacon = triggeredByAura->GetCaster(); + if (!beacon) + return false; + + // find caster main aura at beacon + Aura* dummy = NULL; + Unit::AuraList const& baa = beacon->GetAurasByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL); + for(Unit::AuraList::const_iterator i = baa.begin(); i != baa.end(); ++i) + { + if ((*i)->GetId() == 53563 && (*i)->GetCasterGUID() == pVictim->GetGUID()) + { + dummy = (*i); + break; + } + } + + // original heal must be form beacon caster + if (!dummy) + return false; + + triggered_spell_id = 53652; // Beacon of Light + basepoints[0] = triggeredByAura->GetModifier()->m_amount*damage/100; + + // cast with original caster set but beacon to beacon for apply caster mods and avoid LoS check + beacon->CastCustomSpell(beacon,triggered_spell_id,&basepoints[0],NULL,NULL,true,castItem,triggeredByAura,pVictim->GetGUID()); + return true; + } + // Seal of Corruption (damage calc on apply aura) + case 53736: + { + if (effIndex != EFFECT_INDEX_0) // effect 1,2 used by seal unleashing code + return false; + + // At melee attack or Hammer of the Righteous spell damage considered as melee attack + if ((procFlag & PROC_FLAG_SUCCESSFUL_MELEE_HIT) || (procSpell && procSpell->Id == 53595)) + triggered_spell_id = 53742; // Blood Corruption + + // Add 5-stack effect from Blood Corruption + int8 stacks = 0; + AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + { + if( ((*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==GetGUID()) + { + stacks = (*itr)->GetStackAmount(); + break; + } + } + if(stacks >= 5) + CastSpell(target,53739,true,NULL,triggeredByAura); + break; + } + // Glyph of Holy Light + case 54937: + { + triggered_spell_id = 54968; + basepoints[0] = triggerAmount*damage/100; + break; + } + // Sacred Shield (buff) + case 58597: + { + triggered_spell_id = 66922; + SpellEntry const* triggeredEntry = sSpellStore.LookupEntry(triggered_spell_id); + if (!triggeredEntry) + return false; + + basepoints[0] = int32(damage / (GetSpellDuration(triggeredEntry) / triggeredEntry->EffectAmplitude[EFFECT_INDEX_0])); + target = this; + break; + } + // Sacred Shield (talent rank) + case 53601: + { + // triggered_spell_id in spell data + target = this; + break; + } + } + break; + } + case SPELLFAMILY_SHAMAN: + { + switch(dummySpell->Id) + { + // Totemic Power (The Earthshatterer set) + case 28823: + { + if( !pVictim ) + return false; + + // Set class defined buff + switch (pVictim->getClass()) + { + case CLASS_PALADIN: + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + triggered_spell_id = 28824; // Increases the friendly target's mana regeneration by $s1 per 5 sec. for $d. + break; + case CLASS_MAGE: + case CLASS_WARLOCK: + triggered_spell_id = 28825; // Increases the friendly target's spell damage and healing by up to $s1 for $d. + break; + case CLASS_HUNTER: + case CLASS_ROGUE: + triggered_spell_id = 28826; // Increases the friendly target's attack power by $s1 for $d. + break; + case CLASS_WARRIOR: + triggered_spell_id = 28827; // Increases the friendly target's armor + break; + default: + return false; + } + break; + } + // Lesser Healing Wave (Totem of Flowing Water Relic) + case 28849: + { + target = this; + triggered_spell_id = 28850; + break; + } + // Windfury Weapon (Passive) 1-5 Ranks + case 33757: + { + if(GetTypeId()!=TYPEID_PLAYER) + return false; + + if(!castItem || !castItem->IsEquipped()) + return false; + + // custom cooldown processing case + if( cooldown && ((Player*)this)->HasSpellCooldown(dummySpell->Id)) + return false; + + // Now amount of extra power stored in 1 effect of Enchant spell + // Get it by item enchant id + uint32 spellId; + switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT))) + { + case 283: spellId = 8232; break; // 1 Rank + case 284: spellId = 8235; break; // 2 Rank + case 525: spellId = 10486; break; // 3 Rank + case 1669:spellId = 16362; break; // 4 Rank + case 2636:spellId = 25505; break; // 5 Rank + case 3785:spellId = 58801; break; // 6 Rank + case 3786:spellId = 58803; break; // 7 Rank + case 3787:spellId = 58804; break; // 8 Rank + default: + { + sLog.outError("Unit::HandleDummyAuraProc: non handled item enchantment (rank?) %u for spell id: %u (Windfury)", + castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)),dummySpell->Id); + return false; + } + } + + SpellEntry const* windfurySpellEntry = sSpellStore.LookupEntry(spellId); + if(!windfurySpellEntry) + { + sLog.outError("Unit::HandleDummyAuraProc: non existed spell id: %u (Windfury)",spellId); + return false; + } + + int32 extra_attack_power = CalculateSpellDamage(pVictim, windfurySpellEntry, EFFECT_INDEX_1); + + // Off-Hand case + if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND) + { + // Value gained from additional AP + basepoints[0] = int32(extra_attack_power/14.0f * GetAttackTime(OFF_ATTACK)/1000/2); + triggered_spell_id = 33750; + } + // Main-Hand case + else + { + // Value gained from additional AP + basepoints[0] = int32(extra_attack_power/14.0f * GetAttackTime(BASE_ATTACK)/1000); + triggered_spell_id = 25504; + } + + // apply cooldown before cast to prevent processing itself + if( cooldown ) + ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); + + // Attack Twice + for ( uint32 i = 0; i<2; ++i ) + CastCustomSpell(pVictim,triggered_spell_id,&basepoints[0],NULL,NULL,true,castItem,triggeredByAura); + + return true; + } + // Shaman Tier 6 Trinket + case 40463: + { + if( !procSpell ) + return false; + + float chance; + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000001)) + { + triggered_spell_id = 40465; // Lightning Bolt + chance = 15.0f; + } + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) + { + triggered_spell_id = 40465; // Lesser Healing Wave + chance = 10.0f; + } + else if (procSpell->SpellFamilyFlags & UI64LIT(0x0000001000000000)) + { + triggered_spell_id = 40466; // Stormstrike + chance = 50.0f; + } + else + return false; + + if (!roll_chance_f(chance)) + return false; + + target = this; + break; + } + // Glyph of Healing Wave + case 55440: + { + // Not proc from self heals + if (this==pVictim) + return false; + basepoints[0] = triggerAmount * damage / 100; + target = this; + triggered_spell_id = 55533; + break; + } + // Spirit Hunt + case 58877: + { + // Cast on owner + target = GetOwner(); + if (!target) + return false; + basepoints[0] = triggerAmount * damage / 100; + triggered_spell_id = 58879; + break; + } + // Glyph of Totem of Wrath + case 63280: + { + Totem* totem = GetTotem(TOTEM_SLOT_FIRE); + if (!totem) + return false; + + // find totem aura bonus + AuraList const& spellPower = totem->GetAurasByType(SPELL_AURA_NONE); + for(AuraList::const_iterator i = spellPower.begin();i != spellPower.end(); ++i) + { + // select proper aura for format aura type in spell proto + if ((*i)->GetTarget()==totem && (*i)->GetSpellProto()->EffectApplyAuraName[(*i)->GetEffIndex()] == SPELL_AURA_MOD_HEALING_DONE && + (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (*i)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000004000000)) + { + basepoints[0] = triggerAmount * (*i)->GetModifier()->m_amount / 100; + break; + } + } + + if (!basepoints[0]) + return false; + + basepoints[1] = basepoints[0]; + triggered_spell_id = 63283; // Totem of Wrath, caster bonus + target = this; + break; + } + // Shaman T8 Elemental 4P Bonus + case 64928: + { + basepoints[0] = int32( triggerAmount * damage / 100 ); + triggered_spell_id = 64930; // Electrified + break; + } + // Shaman T9 Elemental 4P Bonus + case 67228: + { + basepoints[0] = int32( triggerAmount * damage / 100 ); + triggered_spell_id = 71824; + break; + } + } + // Storm, Earth and Fire + if (dummySpell->SpellIconID == 3063) + { + // Earthbind Totem summon only + if(procSpell->Id != 2484) + return false; + + if (!roll_chance_i(triggerAmount)) + return false; + + triggered_spell_id = 64695; + break; + } + // Ancestral Awakening + if (dummySpell->SpellIconID == 3065) + { + triggered_spell_id = 52759; + basepoints[0] = triggerAmount * damage / 100; + target = this; + break; + } + // Earth Shield + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + { + target = this; + basepoints[0] = triggerAmount; + + // Glyph of Earth Shield + if (Aura* aur = GetDummyAura(63279)) + { + int32 aur_mod = aur->GetModifier()->m_amount; + basepoints[0] = int32(basepoints[0] * (aur_mod + 100.0f) / 100.0f); + } + + triggered_spell_id = 379; + break; + } + // Improved Water Shield + if (dummySpell->SpellIconID == 2287) + { + // Lesser Healing Wave need aditional 60% roll + if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080)) && !roll_chance_i(60)) + return false; + // Chain Heal needs additional 30% roll + if ((procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000100)) && !roll_chance_i(30)) + return false; + // lookup water shield + AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); + for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) + { + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000002000000000))) + { + uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; + CastSpell(this, spell, true, castItem, triggeredByAura); + return true; + } + } + return false; + } + // Lightning Overload + if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura + { + if(!procSpell || GetTypeId() != TYPEID_PLAYER || !pVictim ) + return false; + + // custom cooldown processing case + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(dummySpell->Id)) + return false; + + uint32 spellId = 0; + // Every Lightning Bolt and Chain Lightning spell have duplicate vs half damage and zero cost + switch (procSpell->Id) + { + // Lightning Bolt + case 403: spellId = 45284; break; // Rank 1 + case 529: spellId = 45286; break; // Rank 2 + case 548: spellId = 45287; break; // Rank 3 + case 915: spellId = 45288; break; // Rank 4 + case 943: spellId = 45289; break; // Rank 5 + case 6041: spellId = 45290; break; // Rank 6 + case 10391: spellId = 45291; break; // Rank 7 + case 10392: spellId = 45292; break; // Rank 8 + case 15207: spellId = 45293; break; // Rank 9 + case 15208: spellId = 45294; break; // Rank 10 + case 25448: spellId = 45295; break; // Rank 11 + case 25449: spellId = 45296; break; // Rank 12 + case 49237: spellId = 49239; break; // Rank 13 + case 49238: spellId = 49240; break; // Rank 14 + // Chain Lightning + case 421: spellId = 45297; break; // Rank 1 + case 930: spellId = 45298; break; // Rank 2 + case 2860: spellId = 45299; break; // Rank 3 + case 10605: spellId = 45300; break; // Rank 4 + case 25439: spellId = 45301; break; // Rank 5 + case 25442: spellId = 45302; break; // Rank 6 + case 49270: spellId = 49268; break; // Rank 7 + case 49271: spellId = 49269; break; // Rank 8 + default: + sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id); + return false; + } + // No thread generated mod + // TODO: exist special flag in spell attributes for this, need found and use! + SpellModifier *mod = new SpellModifier(SPELLMOD_THREAT,SPELLMOD_PCT,-100,triggeredByAura); + + ((Player*)this)->AddSpellMod(mod, true); + + // Remove cooldown (Chain Lightning - have Category Recovery time) + if (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000002)) + ((Player*)this)->RemoveSpellCooldown(spellId); + + CastSpell(pVictim, spellId, true, castItem, triggeredByAura); + + ((Player*)this)->AddSpellMod(mod, false); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); + + return true; + } + // Static Shock + if(dummySpell->SpellIconID == 3059) + { + // lookup Lightning Shield + AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); + for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) + { + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + ((*itr)->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000400))) + { + uint32 spell = 0; + switch ((*itr)->GetId()) + { + case 324: spell = 26364; break; + case 325: spell = 26365; break; + case 905: spell = 26366; break; + case 945: spell = 26367; break; + case 8134: spell = 26369; break; + case 10431: spell = 26370; break; + case 10432: spell = 26363; break; + case 25469: spell = 26371; break; + case 25472: spell = 26372; break; + case 49280: spell = 49278; break; + case 49281: spell = 49279; break; + default: + return false; + } + CastSpell(target, spell, true, castItem, triggeredByAura); + if ((*itr)->GetHolder()->DropAuraCharge()) + RemoveSingleAuraHolderFromStack((*itr)->GetId()); + return true; + } + } + return false; + } + // Frozen Power + if (dummySpell->SpellIconID == 3780) + { + Unit *caster = triggeredByAura->GetCaster(); + + if (!procSpell || !caster) + return false; + + float distance = caster->GetDistance(pVictim); + int32 chance = triggerAmount; + + if (distance < 15.0f || !roll_chance_i(chance)) + return false; + + // make triggered cast apply after current damage spell processing for prevent remove by it + if(Spell* spell = GetCurrentSpell(CURRENT_GENERIC_SPELL)) + spell->AddTriggeredSpell(63685); + return true; + } + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Butchery + if (dummySpell->SpellIconID == 2664) + { + basepoints[0] = triggerAmount; + triggered_spell_id = 50163; + target = this; + break; + } + // Dancing Rune Weapon + if (dummySpell->Id == 49028) + { + // 1 dummy aura for dismiss rune blade + if (effIndex != EFFECT_INDEX_2) + return false; + // TODO: wite script for this "fights on its own, doing the same attacks" + // NOTE: Trigger here on every attack and spell cast + return false; + } + // Mark of Blood + if (dummySpell->Id == 49005) + { + // TODO: need more info (cooldowns/PPM) + triggered_spell_id = 61607; + break; + } + // Vendetta + if (dummySpell->SpellFamilyFlags & UI64LIT(0x0000000000010000)) + { + basepoints[0] = triggerAmount * GetMaxHealth() / 100; + triggered_spell_id = 50181; + target = this; + break; + } + // Necrosis + if (dummySpell->SpellIconID == 2709) + { + // only melee auto attack affected and Rune Strike + if (procSpell && procSpell->Id != 56815) + return false; + + basepoints[0] = triggerAmount * damage / 100; + triggered_spell_id = 51460; + break; + } + // Threat of Thassarian + if (dummySpell->SpellIconID == 2023) + { + // Must Dual Wield + if (!procSpell || !haveOffhandWeapon()) + return false; + // Chance as basepoints for dummy aura + if (!roll_chance_i(triggerAmount)) + return false; + + switch (procSpell->Id) + { + // Obliterate + case 49020: // Rank 1 + triggered_spell_id = 66198; break; + case 51423: // Rank 2 + triggered_spell_id = 66972; break; + case 51424: // Rank 3 + triggered_spell_id = 66973; break; + case 51425: // Rank 4 + triggered_spell_id = 66974; break; + // Frost Strike + case 49143: // Rank 1 + triggered_spell_id = 66196; break; + case 51416: // Rank 2 + triggered_spell_id = 66958; break; + case 51417: // Rank 3 + triggered_spell_id = 66959; break; + case 51418: // Rank 4 + triggered_spell_id = 66960; break; + case 51419: // Rank 5 + triggered_spell_id = 66961; break; + case 55268: // Rank 6 + triggered_spell_id = 66962; break; + // Plague Strike + case 45462: // Rank 1 + triggered_spell_id = 66216; break; + case 49917: // Rank 2 + triggered_spell_id = 66988; break; + case 49918: // Rank 3 + triggered_spell_id = 66989; break; + case 49919: // Rank 4 + triggered_spell_id = 66990; break; + case 49920: // Rank 5 + triggered_spell_id = 66991; break; + case 49921: // Rank 6 + triggered_spell_id = 66992; break; + // Death Strike + case 49998: // Rank 1 + triggered_spell_id = 66188; break; + case 49999: // Rank 2 + triggered_spell_id = 66950; break; + case 45463: // Rank 3 + triggered_spell_id = 66951; break; + case 49923: // Rank 4 + triggered_spell_id = 66952; break; + case 49924: // Rank 5 + triggered_spell_id = 66953; break; + // Rune Strike + case 56815: + triggered_spell_id = 66217; break; + // Blood Strike + case 45902: // Rank 1 + triggered_spell_id = 66215; break; + case 49926: // Rank 2 + triggered_spell_id = 66975; break; + case 49927: // Rank 3 + triggered_spell_id = 66976; break; + case 49928: // Rank 4 + triggered_spell_id = 66977; break; + case 49929: // Rank 5 + triggered_spell_id = 66978; break; + case 49930: // Rank 6 + triggered_spell_id = 66979; break; + default: + return false; + } + break; + } + // Runic Power Back on Snare/Root + if (dummySpell->Id == 61257) + { + // only for spells and hit/crit (trigger start always) and not start from self casted spells + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) + return false; + // Need snare or root mechanic + if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_ROOT_AND_SNARE_MASK)) + return false; + triggered_spell_id = 61258; + target = this; + break; + } + // Wandering Plague + if (dummySpell->SpellIconID == 1614) + { + if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim))) + return false; + basepoints[0] = triggerAmount * damage / 100; + triggered_spell_id = 50526; + break; + } + // Blood-Caked Blade + if (dummySpell->SpellIconID == 138) + { + // only main hand melee auto attack affected and Rune Strike + if ((procFlag & PROC_FLAG_SUCCESSFUL_OFFHAND_HIT) || procSpell && procSpell->Id != 56815) + return false; + + // triggered_spell_id in spell data + break; + } + break; + } + default: + break; + } + + // processed charge only counting case + if(!triggered_spell_id) + return true; + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleDummyAuraProc: Spell %u have not existed triggered spell %u",dummySpell->Id,triggered_spell_id); + return false; + } + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + if (basepoints[EFFECT_INDEX_0] || basepoints[EFFECT_INDEX_1] || basepoints[EFFECT_INDEX_2]) + CastCustomSpell(target, triggered_spell_id, + basepoints[EFFECT_INDEX_0] ? &basepoints[EFFECT_INDEX_0] : NULL, + basepoints[EFFECT_INDEX_1] ? &basepoints[EFFECT_INDEX_1] : NULL, + basepoints[EFFECT_INDEX_2] ? &basepoints[EFFECT_INDEX_2] : NULL, + true, castItem, triggeredByAura); + else + CastSpell(target, triggered_spell_id, true, castItem, triggeredByAura); + + if (cooldown && GetTypeId()==TYPEID_PLAYER) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleProcTriggerSpellAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown) +{ + // Get triggered aura spell info + SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto(); + + // Basepoints of trigger aura + int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; + + // Set trigger spell id, target, custom basepoints + uint32 trigger_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; + Unit* target = NULL; + int32 basepoints[MAX_EFFECT_INDEX] = {0, 0, 0}; + + if(triggeredByAura->GetModifier()->m_auraname == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE) + basepoints[0] = triggerAmount; + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + // Try handle unknown trigger spells + // Custom requirements (not listed in procEx) Warning! damage dealing after this + // Custom triggered spells + switch (auraSpellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + switch(auraSpellInfo->Id) + { + //case 191: // Elemental Response + // switch (procSpell->School) + // { + // case SPELL_SCHOOL_FIRE: trigger_spell_id = 34192; break; + // case SPELL_SCHOOL_FROST: trigger_spell_id = 34193; break; + // case SPELL_SCHOOL_ARCANE:trigger_spell_id = 34194; break; + // case SPELL_SCHOOL_NATURE:trigger_spell_id = 34195; break; + // case SPELL_SCHOOL_SHADOW:trigger_spell_id = 34196; break; + // case SPELL_SCHOOL_HOLY: trigger_spell_id = 34197; break; + // case SPELL_SCHOOL_NORMAL:trigger_spell_id = 34198; break; + // } + // break; + //case 5301: break; // Defensive State (DND) + //case 7137: break: // Shadow Charge (Rank 1) + //case 7377: break: // Take Immune Periodic Damage + //case 13358: break; // Defensive State (DND) + //case 16092: break; // Defensive State (DND) + //case 18943: break; // Double Attack + //case 19194: break; // Double Attack + //case 19817: break; // Double Attack + //case 19818: break; // Double Attack + //case 22835: break; // Drunken Rage + // trigger_spell_id = 14822; break; + case 23780: // Aegis of Preservation (Aegis of Preservation trinket) + trigger_spell_id = 23781; + break; + //case 24949: break; // Defensive State 2 (DND) + case 27522: // Mana Drain Trigger + case 40336: // Mana Drain Trigger + // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target. + if (isAlive()) + CastSpell(this, 29471, true, castItem, triggeredByAura); + if (pVictim && pVictim->isAlive()) + CastSpell(pVictim, 27526, true, castItem, triggeredByAura); + return true; + case 31255: // Deadly Swiftness (Rank 1) + // whenever you deal damage to a target who is below 20% health. + if (pVictim->GetHealth() > pVictim->GetMaxHealth() / 5) + return false; + + target = this; + trigger_spell_id = 22588; + break; + //case 33207: break; // Gossip NPC Periodic - Fidget + case 33896: // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher) + trigger_spell_id = 33898; + break; + //case 34082: break; // Advantaged State (DND) + //case 34783: break: // Spell Reflection + //case 35205: break: // Vanish + //case 35321: break; // Gushing Wound + //case 36096: break: // Spell Reflection + //case 36207: break: // Steal Weapon + //case 36576: break: // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger + //case 37030: break; // Chaotic Temperament + //case 38363: break; // Gushing Wound + //case 39215: break; // Gushing Wound + //case 40250: break; // Improved Duration + //case 40329: break; // Demo Shout Sensor + //case 40364: break; // Entangling Roots Sensor + //case 41054: break; // Copy Weapon + // trigger_spell_id = 41055; break; + //case 41248: break; // Consuming Strikes + // trigger_spell_id = 41249; break; + //case 42730: break: // Woe Strike + //case 43453: break: // Rune Ward + //case 43504: break; // Alterac Valley OnKill Proc Aura + //case 44326: break: // Pure Energy Passive + //case 44526: break; // Hate Monster (Spar) (30 sec) + //case 44527: break; // Hate Monster (Spar Buddy) (30 sec) + //case 44819: break; // Hate Monster (Spar Buddy) (>30% Health) + //case 44820: break; // Hate Monster (Spar) (<30%) + case 45057: // Evasive Maneuvers (Commendation of Kael`thas trinket) + // reduce you below $s1% health + if (GetHealth() - damage > GetMaxHealth() * triggerAmount / 100) + return false; + break; + //case 45903: break: // Offensive State + //case 46146: break: // [PH] Ahune Spanky Hands + //case 46939: break; // Black Bow of the Betrayer + // trigger_spell_id = 29471; - gain mana + // 27526; - drain mana if possible + case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket) + // Pct value stored in dummy + basepoints[0] = pVictim->GetCreateHealth() * auraSpellInfo->CalculateSimpleValue(EFFECT_INDEX_1) / 100; + target = pVictim; + break; + //case 45205: break; // Copy Offhand Weapon + //case 45343: break; // Dark Flame Aura + //case 47300: break; // Dark Flame Aura + //case 48876: break; // Beast's Mark + // trigger_spell_id = 48877; break; + //case 49059: break; // Horde, Hate Monster (Spar Buddy) (>30% Health) + //case 50051: break; // Ethereal Pet Aura + //case 50689: break; // Blood Presence (Rank 1) + //case 50844: break; // Blood Mirror + //case 52856: break; // Charge + //case 54072: break; // Knockback Ball Passive + //case 54476: break; // Blood Presence + //case 54775: break; // Abandon Vehicle on Poly + case 57345: // Darkmoon Card: Greatness + { + float stat = 0.0f; + // strength + if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 60229;stat = GetStat(STAT_STRENGTH); } + // agility + if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 60233;stat = GetStat(STAT_AGILITY); } + // intellect + if (GetStat(STAT_INTELLECT)> stat) { trigger_spell_id = 60234;stat = GetStat(STAT_INTELLECT);} + // spirit + if (GetStat(STAT_SPIRIT) > stat) { trigger_spell_id = 60235; } + break; + } + //case 55580: break: // Mana Link + //case 57587: break: // Steal Ranged () + //case 57594: break; // Copy Ranged Weapon + //case 59237: break; // Beast's Mark + // trigger_spell_id = 59233; break; + //case 59288: break; // Infra-Green Shield + //case 59532: break; // Abandon Passengers on Poly + //case 59735: break: // Woe Strike + case 64415: // // Val'anyr Hammer of Ancient Kings - Equip Effect + { + // for DOT procs + if (!IsPositiveSpell(procSpell->Id)) + return false; + break; + } + case 67702: // Death's Choice, Item - Coliseum 25 Normal Melee Trinket + { + float stat = 0.0f; + // strength + if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67708;stat = GetStat(STAT_STRENGTH); } + // agility + if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67703; } + break; + } + case 67771: // Death's Choice (heroic), Item - Coliseum 25 Heroic Melee Trinket + { + float stat = 0.0f; + // strength + if (GetStat(STAT_STRENGTH) > stat) { trigger_spell_id = 67773;stat = GetStat(STAT_STRENGTH); } + // agility + if (GetStat(STAT_AGILITY) > stat) { trigger_spell_id = 67772; } + break; + } + } + break; + case SPELLFAMILY_MAGE: + if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed + { + switch (auraSpellInfo->Id) + { + case 31641: // Rank 1 + case 31642: // Rank 2 + trigger_spell_id = 31643; + break; + default: + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u miss posibly Blazing Speed",auraSpellInfo->Id); + return false; + } + } + // Persistent Shield (Scarab Brooch trinket) + else if(auraSpellInfo->Id == 26467) + { + // This spell originally trigger 13567 - Dummy Trigger (vs dummy efect) + basepoints[0] = damage * 15 / 100; + target = pVictim; + trigger_spell_id = 26470; + } + break; + case SPELLFAMILY_WARRIOR: + // Deep Wounds (replace triggered spells to directly apply DoT), dot spell have finilyflags + if (auraSpellInfo->SpellFamilyFlags == UI64LIT(0x0) && auraSpellInfo->SpellIconID == 243) + { + float weaponDamage; + // DW should benefit of attack power, damage percent mods etc. + // TODO: check if using offhand damage is correct and if it should be divided by 2 + if (haveOffhandWeapon() && getAttackTimer(BASE_ATTACK) > getAttackTimer(OFF_ATTACK)) + weaponDamage = (GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE) + GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE))/2; + else + weaponDamage = (GetFloatValue(UNIT_FIELD_MINDAMAGE) + GetFloatValue(UNIT_FIELD_MAXDAMAGE))/2; + + switch (auraSpellInfo->Id) + { + case 12834: basepoints[0] = int32(weaponDamage * 16 / 100); break; + case 12849: basepoints[0] = int32(weaponDamage * 32 / 100); break; + case 12867: basepoints[0] = int32(weaponDamage * 48 / 100); break; + // Impossible case + default: + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: DW unknown spell rank %u",auraSpellInfo->Id); + return false; + } + + // 1 tick/sec * 6 sec = 6 ticks + basepoints[0] /= 6; + + trigger_spell_id = 12721; + break; + } + if (auraSpellInfo->Id == 50421) // Scent of Blood + trigger_spell_id = 50422; + break; + case SPELLFAMILY_WARLOCK: + { + // Drain Soul + if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000004000)) + { + // search for "Improved Drain Soul" dummy aura + Unit::AuraList const& mDummyAura = GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummyAura.begin(); i != mDummyAura.end(); ++i) + { + if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*i)->GetSpellProto()->SpellIconID == 113) + { + // basepoints of trigger spell stored in dummyeffect of spellProto + int32 basepoints = GetMaxPower(POWER_MANA) * (*i)->GetSpellProto()->CalculateSimpleValue(EFFECT_INDEX_2) / 100; + CastCustomSpell(this, 18371, &basepoints, NULL, NULL, true, castItem, triggeredByAura); + break; + } + } + // Not remove charge (aura removed on death in any cases) + // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura + return false; + } + // Nether Protection + else if (auraSpellInfo->SpellIconID == 1985) + { + if (!procSpell) + return false; + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + case SPELL_SCHOOL_NORMAL: + return false; // ignore + case SPELL_SCHOOL_HOLY: trigger_spell_id = 54370; break; + case SPELL_SCHOOL_FIRE: trigger_spell_id = 54371; break; + case SPELL_SCHOOL_NATURE: trigger_spell_id = 54375; break; + case SPELL_SCHOOL_FROST: trigger_spell_id = 54372; break; + case SPELL_SCHOOL_SHADOW: trigger_spell_id = 54374; break; + case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break; + default: + return false; + } + } + // Cheat Death + else if (auraSpellInfo->Id == 28845) + { + // When your health drops below 20% .... + if (GetHealth() - damage > GetMaxHealth() / 5 || GetHealth() < GetMaxHealth() / 5) + return false; + } + // Decimation + else if (auraSpellInfo->Id == 63156 || auraSpellInfo->Id == 63158) + { + // Looking for dummy effect + Aura *aur = GetAura(auraSpellInfo->Id, EFFECT_INDEX_1); + if (!aur) + return false; + + // If target's health is not below equal certain value (35%) not proc + if (int32(pVictim->GetHealth() * 100 / pVictim->GetMaxHealth()) > aur->GetModifier()->m_amount) + return false; + } + break; + } + case SPELLFAMILY_PRIEST: + { + // Greater Heal Refund (Avatar Raiment set) + if (auraSpellInfo->Id==37594) + { + // Not give if target already have full health + if (pVictim->GetHealth() == pVictim->GetMaxHealth()) + return false; + // If your Greater Heal brings the target to full health, you gain $37595s1 mana. + if (pVictim->GetHealth() + damage < pVictim->GetMaxHealth()) + return false; + trigger_spell_id = 37595; + } + // Blessed Recovery + else if (auraSpellInfo->SpellIconID == 1875) + { + switch (auraSpellInfo->Id) + { + case 27811: trigger_spell_id = 27813; break; + case 27815: trigger_spell_id = 27817; break; + case 27816: trigger_spell_id = 27818; break; + default: + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u not handled in BR", auraSpellInfo->Id); + return false; + } + basepoints[0] = damage * triggerAmount / 100 / 3; + target = this; + } + break; + } + case SPELLFAMILY_DRUID: + { + // Druid Forms Trinket + if (auraSpellInfo->Id==37336) + { + switch(m_form) + { + case FORM_NONE: trigger_spell_id = 37344;break; + case FORM_CAT: trigger_spell_id = 37341;break; + case FORM_BEAR: + case FORM_DIREBEAR: trigger_spell_id = 37340;break; + case FORM_TREE: trigger_spell_id = 37342;break; + case FORM_MOONKIN: trigger_spell_id = 37343;break; + default: + return false; + } + } + // Druid T9 Feral Relic (Lacerate, Swipe, Mangle, and Shred) + else if (auraSpellInfo->Id==67353) + { + switch(m_form) + { + case FORM_CAT: trigger_spell_id = 67355; break; + case FORM_BEAR: + case FORM_DIREBEAR: trigger_spell_id = 67354; break; + default: + return false; + } + } + break; + } + case SPELLFAMILY_HUNTER: + // Piercing Shots + if (auraSpellInfo->SpellIconID == 3247 && auraSpellInfo->SpellVisual[0] == 0) + { + basepoints[0] = damage * triggerAmount / 100 / 8; + trigger_spell_id = 63468; + target = pVictim; + } + // Rapid Recuperation + else if (auraSpellInfo->Id == 53228 || auraSpellInfo->Id == 53232) + { + // This effect only from Rapid Fire (ability cast) + if (!(procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000020))) + return false; + } + break; + case SPELLFAMILY_PALADIN: + { + /* + // Blessed Life + if (auraSpellInfo->SpellIconID == 2137) + { + switch (auraSpellInfo->Id) + { + case 31828: // Rank 1 + case 31829: // Rank 2 + case 31830: // Rank 3 + break; + default: + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u miss posibly Blessed Life", auraSpellInfo->Id); + return false; + } + } + */ + // Healing Discount + if (auraSpellInfo->Id==37705) + { + trigger_spell_id = 37706; + target = this; + } + // Soul Preserver + if (auraSpellInfo->Id==60510) + { + trigger_spell_id = 60515; + target = this; + } + // Illumination + else if (auraSpellInfo->SpellIconID==241) + { + if(!procSpell) + return false; + // procspell is triggered spell but we need mana cost of original casted spell + uint32 originalSpellId = procSpell->Id; + // Holy Shock heal + if (procSpell->SpellFamilyFlags & UI64LIT(0x0001000000000000)) + { + switch(procSpell->Id) + { + case 25914: originalSpellId = 20473; break; + case 25913: originalSpellId = 20929; break; + case 25903: originalSpellId = 20930; break; + case 27175: originalSpellId = 27174; break; + case 33074: originalSpellId = 33072; break; + case 48820: originalSpellId = 48824; break; + case 48821: originalSpellId = 48825; break; + default: + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u not handled in HShock",procSpell->Id); + return false; + } + } + SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); + if(!originalSpell) + { + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u unknown but selected as original in Illu",originalSpellId); + return false; + } + // percent stored in effect 1 (class scripts) base points + int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100; + basepoints[0] = cost*auraSpellInfo->CalculateSimpleValue(EFFECT_INDEX_1)/100; + trigger_spell_id = 20272; + target = this; + } + // Lightning Capacitor + else if (auraSpellInfo->Id==37657) + { + if(!pVictim || !pVictim->isAlive()) + return false; + // stacking + CastSpell(this, 37658, true, NULL, triggeredByAura); + + Aura * dummy = GetDummyAura(37658); + // release at 3 aura in stack (cont contain in basepoint of trigger aura) + if(!dummy || dummy->GetStackAmount() < triggerAmount) + return false; + + RemoveAurasDueToSpell(37658); + trigger_spell_id = 37661; + target = pVictim; + } + // Bonus Healing (Crystal Spire of Karabor mace) + else if (auraSpellInfo->Id == 40971) + { + // If your target is below $s1% health + if (pVictim->GetHealth() > pVictim->GetMaxHealth() * triggerAmount / 100) + return false; + } + // Thunder Capacitor + else if (auraSpellInfo->Id == 54841) + { + if(!pVictim || !pVictim->isAlive()) + return false; + // stacking + CastSpell(this, 54842, true, NULL, triggeredByAura); + + // counting + Aura * dummy = GetDummyAura(54842); + // release at 3 aura in stack (cont contain in basepoint of trigger aura) + if(!dummy || dummy->GetStackAmount() < triggerAmount) + return false; + + RemoveAurasDueToSpell(54842); + trigger_spell_id = 54843; + target = pVictim; + } + break; + } + case SPELLFAMILY_SHAMAN: + { + // Lightning Shield (overwrite non existing triggered spell call in spell.dbc + if (auraSpellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000400)) + { + switch(auraSpellInfo->Id) + { + case 324: // Rank 1 + trigger_spell_id = 26364; break; + case 325: // Rank 2 + trigger_spell_id = 26365; break; + case 905: // Rank 3 + trigger_spell_id = 26366; break; + case 945: // Rank 4 + trigger_spell_id = 26367; break; + case 8134: // Rank 5 + trigger_spell_id = 26369; break; + case 10431: // Rank 6 + trigger_spell_id = 26370; break; + case 10432: // Rank 7 + trigger_spell_id = 26363; break; + case 25469: // Rank 8 + trigger_spell_id = 26371; break; + case 25472: // Rank 9 + trigger_spell_id = 26372; break; + case 49280: // Rank 10 + trigger_spell_id = 49278; break; + case 49281: // Rank 11 + trigger_spell_id = 49279; break; + default: + sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u not handled in LShield", auraSpellInfo->Id); + return false; + } + } + // Lightning Shield (The Ten Storms set) + else if (auraSpellInfo->Id == 23551) + { + trigger_spell_id = 23552; + target = pVictim; + } + // Damage from Lightning Shield (The Ten Storms set) + else if (auraSpellInfo->Id == 23552) + trigger_spell_id = 27635; + // Mana Surge (The Earthfury set) + else if (auraSpellInfo->Id == 23572) + { + if(!procSpell) + return false; + basepoints[0] = procSpell->manaCost * 35 / 100; + trigger_spell_id = 23571; + target = this; + } + // Nature's Guardian + else if (auraSpellInfo->SpellIconID == 2013) + { + // Check health condition - should drop to less 30% (damage deal after this!) + if (!(10*(int32(GetHealth() - damage)) < int32(3 * GetMaxHealth()))) + return false; + + if(pVictim && pVictim->isAlive()) + pVictim->getThreatManager().modifyThreatPercent(this,-10); + + basepoints[0] = triggerAmount * GetMaxHealth() / 100; + trigger_spell_id = 31616; + target = this; + } + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Acclimation + if (auraSpellInfo->SpellIconID == 1930) + { + if (!procSpell) + return false; + switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) + { + case SPELL_SCHOOL_NORMAL: + return false; // ignore + case SPELL_SCHOOL_HOLY: trigger_spell_id = 50490; break; + case SPELL_SCHOOL_FIRE: trigger_spell_id = 50362; break; + case SPELL_SCHOOL_NATURE: trigger_spell_id = 50488; break; + case SPELL_SCHOOL_FROST: trigger_spell_id = 50485; break; + case SPELL_SCHOOL_SHADOW: trigger_spell_id = 50489; break; + case SPELL_SCHOOL_ARCANE: trigger_spell_id = 50486; break; + default: + return false; + } + } + // Blade Barrier + else if (auraSpellInfo->SpellIconID == 85) + { + if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT || + !((Player*)this)->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD)) + return false; + } + // Improved Blood Presence + else if (auraSpellInfo->Id == 63611) + { + if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim) || !damage) + return false; + basepoints[0] = triggerAmount * damage / 100; + trigger_spell_id = 50475; + } + break; + } + default: + break; + } + + // All ok. Check current trigger spell + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(trigger_spell_id); + if (!triggerEntry) + { + // Not cast unknown spell + // sLog.outError("Unit::HandleProcTriggerSpellAuraProc: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex()); + return false; + } + + // not allow proc extra attack spell at extra attack + if (m_extraAttacks && IsSpellHaveEffect(triggerEntry, SPELL_EFFECT_ADD_EXTRA_ATTACKS)) + return false; + + // Custom basepoints/target for exist spell + // dummy basepoints or other customs + switch(trigger_spell_id) + { + // Cast positive spell on enemy target + case 7099: // Curse of Mending + case 39647: // Curse of Mending + case 29494: // Temptation + case 20233: // Improved Lay on Hands (cast on target) + { + target = pVictim; + break; + } + // Combo points add triggers (need add combopoint only for main target, and after possible combopoints reset) + case 15250: // Rogue Setup + { + if(!pVictim || pVictim != getVictim()) // applied only for main target + return false; + break; // continue normal case + } + // Finish movies that add combo + case 14189: // Seal Fate (Netherblade set) + case 14157: // Ruthlessness + { + // Need add combopoint AFTER finish movie (or they dropped in finish phase) + break; + } + // Bloodthirst (($m/100)% of max health) + case 23880: + { + basepoints[0] = int32(GetMaxHealth() * triggerAmount / 100); + break; + } + // Shamanistic Rage triggered spell + case 30824: + { + basepoints[0] = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100); + break; + } + // Enlightenment (trigger only from mana cost spells) + case 35095: + { + if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0) + return false; + break; + } + // Demonic Pact + case 48090: + { + // As the spell is proced from pet's attack - find owner + Unit* owner = GetOwner(); + if (!owner || owner->GetTypeId() != TYPEID_PLAYER) + return false; + + // This spell doesn't stack, but refreshes duration. So we receive current bonuses to minus them later. + int32 curBonus = 0; + if (Aura* aur = owner->GetAura(48090, EFFECT_INDEX_0)) + curBonus = aur->GetModifier()->m_amount; + int32 spellDamage = owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_MAGIC) - curBonus; + if(spellDamage <= 0) + return false; + + // percent stored in owner talent dummy + AuraList const& dummyAuras = owner->GetAurasByType(SPELL_AURA_DUMMY); + for (AuraList::const_iterator i = dummyAuras.begin(); i != dummyAuras.end(); ++i) + { + if ((*i)->GetSpellProto()->SpellIconID == 3220) + { + basepoints[0] = basepoints[1] = int32(spellDamage * (*i)->GetModifier()->m_amount / 100); + break; + } + } + break; + } + // Sword and Board + case 50227: + { + // Remove cooldown on Shield Slam + if (GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->RemoveSpellCategoryCooldown(1209, true); + break; + } + // Maelstrom Weapon + case 53817: + { + // have rank dependent proc chance, ignore too often cases + // PPM = 2.5 * (rank of talent), + uint32 rank = sSpellMgr.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 + case 57761: + { + if(!procSpell) + return false; + // For trigger from Blizzard need exist Improved Blizzard + if (procSpell->SpellFamilyName==SPELLFAMILY_MAGE && (procSpell->SpellFamilyFlags & UI64LIT(0x0000000000000080))) + { + bool found = false; + AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + { + int32 script = (*i)->GetModifier()->m_miscvalue; + if(script==836 || script==988 || script==989) + { + found=true; + break; + } + } + if(!found) + return false; + } + break; + } + // Astral Shift + case 52179: + { + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) + return false; + + // Need stun, fear or silence mechanic + if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_SILENCE_AND_STUN_AND_FEAR_MASK)) + return false; + break; + } + // Burning Determination + case 54748: + { + if(!procSpell) + return false; + // Need Interrupt or Silenced mechanic + if (!(GetAllSpellMechanicMask(procSpell) & IMMUNE_TO_INTERRUPT_AND_SILENCE_MASK)) + return false; + break; + } + // Lock and Load + case 56453: + { + // Proc only from trap activation (from periodic proc another aura of this spell) + if (!(procFlags & PROC_FLAG_ON_TRAP_ACTIVATION) || !roll_chance_i(triggerAmount)) + return false; + break; + } + // Freezing Fog (Rime triggered) + case 59052: + { + // Howling Blast cooldown reset + if (GetTypeId() == TYPEID_PLAYER) + ((Player*)this)->RemoveSpellCategoryCooldown(1248, true); + break; + } + // Druid - Savage Defense + case 62606: + { + basepoints[0] = int32(GetTotalAttackPowerValue(BASE_ATTACK) * triggerAmount / 100); + break; + } + } + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(trigger_spell_id)) + return false; + + // try detect target manually if not set + if (target == NULL) + target = !(procFlags & PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL) && IsPositiveSpell(trigger_spell_id) ? this : pVictim; + + // default case + if (!target || target!=this && !target->isAlive()) + return false; + + if (basepoints[EFFECT_INDEX_0] || basepoints[EFFECT_INDEX_1] || basepoints[EFFECT_INDEX_2]) + CastCustomSpell(target,trigger_spell_id, + basepoints[EFFECT_INDEX_0] ? &basepoints[EFFECT_INDEX_0] : NULL, + basepoints[EFFECT_INDEX_1] ? &basepoints[EFFECT_INDEX_1] : NULL, + basepoints[EFFECT_INDEX_2] ? &basepoints[EFFECT_INDEX_2] : NULL, + true, castItem, triggeredByAura); + else + CastSpell(target,trigger_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(trigger_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleProcTriggerDamageAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown) +{ + SpellEntry const *spellInfo = triggeredByAura->GetSpellProto(); + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetModifier()->m_amount, spellInfo->Id, triggeredByAura->GetId()); + SpellNonMeleeDamage damageInfo(this, pVictim, spellInfo->Id, SpellSchoolMask(spellInfo->SchoolMask)); + CalculateSpellDamage(&damageInfo, triggeredByAura->GetModifier()->m_amount, spellInfo); + damageInfo.target->CalculateAbsorbResistBlock(this, &damageInfo, spellInfo); + DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb); + SendSpellNonMeleeDamageLog(&damageInfo); + DealSpellDamage(&damageInfo, true); + return true; +} + +bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 /*damage*/, Aura *triggeredByAura, SpellEntry const *procSpell, uint32 /*procFlag*/, uint32 /*procEx*/ ,uint32 cooldown) +{ + int32 scriptId = triggeredByAura->GetModifier()->m_miscvalue; + + if(!pVictim || !pVictim->isAlive()) + return false; + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + // Basepoints of trigger aura + int32 triggerAmount = triggeredByAura->GetModifier()->m_amount; + + uint32 triggered_spell_id = 0; + + switch(scriptId) + { + case 836: // Improved Blizzard (Rank 1) + { + if (!procSpell || procSpell->SpellVisual[0]!=9487) + return false; + triggered_spell_id = 12484; + break; + } + case 988: // Improved Blizzard (Rank 2) + { + if (!procSpell || procSpell->SpellVisual[0]!=9487) + return false; + triggered_spell_id = 12485; + break; + } + case 989: // Improved Blizzard (Rank 3) + { + if (!procSpell || procSpell->SpellVisual[0]!=9487) + return false; + triggered_spell_id = 12486; + break; + } + case 4086: // Improved Mend Pet (Rank 1) + case 4087: // Improved Mend Pet (Rank 2) + { + if(!roll_chance_i(triggerAmount)) + return false; + + triggered_spell_id = 24406; + break; + } + case 4533: // Dreamwalker Raiment 2 pieces bonus + { + // Chance 50% + if (!roll_chance_i(50)) + return false; + + switch (pVictim->getPowerType()) + { + case POWER_MANA: triggered_spell_id = 28722; break; + case POWER_RAGE: triggered_spell_id = 28723; break; + case POWER_ENERGY: triggered_spell_id = 28724; break; + default: + return false; + } + break; + } + case 4537: // Dreamwalker Raiment 6 pieces bonus + triggered_spell_id = 28750; // Blessing of the Claw + break; + case 5497: // Improved Mana Gems (Serpent-Coil Braid) + triggered_spell_id = 37445; // Mana Surge + break; + case 6953: // Warbringer + RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK,0,true); + return true; + case 7010: // Revitalize (rank 1) + case 7011: // Revitalize (rank 2) + case 7012: // Revitalize (rank 3) + { + if(!roll_chance_i(triggerAmount)) + return false; + + switch( pVictim->getPowerType() ) + { + case POWER_MANA: triggered_spell_id = 48542; break; + case POWER_RAGE: triggered_spell_id = 48541; break; + case POWER_ENERGY: triggered_spell_id = 48540; break; + case POWER_RUNIC_POWER: triggered_spell_id = 48543; break; + default: return false; + } + break; + } + } + + // not processed + if(!triggered_spell_id) + return false; + + // standard non-dummy case + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleOverrideClassScriptAuraProc: Spell %u triggering for class script id %u",triggered_spell_id,scriptId); + return false; + } + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + CastSpell(pVictim, triggered_spell_id, true, castItem, triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + +bool Unit::HandleMendingAuraProc( Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/ ) +{ + // aura can be deleted at casts + SpellEntry const* spellProto = triggeredByAura->GetSpellProto(); + SpellEffectIndex effIdx = triggeredByAura->GetEffIndex(); + int32 heal = triggeredByAura->GetModifier()->m_amount; + uint64 caster_guid = triggeredByAura->GetCasterGUID(); + + // jumps + int32 jumps = triggeredByAura->GetHolder()->GetAuraCharges()-1; + + // current aura expire + triggeredByAura->GetHolder()->SetAuraCharges(1); // will removed at next charges decrease + + // next target selection + if(jumps > 0 && GetTypeId()==TYPEID_PLAYER && IS_PLAYER_GUID(caster_guid)) + { + float radius; + if (spellProto->EffectRadiusIndex[effIdx]) + radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellProto->EffectRadiusIndex[effIdx])); + else + radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellProto->rangeIndex)); + + if(Player* caster = ((Player*)triggeredByAura->GetCaster())) + { + caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL); + + if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) + { + // aura will applied from caster, but spell casted from current aura holder + SpellModifier *mod = new SpellModifier(SPELLMOD_CHARGES,SPELLMOD_FLAT,jumps-5,spellProto->Id,spellProto->SpellFamilyFlags,spellProto->SpellFamilyFlags2); + + // remove before apply next (locked against deleted) + triggeredByAura->SetInUse(true); + RemoveAurasByCasterSpell(spellProto->Id,caster->GetGUID()); + + caster->AddSpellMod(mod, true); + CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); + caster->AddSpellMod(mod, false); + triggeredByAura->SetInUse(false); + } + } + } + + // heal + CastCustomSpell(this,33110,&heal,NULL,NULL,true,NULL,NULL,caster_guid); + return true; +} + +bool Unit::HandleModCastingSpeedNotStackAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* /*triggeredByAura*/, SpellEntry const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) +{ + // Skip melee hits or instant cast spells + return !(procSpell == NULL || GetSpellCastTime(procSpell) == 0); +} + +bool Unit::HandleReflectSpellsSchoolAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) +{ + // Skip Melee hits and spells ws wrong school + return !(procSpell == NULL || (triggeredByAura->GetModifier()->m_miscvalue & procSpell->SchoolMask) == 0); +} + +bool Unit::HandleModPowerCostSchoolAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) +{ + // Skip melee hits and spells ws wrong school or zero cost + return !(procSpell == NULL || + (procSpell->manaCost == 0 && procSpell->ManaCostPercentage == 0) || // Cost check + (triggeredByAura->GetModifier()->m_miscvalue & procSpell->SchoolMask) == 0); // School check +} + +bool Unit::HandleMechanicImmuneResistanceAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) +{ + // Compare mechanic + return !(procSpell==NULL || procSpell->Mechanic != triggeredByAura->GetModifier()->m_miscvalue); +} + +bool Unit::HandleModDamageFromCasterAuraProc(Unit* pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) +{ + // Compare casters + return triggeredByAura->GetCasterGUID() == pVictim->GetGUID(); +} + +bool Unit::HandleMaelstromWeaponAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const* /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 /*cooldown*/) +{ + // remove all stack; + RemoveSpellsCausingAura(SPELL_AURA_MAELSTROM_WEAPON); + return true; +} + +bool Unit::HandleAddPctModifierAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 /*procFlag*/, uint32 procEx, uint32 /*cooldown*/) +{ + SpellEntry const *spellInfo = triggeredByAura->GetSpellProto(); + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + switch(spellInfo->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + { + // Combustion + if (spellInfo->Id == 11129) + { + //last charge and crit + if (triggeredByAura->GetHolder()->GetAuraCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) ) + return true; // charge counting (will removed) + + CastSpell(this, 28682, true, castItem, triggeredByAura); + return (procEx & PROC_EX_CRITICAL_HIT); // charge update only at crit hits, no hidden cooldowns + } + break; + } + case SPELLFAMILY_PALADIN: + { + // Glyph of Divinity + if (spellInfo->Id == 11129) + { + // Lookup base amount mana restore + for (int i = 0; i < MAX_EFFECT_INDEX; ++i) + { + if (procSpell->Effect[i] == SPELL_EFFECT_ENERGIZE) + { + int32 mana = procSpell->CalculateSimpleValue(SpellEffectIndex(i)); + CastCustomSpell(this, 54986, NULL, &mana, NULL, true, castItem, triggeredByAura); + break; + } + } + return true; + } + break; + } + } + return true; +} + +bool Unit::HandleModDamagePercentDoneAuraProc(Unit* /*pVictim*/, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 /*procFlag*/, uint32 procEx, uint32 cooldown) +{ + SpellEntry const *spellInfo = triggeredByAura->GetSpellProto(); + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + // Aspect of the Viper + if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->SpellFamilyFlags & UI64LIT(0x4000000000000)) + { + uint32 maxmana = GetMaxPower(POWER_MANA); + int32 bp = int32(maxmana* GetAttackTime(RANGED_ATTACK)/1000.0f/100.0f); + + if(cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(34075)) + return false; + + CastCustomSpell(this, 34075, &bp, NULL, NULL, true, castItem, triggeredByAura); + } + return true; +} \ No newline at end of file diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1ee860853..bebb302eb 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10155" + #define REVISION_NR "10156" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 5af3bbcac..d0a163729 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ - #define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura" - #define REVISION_DB_MANGOS "required_10148_01_mangos_mangos_string" + #define REVISION_DB_CHARACTERS "required_10156_02_characters_pet_aura" + #define REVISION_DB_MANGOS "required_10156_03_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__ diff --git a/win/VC100/game.vcxproj b/win/VC100/game.vcxproj index 44858d500..4525ed4b6 100644 --- a/win/VC100/game.vcxproj +++ b/win/VC100/game.vcxproj @@ -1,4 +1,5 @@ - + + Debug_NoPCH @@ -471,6 +472,7 @@ + diff --git a/win/VC100/game.vcxproj.filters b/win/VC100/game.vcxproj.filters index 804e66778..2cec6632e 100644 --- a/win/VC100/game.vcxproj.filters +++ b/win/VC100/game.vcxproj.filters @@ -445,6 +445,9 @@ Object + + World/Handlers + diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj index 8f1c431a6..d083dbdf2 100644 --- a/win/VC80/game.vcproj +++ b/win/VC80/game.vcproj @@ -965,6 +965,10 @@ RelativePath="..\..\src\game\SpellAuras.h" > + + diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index 1eb6872bc..1d491a296 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -958,6 +958,10 @@ RelativePath="..\..\src\game\SpellAuras.h" > + +