aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/characters.sql2
-rw-r--r--sql/mangos.sql271
-rw-r--r--sql/updates/7196_01_mangos_spell_chain.sql18
-rw-r--r--sql/updates/7196_02_mangos_spell_bonus_data.sql233
-rw-r--r--sql/updates/7198_01_characters_characters.sql27
-rw-r--r--sql/updates/7199_01_mangos_spell_bonus_data.sql11
-rw-r--r--sql/updates/7199_02_mangos_spell_proc_event.sql49
-rw-r--r--src/bindings/scripts/scripts/creature/mob_event_ai.cpp8
-rw-r--r--src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp1
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp6
-rw-r--r--src/game/AggressorAI.cpp2
-rw-r--r--src/game/AggressorAI.h2
-rw-r--r--src/game/Chat.cpp1
-rw-r--r--src/game/Chat.h1
-rw-r--r--src/game/Creature.cpp32
-rw-r--r--src/game/Creature.h3
-rw-r--r--src/game/CreatureAI.cpp26
-rw-r--r--src/game/CreatureAI.h19
-rw-r--r--src/game/CreatureAIImpl.h2
-rw-r--r--src/game/CreatureAIRegistry.cpp2
-rw-r--r--src/game/CreatureAISelector.cpp4
-rw-r--r--src/game/GuardAI.cpp2
-rw-r--r--src/game/GuardAI.h2
-rw-r--r--src/game/Level3.cpp9
-rw-r--r--src/game/NullCreatureAI.cpp18
-rw-r--r--src/game/NullCreatureAI.h30
-rw-r--r--src/game/Object.cpp8
-rw-r--r--src/game/Object.h1
-rw-r--r--src/game/ObjectAccessor.cpp6
-rw-r--r--src/game/OutdoorPvPObjectiveAI.cpp6
-rw-r--r--src/game/OutdoorPvPObjectiveAI.h2
-rw-r--r--src/game/PetAI.cpp6
-rw-r--r--src/game/PetAI.h4
-rw-r--r--src/game/Player.cpp38
-rw-r--r--src/game/PossessedAI.h3
-rw-r--r--src/game/ReactorAI.h2
-rw-r--r--src/game/SharedDefines.h4
-rw-r--r--src/game/Spell.cpp30
-rw-r--r--src/game/Spell.h17
-rw-r--r--src/game/SpellAuraDefines.h8
-rw-r--r--src/game/SpellAuras.cpp131
-rw-r--r--src/game/SpellAuras.h3
-rw-r--r--src/game/SpellEffects.cpp32
-rw-r--r--src/game/SpellMgr.cpp51
-rw-r--r--src/game/SpellMgr.h27
-rw-r--r--src/game/TotemAI.cpp2
-rw-r--r--src/game/TotemAI.h2
-rw-r--r--src/game/Unit.cpp524
-rw-r--r--src/game/Unit.h4
-rw-r--r--src/game/World.cpp3
-rw-r--r--src/shared/revision.h4
-rw-r--r--src/shared/revision_nr.h2
52 files changed, 1209 insertions, 492 deletions
diff --git a/sql/characters.sql b/sql/characters.sql
index 4a1bc4f0a10..fcd5cc08ffc 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_7113_01_characters_character_achievement_progress` bit(1) default NULL
+ `required_7198_01_characters_characters` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--
diff --git a/sql/mangos.sql b/sql/mangos.sql
index df89d8beab7..453debf44dd 100644
--- a/sql/mangos.sql
+++ b/sql/mangos.sql
@@ -22,7 +22,7 @@
DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
- `required_7175_01_mangos_spell_proc_event` bit(1) default NULL
+ `required_7199_02_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@@ -16052,7 +16052,22 @@ INSERT INTO spell_chain VALUES
(61195,61194,61193,3,0),
(61196,61195,61193,4,0),
(61197,61196,61193,5,0),
-(61198,61197,61193,6,0);
+(61198,61197,61193,6,0),
+
+/*Tranquility*/
+(44203, 0,44203,1,0),
+(44205,44203,44203,2,0),
+(44206,44205,44203,3,0),
+(44207,44206,44203,4,0),
+(44208,44207,44203,5,0),
+(48444,44208,44203,6,0),
+(48445,48444,44203,7,0),
+/*Hurricane*/
+(42231, 0,42231,1,0),
+(42232,42231,42231,2,0),
+(42233,42232,42231,3,0),
+(42230,42233,42231,4,0),
+(48466,42230,42231,5,0);
/*!40000 ALTER TABLE `spell_chain` ENABLE KEYS */;
UNLOCK TABLES;
@@ -16421,6 +16436,7 @@ INSERT INTO `spell_proc_event` VALUES
(13046, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(13047, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(13048, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
+(13163, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0),
(13165, 0x00000000, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(13754, 0x00000000, 8, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(13867, 0x00000000, 8, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@@ -16864,6 +16880,8 @@ INSERT INTO `spell_proc_event` VALUES
(44396, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0),
(44401, 0x00000000, 3, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000FFF, 0.000000, 0.000000, 0),
(44404, 0x00000000, 3, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
+(44442, 0x00000000, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1),
+(44443, 0x00000000, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1),
(44445, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(44446, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(44448, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@@ -16997,6 +17015,7 @@ INSERT INTO `spell_proc_event` VALUES
(51470, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51474, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(51478, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
+(51479, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(51556, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51557, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51558, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@@ -17026,6 +17045,12 @@ INSERT INTO `spell_proc_event` VALUES
(51698, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51700, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51701, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
+(51940, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
+(51989, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
+(52004, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
+(52005, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
+(52007, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
+(52008, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(52020, 0x00000000, 7, 0x00008000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(52127, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(52129, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
@@ -17177,11 +17202,251 @@ INSERT INTO `spell_proc_event` VALUES
(60826, 0x00000000, 15, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(61188, 0x00000000, 5, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(61257, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0),
-(61324, 0x00000000, 10, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0);
+(61324, 0x00000000, 10, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
+(61846, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0),
+(61847, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0);
/*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */;
UNLOCK TABLES;
--
+-- Table structure for spell_bonus_data
+--
+DROP TABLE IF EXISTS `spell_bonus_data`;
+CREATE TABLE `spell_bonus_data` (
+ `entry` smallint(5) unsigned NOT NULL,
+ `direct_bonus` float NOT NULL default '0',
+ `dot_bonus` float NOT NULL default '0',
+ `ap_bonus` float NOT NULL default '0',
+ `comments` varchar(255) default NULL,
+ PRIMARY KEY (`entry`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+LOCK TABLES `spell_bonus_data` WRITE;
+/*!40000 ALTER TABLE `spell_bonus_data` DISABLE KEYS */;
+INSERT INTO `spell_bonus_data` VALUES
+('5185', '1.6104', '0', '0', 'Druid - Healing Touch'),
+('33763', '0', '0.09518', '0', 'Druid - Lifebloom'),
+('774', '0', '0.37604', '0', 'Druid - Rejuvenation'),
+('8936', '0.539', '0.188', '0', 'Druid - Regrowth'),
+('18562', '0', '0', '0', 'Druid - Swiftmend'),
+('44203', '0.538', '0', '0', 'Druid - Tranquility Triggered'),
+('48438', '0', '0.11505', '0', 'Druid - Wild Growth'),
+('50464', '0.6611', '0', '0', 'Druid - Nourish'),
+('339', '0', '0.1', '0', 'Druid - Entangling Roots'),
+('42231', '0.12898', '0', '0', 'Druid - Hurricane Triggered'),
+('5570', '0', '0.127', '0', 'Druid - Insect Swarm'),
+('8921', '0.1515', '0.13', '0', 'Druid - Moonfire'),
+('2912', '1', '0', '0', 'Druid - Starfire'),
+('5176', '0.5714', '0', '0', 'Druid - Wrath'),
+('30451', '0.7143', '0', '0', 'Mage - Arcane Blast'),
+('1449', '0.2128', '0', '0', 'Mage - Arcane Explosion'),
+('7268', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 1'),
+('7269', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 2'),
+('7270', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 3'),
+('8419', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 4'),
+('8418', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 5'),
+('10273', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 6'),
+('10274', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 7'),
+('25346', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 8'),
+('27076', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 9'),
+('38700', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 10'),
+('38703', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 11'),
+('42844', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 12'),
+('42845', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 13'),
+('1463', '0.8053', '0', '0', 'Mage - Mana Shield'),
+('44425', '0.8571', '0', '0', 'Mage - Arcane Barrage'),
+('11113', '0.1357', '0', '0', 'Mage - Blast Wave Rank'),
+('31661', '0.1357', '0', '0', 'Mage - Dragons Breath'),
+('2136', '0.4286', '0', '0', 'Mage - Fire Blast'),
+('133', '1', '0', '0', 'Mage - Fire Ball'),
+('2120', '0.2357', '0.122', '0', 'Mage - Flamestrike'),
+('11366', '1.15', '0.05', '0', 'Mage - Pyroblast'),
+('2948', '0.4286', '0', '0', 'Mage - Scorch'),
+('44614', '0.8571', '0', '0', 'Mage - Frostfire Bolt'),
+('44457', '0.4', '0.2', '0', 'Mage - Living Bomb'),
+('42208', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 1'),
+('42209', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 2'),
+('42210', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 3'),
+('42211', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 4'),
+('42212', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 5'),
+('42213', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 6'),
+('42198', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 7'),
+('42937', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 8'),
+('42938', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 9'),
+('120', '0.1357', '0', '0', 'Mage - Cone of Cold'),
+('122', '0.193', '0', '0', 'Mage - Frost Nova'),
+('116', '0.8143', '0', '0', 'Mage - Frost Bolt'),
+('11426', '0.8053', '0', '0', 'Mage - Ice Barrier'),
+('30455', '0.1429', '0', '0', 'Mage - Ice Lance'),
+('19750', '0.4286', '0', '0', 'Paladin - Flash of Light'),
+('635', '0.7143', '0', '0', 'Paladin - Holy Light'),
+('25912', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 1'),
+('25911', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 2'),
+('25902', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 3'),
+('27176', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 4'),
+('33073', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 5'),
+('48822', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 6'),
+('48823', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 7'),
+('25914', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 1'),
+('25913', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 2'),
+('25903', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 3'),
+('27175', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 4'),
+('33074', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 5'),
+('48820', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 6'),
+('48821', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 7'),
+('31935', '0.07', '0', '0.07', 'Paladin - Avengers Shiled'),
+('26573', '0', '0.04', '0.04', 'Paladin - Consecration'),
+('879', '0.15', '0', '0.15', 'Paladin - Exorcism'),
+('24275', '0.15', '0', '0.15', 'Paladin - Hammer of Wrath'),
+('20925', '0.09', '0', '0.056', 'Paladin - Holy Shield'),
+('2812', '0.07', '0', '0.07', 'Paladin - Holy Wrath'),
+('31893', '0.25', '0', '0.16', 'Paladin - Seal of Blood Enemy Proc'),
+('32221', '0.25', '0', '0.16', 'Paladin - Seal of Blood Self Proc'),
+('20424', '0.25', '0', '0.16', 'Paladin - Seal of Command Proc'),
+('379', '0', '0', '0', 'Shaman - Earth Shield Triggered'),
+('20167', '0.25', '0', '0.16', 'Paladin - Seal of Light Proc'),
+('53719', '0.25', '0', '0.16', 'Paladin - Seal of The Martyr Enemy Proc'),
+('53718', '0.25', '0', '0.16', 'Paladin - Seal of The Martyr Self Proc'),
+('25742', '0.07', '0', '0.039', 'Paladin - Seal of Righteousness Dummy Proc'),
+('31803', '0', '0.013', '0.15', 'Paladin - Holy Vengeance'),
+('52042', '0.045', '0', '0', 'Shaman - Healing Stream Totem Triggered Heal'),
+('32546', '0.8068', '0', '0', 'Priest - Binding Heal'),
+('34861', '0.402', '0', '0', 'Priest - Circle of Healing'),
+('19236', '0.8068', '0', '0', 'Priest - Desperate Prayer'),
+('2061', '0.8068', '0', '0', 'Priest - Flash Heal'),
+('2060', '1.6135', '0', '0', 'Priest - Greater Heal'),
+('23455', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 1'),
+('23458', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 2'),
+('23459', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 3'),
+('27803', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 4'),
+('27804', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 5'),
+('27805', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 6'),
+('25329', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 7'),
+('17', '0.8068', '0', '0', 'Priest - Power Word: Shield'),
+('596', '0.8086', '0', '0', 'Priest - Prayer of Healing'),
+('33110', '0.8068', '0', '0', 'Priest - Prayer of Mending Heal Proc'),
+('139', '0', '0.376', '0', 'Priest - Renew'),
+('2944', '0.1849', '0', '0', 'Priest - Devouring Plague'),
+('14914', '0.5711', '0.024', '0', 'Priest - Holy Fire'),
+('15237', '0.1606', '0', '0', 'Priest - Holy Nova Damage'),
+('8129', '0', '0', '0', 'Priest - Mana Burn'),
+('8092', '0.4296', '0', '0', 'Priest - Mind Blast'),
+('15407', '0.257', '0', '0', 'Priest - Mind Flay'),
+('49821', '0.14286', '0', '0', 'Priest - Mind Sear Trigger Rank 1'),
+('53022', '0.14286', '0', '0', 'Priest - Mind Sear Trigger Rank 2'),
+('34433', '0.65', '0', '0', 'Priest - Shadowfiend'),
+('32379', '0.4296', '0', '0', 'Priest - Shadow Word: Death'),
+('589', '0', '0.1829', '0', 'Priest - Shadow Word: Pain'),
+('585', '0.714', '0', '0', 'Priest - Smite'),
+('34914', '0', '0.4', '0', 'Priest - Vampiric Touch'),
+('974', '0.4762', '0', '0', 'Shaman - Earth Shield'),
+('1064', '1.34', '0', '0', 'Shaman - Chain Heal'),
+('331', '1.6106', '0', '0', 'Shaman - Healing Wave'),
+('8004', '0.8082', '0', '0', 'Shaman - Lesser Healing Wave'),
+('61295', '0.4', '0.18', '0', 'Shaman - Riptide'),
+('421', '0.57', '0', '0', 'Shaman - Chain Lightning'),
+('8042', '0.3858', '0', '0', 'Shaman - Earth Shock'),
+('8443', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 1'),
+('8504', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 2'),
+('8505', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 3'),
+('11310', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 4'),
+('11311', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 5'),
+('25538', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 6'),
+('25539', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 7'),
+('61651', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 8'),
+('61660', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 9'),
+('8050', '0.2142', '0.1', '0', 'Shaman - Flame Shock'),
+('8026', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 1'),
+('8028', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 2'),
+('8029', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 3'),
+('10445', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 4'),
+('16343', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 5'),
+('16344', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 6'),
+('25488', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 7'),
+('58786', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 8'),
+('58787', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 9'),
+('58788', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 10'),
+('8056', '0.3858', '0', '0', 'Shaman - Frost Shock'),
+('8034', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 1'),
+('8037', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 2'),
+('10458', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 3'),
+('16352', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 4'),
+('16353', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 5'),
+('25501', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 6'),
+('58797', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 7'),
+('58798', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 8'),
+('58799', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 9'),
+('51505', '0.5714', '0', '0', 'Shaman - Lava Burst'),
+('403', '0.7143', '0', '0', 'Shaman - Lightning Bolt'),
+('26364', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 1'),
+('26365', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 2'),
+('26366', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 3'),
+('26367', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 4'),
+('26369', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 5'),
+('26370', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 6'),
+('26363', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 7'),
+('26371', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 8'),
+('26372', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 9'),
+('49278', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 10'),
+('49279', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 11'),
+('8188', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 1'),
+('10582', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 2'),
+('10583', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 3'),
+('10584', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 4'),
+('25551', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 5'),
+('58733', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 6'),
+('58736', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 7'),
+('3606', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 1'),
+('6350', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 2'),
+('6351', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 3'),
+('6352', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 4'),
+('10435', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 5'),
+('10436', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 6'),
+('25530', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 7'),
+('58700', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 8'),
+('58701', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 9'),
+('58702', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 10'),
+('980', '0', '0.1', '0', 'Warlock - Curse of Agony'),
+('603', '0', '2', '0', 'Warlock - Curse of Doom'),
+('172', '0', '0.3', '0', 'Warlock - Corruption'),
+('348', '0.2', '0.2', '0', 'Warlock - Immolate'),
+('27243', '0.22', '0.25', '0', 'Warlock - Seed of Corruption'),
+('18265', '0', '0.1', '0', 'Warlock - Siphon Life'),
+('30108', '0', '0.24', '0', 'Warlock - Unstable Affliction'),
+('31117', '1.8', '0', '0', 'Warlock - Unstable Affliction Dispell'),
+('17962', '0.4286', '0', '0', 'Warlock - Conflagrate'),
+('6789', '0.22', '0', '0', 'Warlock - Death Coil'),
+('28176', '0', '0', '0', 'Warlock - Fel Armor'),
+('48181', '0.4729', '0', '0', 'Warlock - Haunt'),
+('29722', '0.7143', '0', '0', 'Warlock - Incinerate'),
+('5676', '0.4286', '0', '0', 'Warlock - Searing Pain'),
+('686', '0.8571', '0', '0', 'Warlock - Shadow Bolt'),
+('17877', '0.4286', '0', '0', 'Warlock - Shadowburn'),
+('30283', '0.195', '0', '0', 'Warlock - Shadowfury'),
+('6353', '1.15', '0', '0', 'Warlock - Soul Fire'),
+('689', '0', '0.1428', '0', 'Warlock - Drain Life'),
+('5138', '0', '0', '0', 'Warlock - Drain Mana'),
+('1120', '0', '0.4286', '0', 'Warlock - Drain Soul'),
+('755', '0', '0.4485', '0', 'Warlock - Health Funnel'),
+('1949', '0', '0.0946', '0', 'Warlock - Hellfire'),
+('5857', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 1'),
+('11681', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 2'),
+('11682', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 3'),
+('27214', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 4'),
+('47822', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 5'),
+('42223', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 1'),
+('42224', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 2'),
+('42225', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 3'),
+('42226', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 4'),
+('42218', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 5'),
+('47817', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 6'),
+('47818', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 7'),
+('18220', '0.96', '0', '0', 'Warlock - Dark Pact'),
+('6229', '0.3', '0', '0', 'Warlock - Shadow Ward');
+/*!40000 ALTER TABLE `spell_bonus_data` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `spell_script_target`
--
diff --git a/sql/updates/7196_01_mangos_spell_chain.sql b/sql/updates/7196_01_mangos_spell_chain.sql
new file mode 100644
index 00000000000..c7ab0569229
--- /dev/null
+++ b/sql/updates/7196_01_mangos_spell_chain.sql
@@ -0,0 +1,18 @@
+ALTER TABLE db_version CHANGE COLUMN required_7193_01_mangos_mangos_string required_7196_01_mangos_spell_chain bit;
+
+INSERT INTO spell_chain VALUES
+/*Tranquility*/
+(44203, 0,44203,1,0),
+(44205,44203,44203,2,0),
+(44206,44205,44203,3,0),
+(44207,44206,44203,4,0),
+(44208,44207,44203,5,0),
+(48444,44208,44203,6,0),
+(48445,48444,44203,7,0),
+
+/*Hurricane*/
+(42231, 0,42231,1,0),
+(42232,42231,42231,2,0),
+(42233,42232,42231,3,0),
+(42230,42233,42231,4,0),
+(48466,42230,42231,5,0); \ No newline at end of file
diff --git a/sql/updates/7196_02_mangos_spell_bonus_data.sql b/sql/updates/7196_02_mangos_spell_bonus_data.sql
new file mode 100644
index 00000000000..7d62722bd10
--- /dev/null
+++ b/sql/updates/7196_02_mangos_spell_bonus_data.sql
@@ -0,0 +1,233 @@
+ALTER TABLE db_version CHANGE COLUMN required_7196_01_mangos_spell_chain required_7196_02_mangos_spell_bonus_data bit;
+
+-- ----------------------------
+-- Table structure for spell_bonus_data
+-- ----------------------------
+DROP TABLE IF EXISTS `spell_bonus_data`;
+CREATE TABLE `spell_bonus_data` (
+ `entry` smallint(5) unsigned NOT NULL,
+ `direct_bonus` float NOT NULL default '0',
+ `dot_bonus` float NOT NULL default '0',
+ `ap_bonus` float NOT NULL default '0',
+ `comments` varchar(255) default NULL,
+ PRIMARY KEY (`entry`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO `spell_bonus_data` VALUES
+('5185', '1.6104', '0', '0', 'Druid - Healing Touch'),
+('33763', '0', '0.09518', '0', 'Druid - Lifebloom'),
+('774', '0', '0.37604', '0', 'Druid - Rejuvenation'),
+('8936', '0.539', '0.188', '0', 'Druid - Regrowth'),
+('18562', '0', '0', '0', 'Druid - Swiftmend'),
+('44203', '0.538', '0', '0', 'Druid - Tranquility Triggered'),
+('48438', '0', '0.11505', '0', 'Druid - Wild Growth'),
+('50464', '0.6611', '0', '0', 'Druid - Nourish'),
+('339', '0', '0.1', '0', 'Druid - Entangling Roots'),
+('42231', '0.12898', '0', '0', 'Druid - Hurricane Triggered'),
+('5570', '0', '0.127', '0', 'Druid - Insect Swarm'),
+('8921', '0.1515', '0.13', '0', 'Druid - Moonfire'),
+('2912', '1', '0', '0', 'Druid - Starfire'),
+('5176', '0.5714', '0', '0', 'Druid - Wrath'),
+('30451', '0.7143', '0', '0', 'Mage - Arcane Blast'),
+('1449', '0.2128', '0', '0', 'Mage - Arcane Explosion'),
+('7268', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 1'),
+('7269', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 2'),
+('7270', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 3'),
+('8419', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 4'),
+('8418', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 5'),
+('10273', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 6'),
+('10274', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 7'),
+('25346', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 8'),
+('27076', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 9'),
+('38700', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 10'),
+('38703', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 11'),
+('42844', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 12'),
+('42845', '0.2857', '0', '0', 'Mage - Arcane Missiles Triggered Spell Rank 13'),
+('1463', '0.8053', '0', '0', 'Mage - Mana Shield'),
+('44425', '0.8571', '0', '0', 'Mage - Arcane Barrage'),
+('11113', '0.1357', '0', '0', 'Mage - Blast Wave Rank'),
+('31661', '0.1357', '0', '0', 'Mage - Dragons Breath'),
+('2136', '0.4286', '0', '0', 'Mage - Fire Blast'),
+('133', '1', '0', '0', 'Mage - Fire Ball'),
+('2120', '0.2357', '0.122', '0', 'Mage - Flamestrike'),
+('11366', '1.15', '0.05', '0', 'Mage - Pyroblast'),
+('2948', '0.4286', '0', '0', 'Mage - Scorch'),
+('44614', '0.8571', '0', '0', 'Frostfire Bolt'),
+('44457', '0.4', '0.2', '0', 'Mage - Living Bomb'),
+('42208', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 1'),
+('42209', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 2'),
+('42210', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 3'),
+('42211', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 4'),
+('42212', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 5'),
+('42213', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 6'),
+('42198', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 7'),
+('42937', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 8'),
+('42938', '0.0952', '0', '0', 'Mage - Blizzard Triggered Spell Rank 9'),
+('120', '0.1357', '0', '0', 'Mage - Cone of Cold'),
+('122', '0.193', '0', '0', 'Mage - Frost Nova'),
+('116', '0.8143', '0', '0', 'Mage - Frost Bolt'),
+('11426', '0.8053', '0', '0', 'Mage - Ice Barrier'),
+('30455', '0.1429', '0', '0', 'Mage - Ice Lance'),
+('19750', '0.4286', '0', '0', 'Paladin - Flash of Light'),
+('635', '0.7143', '0', '0', 'Paladin - Holy Light'),
+('25912', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 1'),
+('25911', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 2'),
+('25902', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 3'),
+('27176', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 4'),
+('33073', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 5'),
+('48822', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 6'),
+('48823', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Hurt Rank 7'),
+('25914', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 1'),
+('25913', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 2'),
+('25903', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 3'),
+('27175', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 4'),
+('33074', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 5'),
+('48820', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 6'),
+('48821', '0.4286', '0', '0', 'Paladin - Holy Shock Triggered Heal Rank 7'),
+('31935', '0.07', '0', '0.07', 'Paladin - Avengers Shiled'),
+('26573', '0', '0.04', '0.04', 'Paladin - Consecration'),
+('879', '0.15', '0', '0.15', 'Paladin - Exorcism'),
+('24275', '0.15', '0', '0.15', 'Paladin - Hammer of Wrath'),
+('20925', '0.09', '0', '0.056', 'Paladin - Holy Shield'),
+('2812', '0.07', '0', '0.07', 'Paladin - Holy Wrath'),
+('31893', '0.25', '0', '0.16', 'Paladin - Seal of Blood Enemy Proc'),
+('32221', '0.25', '0', '0.16', 'Paladin - Seal of Blood Self Proc'),
+('20424', '0.25', '0', '0.16', 'Paladin - Seal of Command Proc'),
+('379', '0', '0', '0', 'Shaman - Earth Shield Triggered'),
+('20167', '0.25', '0', '0.16', 'Paladin - Seal of Light Proc'),
+('53719', '0.25', '0', '0.16', 'Paladin - Seal of The Martyr Enemy Proc'),
+('53718', '0.25', '0', '0.16', 'Paladin - Seal of The Martyr Self Proc'),
+('25742', '0.07', '0', '0.039', 'Paladin - Seal of Righteousness Dummy Proc'),
+('31803', '0', '0.013', '0.15', 'Paladin - Holy Vengeance'),
+('52042', '0.045', '0', '0', 'Shaman - Healing Stream Totem Triggered Heal'),
+('32546', '0.8068', '0', '0', 'Priest - Binding Heal'),
+('34861', '0.402', '0', '0', 'Priest - Circle of Healing'),
+('19236', '0.8068', '0', '0', 'Priest - Desperate Prayer'),
+('2061', '0.8068', '0', '0', 'Priest - Flash Heal'),
+('2060', '1.6135', '0', '0', 'Priest - Greater Heal'),
+('23455', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 1'),
+('23458', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 2'),
+('23459', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 3'),
+('27803', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 4'),
+('27804', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 5'),
+('27805', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 6'),
+('25329', '0.3035', '0', '0', 'Priest - Holy Nova Heal Rank 7'),
+('17', '0.8068', '0', '0', 'Priest - Power Word: Shield'),
+('596', '0.8086', '0', '0', 'Priest - Prayer of Healing'),
+('33110', '0.8068', '0', '0', 'Priest - Prayer of Mending Heal Proc'),
+('139', '1.88', '0', '0', 'Priest - Renew'),
+('2944', '0.1849', '0', '0', 'Priest - Devouring Plague'),
+('14914', '0.5711', '0.024', '0', 'Priest - Holy Fire'),
+('15237', '0.1606', '0', '0', 'Priest - Holy Nova Damage'),
+('8129', '0', '0', '0', 'Priest - Mana Burn'),
+('8092', '0.4296', '0', '0', 'Priest - Mind Blast'),
+('15407', '0.257', '0', '0', 'Priest - Mind Flay'),
+('49821', '0.7143', '0', '0', 'Priest - Mind Sear Trigger Rank 1'),
+('53022', '0.7143', '0', '0', 'Priest - Mind Sear Trigger Rank 2'),
+('34433', '0.65', '0', '0', 'Priest - Shadowfiend'),
+('32379', '0.4296', '0', '0', 'Priest - Shadow Word: Death'),
+('589', '0', '0.1829', '0', 'Priest - Shadow Word: Pain'),
+('585', '0.714', '0', '0', 'Priest - Smite'),
+('34914', '0', '0.4', '0', 'Priest - Vampiric Touch'),
+('974', '0.4762', '0', '0', 'Shaman - Earth Shield'),
+('1064', '1.34', '0', '0', 'Shaman - Chain Heal'),
+('331', '1.6106', '0', '0', 'Shaman - Healing Wave'),
+('8004', '0.8082', '0', '0', 'Shaman - Lesser Healing Wave'),
+('61295', '0.4', '0.18', '0', 'Shaman - Riptide'),
+('421', '0.57', '0', '0', 'Shaman - Chain Lightning'),
+('8042', '0.3858', '0', '0', 'Shaman - Earth Shock'),
+('8443', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 1'),
+('8504', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 2'),
+('8505', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 3'),
+('11310', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 4'),
+('11311', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 5'),
+('25538', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 6'),
+('25539', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 7'),
+('61651', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 8'),
+('61660', '0.2142', '0', '0', 'Shaman - Fire Nova Totem Casted by Totem Rank 9'),
+('8050', '0.2142', '0.1', '0', 'Shaman - Flame Shock'),
+('8026', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 1'),
+('8028', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 2'),
+('8029', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 3'),
+('10445', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 4'),
+('16343', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 5'),
+('16344', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 6'),
+('25488', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 7'),
+('58786', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 8'),
+('58787', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 9'),
+('58788', '0.1', '0', '0', 'Shaman - Flametongue Weapon Proc Rank 10'),
+('8056', '0.3858', '0', '0', 'Shaman - Frost Shock'),
+('8034', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 1'),
+('8037', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 2'),
+('10458', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 3'),
+('16352', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 4'),
+('16353', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 5'),
+('25501', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 6'),
+('58797', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 7'),
+('58798', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 8'),
+('58799', '0.1', '0', '0', 'Shaman - Frostbrand Attack Rank 9'),
+('51505', '0.5714', '0', '0', 'Shaman - Lava Burst'),
+('403', '0.7143', '0', '0', 'Shaman - Lightning Bolt'),
+('26364', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 1'),
+('26365', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 2'),
+('26366', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 3'),
+('26367', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 4'),
+('26369', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 5'),
+('26370', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 6'),
+('26363', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 7'),
+('26371', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 8'),
+('26372', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 9'),
+('49278', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 10'),
+('49279', '0.33', '0', '0', 'Shaman - Lightning Shield Proc Rank 11'),
+('8188', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 1'),
+('10582', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 2'),
+('10583', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 3'),
+('10584', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 4'),
+('25551', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 5'),
+('58733', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 6'),
+('58736', '0.1', '0', '0', 'Shaman - Magma Totam Passive Rank 7'),
+('3606', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 1'),
+('6350', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 2'),
+('6351', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 3'),
+('6352', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 4'),
+('10435', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 5'),
+('10436', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 6'),
+('25530', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 7'),
+('58700', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 8'),
+('58701', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 9'),
+('58702', '0.1667', '0', '0', 'Shaman - Searing Totem Attack Rank 10'),
+('980', '0', '0.1', '0', 'Warlock - Curse of Agony'),
+('603', '0', '2', '0', 'Warlock - Curse of Doom'),
+('172', '0', '0.3', '0', 'Warlock - Corruption'),
+('348', '0.2', '0.2', '0', 'Warlock - Immolate'),
+('27243', '0.22', '0.25', '0', 'Warlock - Seed of Corruption'),
+('18265', '0', '1', '0', 'Warlock - Siphon Life'),
+('30108', '0', '0.24', '0', 'Warlock - Unstable Affliction'),
+('17962', '0.4286', '0', '0', 'Warlock - Conflagrate'),
+('6789', '0.22', '0', '0', 'Warlock - Death Coil'),
+('48181', '0.4729', '0', '0', 'Warlock - Haunt'),
+('29722', '0.7143', '0', '0', 'Warlock - Incinerate'),
+('5676', '0.4286', '0', '0', 'Warlock - Searing Pain'),
+('686', '0.8571', '0', '0', 'Warlock - Shadow Bolt'),
+('17877', '0.4286', '0', '0', 'Warlock - Shadowburn'),
+('30283', '0.195', '0', '0', 'Warlock - Shadowfury'),
+('6353', '1.15', '0', '0', 'Warlock - Soul Fire'),
+('689', '0', '0.1428', '0', 'Warlock - Drain Life'),
+('5138', '0', '0', '0', 'Warlock - Drain Mana'),
+('1120', '0', '0.4286', '0', 'Warlock - Drain Soul'),
+('755', '0', '0.4485', '0', 'Warlock - Health Funnel'),
+('1949', '0', '0.0946', '0', 'Warlock - Hellfire'),
+('5857', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 1'),
+('11681', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 2'),
+('11682', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 3'),
+('27214', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 4'),
+('47822', '0.1428', '0', '0', 'Warlock - Hellfire Effect on Enemy Rank 5'),
+('42223', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 1'),
+('42224', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 2'),
+('42225', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 3'),
+('42226', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 4'),
+('42218', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 5'),
+('47817', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 6'),
+('47818', '0.952', '0', '0', 'Warlock - Rain of Fire Triggered Rank 7'),
+('18220', '0.96', '0', '0', 'Warlock - Dark Pact'),
+('6229', '0.3', '0', '0', 'Warlock - Shadow Ward'); \ No newline at end of file
diff --git a/sql/updates/7198_01_characters_characters.sql b/sql/updates/7198_01_characters_characters.sql
new file mode 100644
index 00000000000..5e77c643291
--- /dev/null
+++ b/sql/updates/7198_01_characters_characters.sql
@@ -0,0 +1,27 @@
+ALTER TABLE character_db_version CHANGE COLUMN required_7113_01_characters_character_achievement_progress required_7198_01_characters_characters bit;
+
+UPDATE `characters`.`item_instance` AS `t1`
+INNER JOIN `mangos`.`item_template` AS `t2` ON
+`t2`.`entry` = SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',4),' ',-1)
+SET `t1`.`data` = CONCAT(
+ SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',16),' ',-16), ' ',
+ IF (`t2`.`spellcharges_1` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',17),' ',-1) = 0, IF(`t2`.`spellcharges_1` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',17),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_2` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',18),' ',-1) = 0, IF(`t2`.`spellcharges_2` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',18),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_3` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',19),' ',-1) = 0, IF(`t2`.`spellcharges_3` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',19),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_4` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',20),' ',-1) = 0, IF(`t2`.`spellcharges_4` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',20),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_5` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',21),' ',-1) = 0, IF(`t2`.`spellcharges_5` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',21),' ',-1))), ' ',
+ SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',64),' ',-64+21),' ')
+WHERE (`t2`.`spellid_1` = 55884) AND (SUBSTRING_INDEX(data,' ',64) = data AND SUBSTRING_INDEX(data,' ',64-1) <> data);
+
+UPDATE `characters`.`item_instance` AS `t1`
+INNER JOIN `mangos`.`item_template` AS `t2` ON
+`t2`.`entry` = SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',4),' ',-1)
+SET `t1`.`data` = CONCAT(
+ SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',16),' ',-16), ' ',
+ IF (`t2`.`spellcharges_1` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',17),' ',-1) = 0, IF(`t2`.`spellcharges_1` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',17),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_2` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',18),' ',-1) = 0, IF(`t2`.`spellcharges_2` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',18),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_3` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',19),' ',-1) = 0, IF(`t2`.`spellcharges_3` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',19),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_4` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',20),' ',-1) = 0, IF(`t2`.`spellcharges_4` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',20),' ',-1))), ' ',
+ IF (`t2`.`spellcharges_5` = 0, 0, IF (SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',21),' ',-1) = 0, IF(`t2`.`spellcharges_5` < 0, 4294967295, 1), SUBSTRING_INDEX(SUBSTRING_INDEX(`t1`.`data`,' ',21),' ',-1))), ' ',
+ SUBSTRING_INDEX(SUBSTRING_INDEX(`data`,' ',138),' ',-138+21),' ')
+WHERE (`t2`.`spellid_1` = 55884) AND (SUBSTRING_INDEX(data,' ',138) = data AND SUBSTRING_INDEX(data,' ',138-1) <> data);
diff --git a/sql/updates/7199_01_mangos_spell_bonus_data.sql b/sql/updates/7199_01_mangos_spell_bonus_data.sql
new file mode 100644
index 00000000000..99d908b183f
--- /dev/null
+++ b/sql/updates/7199_01_mangos_spell_bonus_data.sql
@@ -0,0 +1,11 @@
+ALTER TABLE db_version CHANGE COLUMN required_7196_02_mangos_spell_bonus_data required_7199_01_mangos_spell_bonus_data bit;
+
+DELETE FROM `spell_bonus_data` WHERE `entry` IN (44614, 139, 49821, 53022, 18265, 31117, 28176);
+INSERT INTO `spell_bonus_data` VALUES
+('44614', '0.8571', '0', '0', 'Mage - Frostfire Bolt'),
+('139', '0', '0.376', '0', 'Priest - Renew'),
+('49821', '0.14286', '0', '0', 'Priest - Mind Sear Trigger Rank 1'),
+('53022', '0.14286', '0', '0', 'Priest - Mind Sear Trigger Rank 2'),
+('18265', '0', '0.1', '0', 'Warlock - Siphon Life'),
+('31117', '1.8', '0', '0', 'Warlock - Unstable Affliction Dispell'),
+('28176', '0', '0', '0', 'Warlock - Fel Armor');
diff --git a/sql/updates/7199_02_mangos_spell_proc_event.sql b/sql/updates/7199_02_mangos_spell_proc_event.sql
new file mode 100644
index 00000000000..51017507e52
--- /dev/null
+++ b/sql/updates/7199_02_mangos_spell_proc_event.sql
@@ -0,0 +1,49 @@
+ALTER TABLE db_version CHANGE COLUMN required_7199_01_mangos_spell_bonus_data required_7199_02_mangos_spell_proc_event bit;
+
+-- (51479) Astral Shift (Rank 3)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (51479);
+INSERT INTO `spell_proc_event` VALUES (51479, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0);
+
+-- (61846) Aspect of the Dragonhawk (Rank 1)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (61846);
+INSERT INTO `spell_proc_event` VALUES (61846, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0);
+
+-- (61847) Aspect of the Dragonhawk (Rank 2)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (61847);
+INSERT INTO `spell_proc_event` VALUES (61847, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0);
+
+-- (13163) Aspect of the Monkey ()
+DELETE FROM `spell_proc_event` WHERE `entry` IN (13163);
+INSERT INTO `spell_proc_event` VALUES (13163, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0);
+
+-- (51940) Earthliving Weapon (Passive) (Rank 1)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (51940);
+INSERT INTO `spell_proc_event` VALUES (51940, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0);
+
+-- (51989) Earthliving Weapon (Passive) (Rank 2)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (51989);
+INSERT INTO `spell_proc_event` VALUES (51989, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0);
+
+-- (52004) Earthliving Weapon (Passive) (Rank 3)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (52004);
+INSERT INTO `spell_proc_event` VALUES (52004, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0);
+
+-- (52005) Earthliving Weapon (Passive) (Rank 4)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (52005);
+INSERT INTO `spell_proc_event` VALUES (52005, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0);
+
+-- (52007) Earthliving Weapon (Passive) (Rank 5)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (52007);
+INSERT INTO `spell_proc_event` VALUES (52007, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0);
+
+-- (52008) Earthliving Weapon (Passive) (Rank 6)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (52008);
+INSERT INTO `spell_proc_event` VALUES (52008, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0);
+
+-- (44442) Firestarter (Rank 1)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (44442);
+INSERT INTO `spell_proc_event` VALUES (44442, 0x00, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1);
+
+-- (44443) Firestarter (Rank 2)
+DELETE FROM `spell_proc_event` WHERE `entry` IN (44443);
+INSERT INTO `spell_proc_event` VALUES (44443, 0x00, 3, 0x00800000, 0x00000040, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 1); \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
index eee4269e12c..6b46b7aecde 100644
--- a/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
+++ b/src/bindings/scripts/scripts/creature/mob_event_ai.cpp
@@ -1225,7 +1225,7 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
void UpdateAI(const uint32 diff)
{
//Check if we are in combat (also updates calls threat update code)
- bool Combat = InCombat ? (m_creature->SelectHostilTarget() && m_creature->getVictim()) : false;
+ bool Combat = InCombat ? m_creature->SelectHostilTarget() : false;
//Must return if creature isn't alive. Normally select hostil target and get victim prevent this
if (!m_creature->isAlive())
@@ -1233,11 +1233,9 @@ struct TRINITY_DLL_DECL Mob_EventAI : public ScriptedAI
if (IsFleeing)
{
- if(TimetoFleeLeft < diff
- || m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE
- && m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLEEING_MOTION_TYPE)
+ if(TimetoFleeLeft < diff)
{
- m_creature->GetMotionMaster()->Clear(false);
+ m_creature->SetControlled(false, UNIT_STAT_FLEEING);
m_creature->SetNoCallAssistance(false);
m_creature->CallAssistance();
if(m_creature->getVictim())
diff --git a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
index c6ef71f25e5..6a11c455f67 100644
--- a/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
+++ b/src/bindings/scripts/scripts/zone/stormwind/stormwind_city.cpp
@@ -149,7 +149,6 @@ struct TRINITY_DLL_DECL npc_dashel_stonefistAI : public ScriptedAI
//m_creature->CombatStop();
EnterEvadeMode();
}
- AttackedBy(done_by);
}
void Aggro(Unit *who) {}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp
index 87fe0f92641..c7e138e0918 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/botanica/boss_laj.cpp
@@ -144,6 +144,12 @@ struct TRINITY_DLL_DECL boss_lajAI : public ScriptedAI
{
}
+ void JustSummoned(Creature *summon)
+ {
+ if(summon && m_creature->getVictim())
+ summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0));
+ }
+
void UpdateAI(const uint32 diff)
{
if( !m_creature->SelectHostilTarget() || !m_creature->getVictim() )
diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp
index 1e29cd1df30..99e39618f53 100644
--- a/src/game/AggressorAI.cpp
+++ b/src/game/AggressorAI.cpp
@@ -38,7 +38,7 @@ AggressorAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+AggressorAI::AggressorAI(Creature *c) : i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
{
}
diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h
index 51c123237f8..f6e2a649c8a 100644
--- a/src/game/AggressorAI.h
+++ b/src/game/AggressorAI.h
@@ -36,7 +36,7 @@ class TRINITY_DLL_DECL AggressorAI : public CreatureAI
public:
- AggressorAI(Creature &c);
+ AggressorAI(Creature *c);
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 42fe369e1d4..785b2380914 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -310,6 +310,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
{ "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
{ "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
+ { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
{ "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL },
{ "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 483f3c97863..8faea36e9fc 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -264,6 +264,7 @@ class ChatHandler
bool HandleReloadSpellElixirCommand(const char* args);
bool HandleReloadSpellLearnSpellCommand(const char* args);
bool HandleReloadSpellProcEventCommand(const char* args);
+ bool HandleReloadSpellBonusesCommand(const char* args);
bool HandleReloadSpellScriptTargetCommand(const char* args);
bool HandleReloadSpellScriptsCommand(const char* args);
bool HandleReloadSpellTargetPositionCommand(const char* args);
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 7ce5de97297..a4e683fb9d1 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -336,6 +336,8 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags);
SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags);
+ RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
+
SetMeleeDamageSchool(SpellSchools(GetCreatureInfo()->dmgschool));
SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor));
SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(GetCreatureInfo()->resistance1));
@@ -375,6 +377,12 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )
else
SetReactState(REACT_AGGRESSIVE);
+ if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT)
+ {
+ ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
+ }
+
return true;
}
@@ -482,7 +490,7 @@ void Creature::Update(uint32 diff)
if(!isAlive())
break;
- if(!IsInEvadeMode())
+ if(!IsInEvadeMode() && m_AI_enabled)
{
// do not allow the AI to be changed during update
m_AI_locked = true;
@@ -599,6 +607,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
i_AI = ai ? ai : FactorySelector::selectAI(this);
if (oldAI)
delete oldAI;
+ m_AI_enabled = true;
return true;
}
@@ -607,10 +616,13 @@ void Creature::InitPossessedAI()
if (!isPossessed()) return;
if (!i_AI_possessed)
- i_AI_possessed = new PossessedAI(*this);
+ i_AI_possessed = new PossessedAI(this);
// Signal the old AI that it's been disabled
i_AI->OnPossess(true);
+
+ if(!(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CHARM_AI))
+ m_AI_enabled = false;
}
void Creature::DisablePossessedAI()
@@ -621,6 +633,8 @@ void Creature::DisablePossessedAI()
// Signal the old AI that it's been re-enabled
i_AI->OnPossess(false);
+
+ m_AI_enabled = true;
}
bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data)
@@ -1855,22 +1869,12 @@ void Creature::DoFleeToGetAssistance(float radius) // Optional parameter
return;
Creature* pCreature = NULL;
-
- CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
Trinity::NearestAssistCreatureInCreatureRangeCheck u_check(this,getVictim(),radius);
Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck> searcher(pCreature, u_check);
-
- TypeContainerVisitor<Trinity::CreatureLastSearcher<Trinity::NearestAssistCreatureInCreatureRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, grid_creature_searcher, *(GetMap()));
+ VisitNearbyGridObject(radius, searcher);
if(!pCreature)
- GetMotionMaster()->MoveFleeing(getVictim());
+ SetControlled(true, UNIT_STAT_FLEEING);
else
GetMotionMaster()->MovePoint(0,pCreature->GetPositionX(),pCreature->GetPositionY(),pCreature->GetPositionZ());
}
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 6ba3c9178e3..59475e27618 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -132,6 +132,8 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature
CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging)
+ CREATURE_FLAG_EXTRA_CHARM_AI = 0x00008000, // use ai when charmed
+ CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00010000, // cannot be taunted
};
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
@@ -676,6 +678,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool m_AlreadyCallAssistance;
bool m_regenHealth;
bool m_AI_locked;
+ bool m_AI_enabled;
bool m_isDeadByDefault;
SpellSchoolMask m_meleeDamageSchoolMask;
diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp
index 71046e2f154..66c9d5af0b0 100644
--- a/src/game/CreatureAI.cpp
+++ b/src/game/CreatureAI.cpp
@@ -27,37 +27,47 @@ CreatureAI::~CreatureAI()
{
}
-SimpleCharmedAI::SimpleCharmedAI(Unit &u) : me(u)
+void CreatureAI::EnterEvadeMode()
{
+ if(!me) return;
+
+ me->RemoveAllAuras();
+ me->DeleteThreatList();
+ me->CombatStop();
+ me->LoadCreaturesAddon();
+ me->SetLootRecipient(NULL);
+
+ if(me->isAlive())
+ me->GetMotionMaster()->MoveTargetedHome();
}
void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
{
- Creature *charmer = (Creature*)me.GetCharmer();
+ Creature *charmer = (Creature*)me->GetCharmer();
//kill self if charm aura has infinite duration
if(charmer->IsInEvadeMode())
{
- Unit::AuraList const& auras = me.GetAurasByType(SPELL_AURA_MOD_CHARM);
+ Unit::AuraList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM);
for(Unit::AuraList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->IsPermanent())
{
- charmer->Kill(&me);
+ charmer->Kill(me);
return;
}
}
if(!charmer->isInCombat())
- me.GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- Unit *target = me.getVictim();
+ Unit *target = me->getVictim();
if(!target || !charmer->canAttack(target))
{
target = charmer->SelectNearestTarget();
if(!target)
return;
- me.GetMotionMaster()->MoveChase(target);
- me.Attack(target, true);
+ me->GetMotionMaster()->MoveChase(target);
+ me->Attack(target, true);
}
}
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index b5fda95ef85..72e911cceaf 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -72,21 +72,25 @@ enum SelectAggroTarget
class TRINITY_DLL_SPEC UnitAI
{
public:
+ UnitAI(Unit *u) : me(u) {}
virtual void UpdateAI(const uint32 diff) = 0;
+ protected:
+ Unit *me;
};
-class TRINITY_DLL_SPEC SimpleCharmedAI
+class TRINITY_DLL_SPEC SimpleCharmedAI : public UnitAI
{
public:
- SimpleCharmedAI(Unit &u);
virtual void UpdateAI(const uint32 diff);
- private:
- Unit &me;
};
class TRINITY_DLL_SPEC CreatureAI : public UnitAI
{
+ protected:
+ Creature *me;
public:
+ CreatureAI() : UnitAI(NULL), me(NULL) {}
+ CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c) {}
virtual ~CreatureAI();
@@ -97,10 +101,10 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
virtual void AttackStart(Unit *) = 0;
// Called at stopping attack by any attacker
- virtual void EnterEvadeMode() = 0;
+ virtual void EnterEvadeMode();
// Called at any Damage from any attacker (before damage apply)
- virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) { AttackedBy(done_by); }
+ virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {}
// Is unit visible for MoveInLineOfSight
virtual bool IsVisible(Unit *) const = 0;
@@ -128,9 +132,6 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
// Called when vitim entered water and creature can not enter water
virtual bool canReachByRangeAttack(Unit*) { return false; }
- // Called when the creature is attacked
- virtual void AttackedBy(Unit * /*attacker*/) {}
-
// Called when creature is spawned or respawned (for reseting variables)
virtual void JustRespawned() {}
diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h
index 76ba93a3cb5..2122adeb61c 100644
--- a/src/game/CreatureAIImpl.h
+++ b/src/game/CreatureAIImpl.h
@@ -27,6 +27,6 @@ inline CreatureAI*
CreatureAIFactory<REAL_AI>::Create(void *data) const
{
Creature* creature = reinterpret_cast<Creature *>(data);
- return (new REAL_AI(*creature));
+ return (new REAL_AI(creature));
}
#endif
diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp
index a4ee030c34e..12b4aa97d0d 100644
--- a/src/game/CreatureAIRegistry.cpp
+++ b/src/game/CreatureAIRegistry.cpp
@@ -41,6 +41,8 @@ namespace AIRegistry
(new CreatureAIFactory<NullCreatureAI>("NullCreatureAI"))->RegisterSelf();
(new CreatureAIFactory<AggressorAI>("AggressorAI"))->RegisterSelf();
(new CreatureAIFactory<ReactorAI>("ReactorAI"))->RegisterSelf();
+ (new CreatureAIFactory<PassiveAI>("PassiveAI"))->RegisterSelf();
+ (new CreatureAIFactory<CritterAI>("CritterAI"))->RegisterSelf();
(new CreatureAIFactory<GuardAI>("GuardAI"))->RegisterSelf();
(new CreatureAIFactory<PetAI>("PetAI"))->RegisterSelf();
(new CreatureAIFactory<TotemAI>("TotemAI"))->RegisterSelf();
diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp
index 9927ff34df3..9e53fe0f641 100644
--- a/src/game/CreatureAISelector.cpp
+++ b/src/game/CreatureAISelector.cpp
@@ -65,6 +65,8 @@ namespace FactorySelector
ai_factory = ai_registry.GetRegistryItem("TotemAI");
else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
+ else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER)
+ ai_factory = ai_registry.GetRegistryItem("CritterAI");
}
// select by permit check
@@ -91,7 +93,7 @@ namespace FactorySelector
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
- return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) );
+ return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) );
}
MovementGenerator* selectMovementGenerator(Creature *creature)
diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp
index 806b4a1a112..e5a7ce87092 100644
--- a/src/game/GuardAI.cpp
+++ b/src/game/GuardAI.cpp
@@ -33,7 +33,7 @@ int GuardAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-GuardAI::GuardAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
+GuardAI::GuardAI(Creature *c) : i_creature(*c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
{
}
diff --git a/src/game/GuardAI.h b/src/game/GuardAI.h
index 07a638ea17a..16e0c6e8bd6 100644
--- a/src/game/GuardAI.h
+++ b/src/game/GuardAI.h
@@ -36,7 +36,7 @@ class TRINITY_DLL_DECL GuardAI : public CreatureAI
public:
- GuardAI(Creature &c);
+ GuardAI(Creature *c);
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index fde30daebd2..88be4f6f2d5 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -513,6 +513,7 @@ bool ChatHandler::HandleReloadAllSpellCommand(const char*)
HandleReloadSpellElixirCommand("a");
HandleReloadSpellLearnSpellCommand("a");
HandleReloadSpellProcEventCommand("a");
+ HandleReloadSpellBonusesCommand("a");
HandleReloadSpellScriptTargetCommand("a");
HandleReloadSpellTargetPositionCommand("a");
HandleReloadSpellThreatsCommand("a");
@@ -837,6 +838,14 @@ bool ChatHandler::HandleReloadSpellProcEventCommand(const char*)
return true;
}
+bool ChatHandler::HandleReloadSpellBonusesCommand(const char*)
+{
+ sLog.outString( "Re-Loading Spell Bonus Data..." );
+ spellmgr.LoadSpellBonusess();
+ SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
+ return true;
+}
+
bool ChatHandler::HandleReloadSpellScriptTargetCommand(const char*)
{
sLog.outString( "Re-Loading SpellsScriptTarget..." );
diff --git a/src/game/NullCreatureAI.cpp b/src/game/NullCreatureAI.cpp
index 4c1cb592967..164aa2f7974 100644
--- a/src/game/NullCreatureAI.cpp
+++ b/src/game/NullCreatureAI.cpp
@@ -19,7 +19,23 @@
*/
#include "NullCreatureAI.h"
+#include "Creature.h"
-NullCreatureAI::~NullCreatureAI()
+void PassiveAI::UpdateAI(const uint32)
{
+ if(me->isInCombat() && me->getAttackers().empty())
+ EnterEvadeMode();
+}
+
+void CritterAI::DamageTaken(Unit *done_by, uint32 &)
+{
+ if(!me->hasUnitState(UNIT_STAT_FLEEING))
+ me->SetControlled(true, UNIT_STAT_FLEEING);
+}
+
+void CritterAI::EnterEvadeMode()
+{
+ if(me->hasUnitState(UNIT_STAT_FLEEING))
+ me->SetControlled(false, UNIT_STAT_FLEEING);
+ CreatureAI::EnterEvadeMode();
}
diff --git a/src/game/NullCreatureAI.h b/src/game/NullCreatureAI.h
index 3a93805fae2..821b42f7e76 100644
--- a/src/game/NullCreatureAI.h
+++ b/src/game/NullCreatureAI.h
@@ -23,22 +23,36 @@
#include "CreatureAI.h"
-class TRINITY_DLL_DECL NullCreatureAI : public CreatureAI
+class TRINITY_DLL_DECL PassiveAI : public CreatureAI
{
public:
-
- NullCreatureAI(Creature &) {}
- NullCreatureAI() {}
-
- ~NullCreatureAI();
+ PassiveAI(Creature *c) : CreatureAI(c) {}
+ ~PassiveAI() {}
void MoveInLineOfSight(Unit *) {}
void AttackStart(Unit *) {}
- void EnterEvadeMode() {}
bool IsVisible(Unit *) const { return false; }
- void UpdateAI(const uint32) {}
+ void UpdateAI(const uint32);
static int Permissible(const Creature *) { return PERMIT_BASE_IDLE; }
};
+
+class TRINITY_DLL_DECL NullCreatureAI : public PassiveAI
+{
+ public:
+ NullCreatureAI(Creature *c) : PassiveAI(c) {}
+
+ void EnterEvadeMode() {}
+};
+
+class TRINITY_DLL_DECL CritterAI : public PassiveAI
+{
+ public:
+ CritterAI(Creature *c) : PassiveAI(c) {}
+
+ void DamageTaken(Unit *done_by, uint32 & /*damage*/);
+ void EnterEvadeMode();
+};
+
#endif
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 5c46ba93a5a..caaadd1851f 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -1187,6 +1187,14 @@ float WorldObject::GetDistance(const float x, const float y, const float z) cons
return ( dist > 0 ? dist : 0);
}
+float WorldObject::GetDistanceSq(const float &x, const float &y, const float &z) const
+{
+ float dx = GetPositionX() - x;
+ float dy = GetPositionY() - y;
+ float dz = GetPositionZ() - z;
+ return dx*dx + dy*dy + dz*dz;
+}
+
float WorldObject::GetDistance2d(const WorldObject* obj) const
{
float dx = GetPositionX() - obj->GetPositionX();
diff --git a/src/game/Object.h b/src/game/Object.h
index 7db10b1d78d..0399f7313be 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -437,6 +437,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
float GetDistance( const WorldObject* obj ) const;
float GetDistance(const float x, const float y, const float z) const;
+ float GetDistanceSq(const float &x, const float &y, const float &z) const;
float GetDistance2d(const WorldObject* obj) const;
float GetDistance2d(const float x, const float y) const;
float GetDistanceZ(const WorldObject* obj) const;
diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp
index 1891dc0396d..3fe28a4bfb0 100644
--- a/src/game/ObjectAccessor.cpp
+++ b/src/game/ObjectAccessor.cpp
@@ -176,7 +176,7 @@ ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid)
if(!ret)
return NULL;
if(ret->GetMapId() != u.GetMapId())
- ret = NULL;
+ return NULL;
if(ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
@@ -226,7 +226,7 @@ ObjectAccessor::GetGameObject(WorldObject const &u, uint64 guid)
if(!ret)
return NULL;
if(ret->GetMapId() != u.GetMapId())
- ret = NULL;
+ return NULL;
if(ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
@@ -239,7 +239,7 @@ ObjectAccessor::GetDynamicObject(WorldObject const &u, uint64 guid)
if(!ret)
return NULL;
if(ret->GetMapId() != u.GetMapId())
- ret = NULL;
+ return NULL;
if(ret->GetInstanceId() != u.GetInstanceId())
return NULL;
return ret;
diff --git a/src/game/OutdoorPvPObjectiveAI.cpp b/src/game/OutdoorPvPObjectiveAI.cpp
index e27c583eb25..a99afbfbe5a 100644
--- a/src/game/OutdoorPvPObjectiveAI.cpp
+++ b/src/game/OutdoorPvPObjectiveAI.cpp
@@ -25,10 +25,10 @@
#define MAX_OUTDOOR_PVP_DISTANCE 200 // the max value in capture point type go data0 is 100 currently, so use twice that much to handle leaving as well
-OutdoorPvPObjectiveAI::OutdoorPvPObjectiveAI(Creature &c) : i_creature(c)
+OutdoorPvPObjectiveAI::OutdoorPvPObjectiveAI(Creature *c) : i_creature(*c)
{
- sLog.outDebug("OutdoorPvP objective AI assigned to creature guid %u", c.GetGUIDLow());
- c.SetReactState(REACT_AGGRESSIVE);
+ sLog.outDebug("OutdoorPvP objective AI assigned to creature guid %u", i_creature.GetGUIDLow());
+ i_creature.SetReactState(REACT_AGGRESSIVE);
}
void OutdoorPvPObjectiveAI::MoveInLineOfSight(Unit *u)
diff --git a/src/game/OutdoorPvPObjectiveAI.h b/src/game/OutdoorPvPObjectiveAI.h
index 19302a31305..2da9086dbd3 100644
--- a/src/game/OutdoorPvPObjectiveAI.h
+++ b/src/game/OutdoorPvPObjectiveAI.h
@@ -27,7 +27,7 @@ class TRINITY_DLL_DECL OutdoorPvPObjectiveAI : public CreatureAI
{
public:
- OutdoorPvPObjectiveAI(Creature &c);
+ OutdoorPvPObjectiveAI(Creature *c);
void MoveInLineOfSight(Unit *);
bool IsVisible(Unit *) const;
diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp
index 1d4fbfba8e2..0a93bea158d 100644
--- a/src/game/PetAI.cpp
+++ b/src/game/PetAI.cpp
@@ -38,7 +38,7 @@ int PetAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-PetAI::PetAI(Creature &c) : i_pet(c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false)
+PetAI::PetAI(Creature *c) : i_pet(*c), i_tracker(TIME_INTERVAL_LOOK), inCombat(false)
{
m_AllySet.clear();
UpdateAllies();
@@ -339,10 +339,10 @@ void PetAI::UpdateAllies()
m_AllySet.insert(owner->GetGUID());
}
-void PetAI::AttackedBy(Unit *attacker)
+/*void PetAI::AttackedBy(Unit *attacker)
{
//when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
(!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.IsWithinMeleeRange(attacker)))
AttackStart(attacker);
-}
+}*/
diff --git a/src/game/PetAI.h b/src/game/PetAI.h
index 33118dabdcb..8583404b669 100644
--- a/src/game/PetAI.h
+++ b/src/game/PetAI.h
@@ -31,13 +31,11 @@ class TRINITY_DLL_DECL PetAI : public CreatureAI
{
public:
- PetAI(Creature &c);
+ PetAI(Creature *c);
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
void EnterEvadeMode();
- void DamageTaken(Unit *done_by, uint32& /*damage*/) { AttackedBy(done_by); }
- void AttackedBy(Unit*);
bool IsVisible(Unit *) const;
void JustDied(Unit* who) { _stopAttack(); }
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 8e7c4762270..7bf2deff3e8 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -19453,20 +19453,24 @@ void Player::UpdateZoneDependentAuras( uint32 newZone )
}
// Some spells applied at enter into zone (with subzones)
- // Human Illusion
- // NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
- if ( newZone == 2367 ) // Old Hillsbrad Foothills
- {
- uint32 spellid = 0;
- // all horde races
- if( GetTeam() == HORDE )
- spellid = getGender() == GENDER_FEMALE ? 35481 : 35480;
- // and some alliance races
- else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI )
- spellid = getGender() == GENDER_FEMALE ? 35483 : 35482;
-
- if(spellid && !HasAura(spellid,0) )
- CastSpell(this,spellid,true);
+ switch(newZone)
+ {
+ case 2367: // Old Hillsbrad Foothills
+ {
+ // Human Illusion
+ // NOTE: these are removed by RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP);
+ uint32 spellid = 0;
+ // all horde races
+ if( GetTeam() == HORDE )
+ spellid = getGender() == GENDER_FEMALE ? 35481 : 35480;
+ // and some alliance races
+ else if( getRace() == RACE_NIGHTELF || getRace() == RACE_DRAENEI )
+ spellid = getGender() == GENDER_FEMALE ? 35483 : 35482;
+
+ if(spellid && !HasAura(spellid,0) )
+ CastSpell(this,spellid,true);
+ break;
+ }
}
}
@@ -20185,11 +20189,11 @@ bool Player::IsAllowUseFlyMountsHere() const
{
case 0:
case 1:
- if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_AZEROTH))
+ //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_AZEROTH))
return false;
break;
case 530:
- if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OUTLAND))
+ //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OUTLAND))
return false;
break;
case 571:
@@ -20197,7 +20201,7 @@ bool Player::IsAllowUseFlyMountsHere() const
return false;
break;
default:
- if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OTHERS))
+ //if (!sWorld.getConfig(CONFIG_FLYING_MOUNTS_OTHERS))
return false;
break;
}
diff --git a/src/game/PossessedAI.h b/src/game/PossessedAI.h
index c33da2c3595..16c3172b6bf 100644
--- a/src/game/PossessedAI.h
+++ b/src/game/PossessedAI.h
@@ -28,7 +28,7 @@ class Creature;
class TRINITY_DLL_DECL PossessedAI : public CreatureAI
{
public:
- PossessedAI(Creature &c) : i_pet(c), i_victimGuid(0) {}
+ PossessedAI(Creature *c) : i_pet(*c), i_victimGuid(0) {}
// Possessed creatures shouldn't aggro by themselves
void MoveInLineOfSight(Unit *) {}
@@ -36,7 +36,6 @@ class TRINITY_DLL_DECL PossessedAI : public CreatureAI
void EnterEvadeMode() {}
void JustDied(Unit*);
void KilledUnit(Unit* victim);
- void AttackedBy(Unit*) {}
bool IsVisible(Unit * u) const { return _isVisible(u); }
void UpdateAI(const uint32);
diff --git a/src/game/ReactorAI.h b/src/game/ReactorAI.h
index c71c48d0985..b2bfa3501c2 100644
--- a/src/game/ReactorAI.h
+++ b/src/game/ReactorAI.h
@@ -29,7 +29,7 @@ class TRINITY_DLL_DECL ReactorAI : public CreatureAI
{
public:
- ReactorAI(Creature &c) : i_creature(c), i_victimGuid(0) {}
+ ReactorAI(Creature *c) : i_creature(*c), i_victimGuid(0) {}
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 720c4898a70..51f6f1488fe 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -285,7 +285,7 @@ enum SpellCategory
#define SPELL_ATTR_EX2_UNK0 0x00000001 // 0
#define SPELL_ATTR_EX2_UNK1 0x00000002 // 1
-#define SPELL_ATTR_EX2_UNK2 0x00000004 // 2 boss spells?
+#define SPELL_ATTR_EX2_CANT_REFLECTED 0x00000004 // 2 ? used for detect can or not spell reflected
#define SPELL_ATTR_EX2_UNK3 0x00000008 // 3
#define SPELL_ATTR_EX2_UNK4 0x00000010 // 4
#define SPELL_ATTR_EX2_AUTOREPEAT_FLAG 0x00000020 // 5
@@ -711,7 +711,7 @@ enum AuraState
AURA_STATE_IMMOLATE = 14, // T |
AURA_STATE_SWIFTMEND = 15, // T |
AURA_STATE_DEADLY_POISON = 16, // T |
- //AURA_STATE_UNKNOWN17 = 17, // C |
+ AURA_STATE_ENRAGE = 17, // C |
//AURA_STATE_UNKNOWN18 = 18, // C t|
//AURA_STATE_UNKNOWN19 = 19, // | not used
//AURA_STATE_UNKNOWN20 = 20, // c | only (45317 Suicide)
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index e7e009bafab..852c7943612 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -378,7 +378,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
// determine reflection
m_canReflect = false;
- if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && (m_spellInfo->AttributesEx2 & 0x4)==0)
+ if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED))
{
for(int j=0;j<3;j++)
{
@@ -1323,7 +1323,7 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const uint32 &type, SpellTargets TargetType, uint32 entry)
{
- float x, y;
+ float x, y, z;
if(type == PUSH_DEST_CENTER)
{
if(!m_targets.HasDest())
@@ -1333,11 +1333,7 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const u
}
x = m_targets.m_destX;
y = m_targets.m_destY;
- }
- else if(type == PUSH_SELF_CENTER)
- {
- x = m_caster->GetPositionX();
- y = m_caster->GetPositionY();
+ z = m_targets.m_destZ;
}
else if(type == PUSH_TARGET_CENTER)
{
@@ -1349,9 +1345,16 @@ void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, const u
}
x = target->GetPositionX();
y = target->GetPositionY();
+ z = target->GetPositionZ();
+ }
+ else
+ {
+ x = m_caster->GetPositionX();
+ y = m_caster->GetPositionY();
+ z = m_caster->GetPositionZ();
}
- Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry);
+ Trinity::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, entry, x, y, z);
if((m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY)
|| TargetType == SPELL_TARGETS_ENTRY && !entry)
m_caster->GetMap()->VisitWorld(x, y, radius, notifier);
@@ -4469,15 +4472,16 @@ uint8 Spell::CheckCasterAuras() const
//Check whether the cast should be prevented by any state you might have.
uint8 prevented_reason = 0;
// Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
- if(!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED) && m_caster->HasAuraType(SPELL_AURA_MOD_STUN))
+ uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS); // Get unit state
+ if(unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
prevented_reason = SPELL_FAILED_STUNNED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
+ else if(unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
prevented_reason = SPELL_FAILED_CONFUSED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING) && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
+ else if(unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
prevented_reason = SPELL_FAILED_FLEEING;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
+ else if(unitflag & UNIT_FLAG_SILENCED && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
prevented_reason = SPELL_FAILED_SILENCED;
- else if(m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
+ else if(unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
prevented_reason = SPELL_FAILED_PACIFIED;
// Attr must make flag drop spell totally immune from all effects
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 2aa6051a654..c5e3841c0f1 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -106,7 +106,6 @@ enum SpellNotifyPushType
PUSH_IN_FRONT,
PUSH_IN_BACK,
PUSH_IN_LINE,
- PUSH_SELF_CENTER,
PUSH_DEST_CENTER,
PUSH_TARGET_CENTER,
};
@@ -621,14 +620,16 @@ namespace Trinity
std::list<Unit*> *i_data;
Spell &i_spell;
const uint32& i_push_type;
- float i_radius;
+ float i_radius, i_radiusSq;
SpellTargets i_TargetType;
Unit* i_caster;
uint32 i_entry;
+ float i_x, i_y, i_z;
SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, const uint32 &type,
- SpellTargets TargetType = SPELL_TARGETS_ENEMY, uint32 entry = 0)
- : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType), i_entry(entry)
+ SpellTargets TargetType = SPELL_TARGETS_ENEMY, uint32 entry = 0, float x = 0, float y = 0, float z = 0)
+ : i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_radiusSq(radius*radius)
+ , i_TargetType(TargetType), i_entry(entry), i_x(x), i_y(y), i_z(z)
{
i_caster = spell.GetCaster();
}
@@ -693,12 +694,8 @@ namespace Trinity
if(i_caster->isInLine((Unit*)(itr->getSource()), i_radius ))
i_data->push_back(itr->getSource());
break;
- case PUSH_SELF_CENTER:
- if(i_caster->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius))
- i_data->push_back(itr->getSource());
- break;
- case PUSH_DEST_CENTER:
- if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius ))
+ default:
+ if((itr->getSource()->GetDistanceSq(i_x, i_y, i_z) < i_radiusSq))
i_data->push_back(itr->getSource());
break;
}
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index eb23306b5b1..81339b038b5 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -90,9 +90,9 @@ enum AuraType
SPELL_AURA_PROC_TRIGGER_DAMAGE = 43,
SPELL_AURA_TRACK_CREATURES = 44,
SPELL_AURA_TRACK_RESOURCES = 45,
- SPELL_AURA_MOD_PARRY_SKILL = 46,
+ SPELL_AURA_46 = 46, // Ignore all Gear test spells
SPELL_AURA_MOD_PARRY_PERCENT = 47,
- SPELL_AURA_MOD_DODGE_SKILL = 48,
+ SPELL_AURA_48 = 48, // One periodic spell
SPELL_AURA_MOD_DODGE_PERCENT = 49,
SPELL_AURA_MOD_CRITICAL_HEALING_BONUS = 50,
SPELL_AURA_MOD_BLOCK_PERCENT = 51,
@@ -109,7 +109,7 @@ enum AuraType
SPELL_AURA_PERIODIC_HEALTH_FUNNEL = 62,
SPELL_AURA_PERIODIC_MANA_FUNNEL = 63,
SPELL_AURA_PERIODIC_MANA_LEECH = 64,
- SPELL_AURA_MOD_CASTING_SPEED = 65,
+ SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK = 65,
SPELL_AURA_FEIGN_DEATH = 66,
SPELL_AURA_MOD_DISARM = 67,
SPELL_AURA_MOD_STALKED = 68,
@@ -305,7 +305,7 @@ enum AuraType
SPELL_AURA_258 = 258,
SPELL_AURA_259 = 259,
SPELL_AURA_SCREEN_EFFECT = 260,
- SPELL_AURA_261 = 261,
+ SPELL_AURA_PHASE = 261,
SPELL_AURA_262 = 262,
SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
SPELL_AURA_264 = 264,
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 8af4f59124f..fdb8fe316f5 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -100,9 +100,9 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
&Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
&Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
- &Aura::HandleUnused, // 46 SPELL_AURA_MOD_PARRY_SKILL obsolete?
+ &Aura::HandleUnused, // 46 SPELL_AURA_46
&Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
- &Aura::HandleUnused, // 48 SPELL_AURA_MOD_DODGE_SKILL obsolete?
+ &Aura::HandleUnused, // 48 SPELL_AURA_48
&Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
&Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_BONUS
&Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
@@ -119,7 +119,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
&Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete?
&Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
- &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED
+ &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
&Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
&Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
&Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
@@ -315,9 +315,9 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
&Aura::HandleNULL, //259 corrupt healing over time spell
&Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
- &Aura::HandleNULL, //261 out of phase?
+ &Aura::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
&Aura::HandleNULL, //262
- &Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilites set in SpellClassMask
+ &Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
&Aura::HandleNULL, //264 unused
&Aura::HandleNULL, //265 unused
&Aura::HandleNULL, //266 unused
@@ -440,8 +440,10 @@ m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false)
if(modOwner)
modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
- m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
- !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
+ 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));
}
Aura::~Aura()
@@ -858,6 +860,10 @@ void Aura::_AddAura()
// Deadly poison aura state
if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags & 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);
}
}
}
@@ -927,6 +933,10 @@ void Aura::_RemoveAura()
//*****************************************************
// 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;
switch(m_spellProto->SpellFamilyName)
{
@@ -1975,7 +1985,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
{
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
return;
}
}
@@ -2173,7 +2183,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
if ( caster )
// prevent double apply bonuses
if(m_target->GetTypeId()!=TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading())
- m_modifier.m_amount = caster->SpellHealingBonus(GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE, m_target);
+ m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE);
}
else
{
@@ -2847,6 +2857,9 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
//talent will remove the caster's aura->interrupt channel->remove victim aura
if(victim->GetHealth() > 0)
return;
+ // Item amount
+ if (m_modifier.m_amount <= 0)
+ return;
SpellEntry const *spellInfo = GetSpellProto();
if(spellInfo->EffectItemType[m_effIndex] == 0)
@@ -2857,16 +2870,22 @@ void Aura::HandleChannelDeathItem(bool apply, bool Real)
(victim->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
victim->GetTypeId()==TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
return;
+ //Adding items
+ uint32 noSpaceForCount = 0;
+ uint32 count = m_modifier.m_amount;
+
ItemPosCountVec dest;
- uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], 1 );
+ uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
if( msg != EQUIP_ERR_OK )
{
+ count-=noSpaceForCount;
((Player*)caster)->SendEquipError( msg, NULL, NULL );
- return;
+ if (count==0)
+ return;
}
Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
- ((Player*)caster)->SendNewItem(newitem, 1, true, false);
+ ((Player*)caster)->SendNewItem(newitem, count, true, false);
}
}
@@ -3694,9 +3713,8 @@ void Aura::HandleModMechanicImmunity(bool apply, bool Real)
next = iter;
++next;
SpellEntry const *spell = iter->second->GetSpellProto();
- if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) // spells unaffected by invulnerability
- && !iter->second->IsPositive() // only remove negative spells
- && spell->Id != GetId())
+ if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) && // spells unaffected by invulnerability
+ spell->Id != GetId())
{
//check for mechanic mask
if(GetSpellMechanicMask(spell, iter->second->GetEffIndex()) & mechanic)
@@ -4122,29 +4140,6 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
}
break;
}
- case SPELLFAMILY_PALADIN:
- {
- // Consecration
- if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
- {
- // ($m1+0.04*$SPH+0.04*$AP)
- float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
- caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
- m_modifier.m_amount += int32(0.04f*holy + 0.04f*ap);
- return;
- }
- // Seal of Vengeance 0.013*$SPH+0.025*$AP per tick (also can stack)
- if(m_spellProto->SpellFamilyFlags & 0x0000080000000000LL)
- {
- float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
- caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
- m_modifier.m_amount += int32((0.013f*holy + 0.025f*ap) * GetStackAmount());
- return;
- }
- break;
- }
default:
break;
}
@@ -5086,7 +5081,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
if(itr->second->state == PLAYERSPELL_REMOVED) continue;
if(itr->first==spellId || itr->first==spellId2) continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !(spellInfo->Attributes & ((1<<6) | (1<<7)))) continue;
+ if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
if (spellInfo->Stances & (1<<form))
m_target->CastSpell(m_target, itr->first, true, NULL, this);
}
@@ -5487,13 +5482,12 @@ void Aura::PeriodicTick()
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
-
- uint32 pdamage;
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetModifier()->m_amount > 0 ? GetModifier()->m_amount : 0;
if(m_modifier.m_auraname == SPELL_AURA_PERIODIC_DAMAGE)
{
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),amount,DOT);
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
// Calculate armor mitigation if it is a physical spell
// But not for bleed mechanic spells
@@ -5505,8 +5499,6 @@ void Aura::PeriodicTick()
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
// Curse of Agony damage-per-tick calculation
if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544)
{
@@ -5520,15 +5512,13 @@ void Aura::PeriodicTick()
}
}
else
- pdamage = uint32(m_target->GetMaxHealth()*amount/100);
+ pdamage = uint32(m_target->GetMaxHealth()*pdamage/100);
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pdamage *= GetStackAmount();
-
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
@@ -5583,8 +5573,9 @@ void Aura::PeriodicTick()
uint32 resist=0;
CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );
- uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
+ //uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetModifier()->m_amount > 0 ? GetModifier()->m_amount : 0;
+ pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
//Calculate armor mitigation if it is a physical spell
if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
@@ -5594,15 +5585,11 @@ void Aura::PeriodicTick()
pdamage = pdamageReductedArmor;
}
- //pdamage = pCaster->SpellDamageBonus(m_target,GetSpellProto(),pdamage,DOT);
-
//As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit
// Reduce dot damage from resilience for players
if (m_target->GetTypeId()==TYPEID_PLAYER)
pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage);
- pdamage *= GetStackAmount();
-
pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist);
if(m_target->GetHealth() < pdamage)
@@ -5640,7 +5627,7 @@ void Aura::PeriodicTick()
if(Player *modOwner = pCaster->GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
- uint32 heal = pCaster->SpellHealingBonus(spellProto, uint32(new_damage * multiplier), DOT, pCaster);
+ uint32 heal = pCaster->SpellHealingBonus(pCaster, spellProto, uint32(new_damage * multiplier), DOT, GetStackAmount());
int32 gain = pCaster->ModifyHealth(heal);
pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
@@ -5660,18 +5647,13 @@ void Aura::PeriodicTick()
return;
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
-
- uint32 pdamage;
+ //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 pdamage = GetModifier()->m_amount > 0 ? GetModifier()->m_amount : 0;
if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH)
- pdamage = uint32(m_target->GetMaxHealth() * amount/100);
+ pdamage = uint32(m_target->GetMaxHealth() * pdamage * GetStackAmount() / 100);
else
- pdamage = pCaster->SpellHealingBonus(GetSpellProto(), amount, DOT, m_target);
-
- pdamage *= GetStackAmount();
-
- //pdamage = pCaster->SpellHealingBonus(GetSpellProto(), pdamage, DOT, m_target);
+ pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount());
sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
@@ -6547,3 +6529,24 @@ void Aura::HandleModCharm(bool apply, bool Real)
else
m_target->RemoveCharmedOrPossessedBy(caster);
}
+
+void Aura::HandlePhase(bool apply, bool Real)
+{
+ // no-phase is also phase state so same code for apply and remove
+
+ // phase auras normaly not expected at BG but anyway better check
+ if(Real && m_target->GetTypeId()==TYPEID_PLAYER)
+ {
+ // drop flag at invisible in bg
+ if(((Player*)m_target)->InBattleGround())
+ if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
+ bg->EventPlayerDroppedFlag((Player*)m_target);
+ }
+
+ // apply/remove only if not in GM invisibility
+ if(m_target->GetVisibility()!=VISIBILITY_OFF)
+ {
+ // just need triggering visibility update base at aura presence
+ m_target->SetVisibility(m_target->GetVisibility());
+ }
+}
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 4cbb531ea6d..3822d2abf86 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -211,6 +211,7 @@ class TRINITY_DLL_SPEC Aura
void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
void HandleNoReagentUseAura(bool Apply, bool Real);
void HandleModAttackerSpellHitChance(bool apply, bool Real);
+ void HandlePhase(bool Apply, bool Real);
virtual ~Aura();
@@ -273,7 +274,7 @@ class TRINITY_DLL_SPEC Aura
void SendAuraUpdate(bool remove);
int8 GetStackAmount() {return m_stackAmount;}
- int32 GetModifierValuePerStack() {return m_modifier.m_amount / m_stackAmount;}
+ //int32 GetModifierValuePerStack() {return m_modifier.m_amount / m_stackAmount;}
void SetStackAmount(uint8 num);
bool modStackAmount(int32 num); // return true if last charge dropped
void RefreshAura();
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 107265d9432..114458db6b9 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -623,7 +623,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if(stacks)
damage += damage * stacks * 10 /100;
}
- // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP)
+ // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) - ranged sdb for future
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL)
{
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
@@ -631,15 +631,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
damage += int32(ap * 0.07f) + int32(holy * 7 / 100);
}
- // Exorcism ($m1+0.15*$SPH+0.15*$AP)
- else if(m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL)
- {
- float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
- m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
- damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
- }
- // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP)
+ // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) - ranged type sdb future fix
else if(m_spellInfo->SpellFamilyFlags & 0x0000008000000000LL)
{
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
@@ -647,14 +639,6 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
}
- // Holy Wrath ($m1+0.07*$SPH+0.07*$AP)
- else if(m_spellInfo->SpellFamilyFlags & 0x0020000000000000LL)
- {
- float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
- m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
- damage += int32(ap * 0.15f) + int32(holy * 15 / 100);
- }
break;
}
}
@@ -2484,12 +2468,12 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
idx++;
}
- int32 tickheal = targetAura->GetModifierValuePerStack();
+ int32 tickheal = targetAura->GetModifier()->m_amount;
if(Unit* auraCaster = targetAura->GetCaster())
- tickheal = auraCaster->SpellHealingBonus(targetAura->GetSpellProto(), tickheal, DOT, unitTarget);
+ tickheal = auraCaster->SpellHealingBonus(unitTarget, targetAura->GetSpellProto(), tickheal, DOT);
//int32 tickheal = targetAura->GetSpellProto()->EffectBasePoints[idx] + 1;
//It is said that talent bonus should not be included
- //int32 tickheal = targetAura->GetModifier()->m_amount;
+
int32 tickcount = GetSpellDuration(targetAura->GetSpellProto()) / targetAura->GetSpellProto()->EffectAmplitude[idx];
addhealth += tickheal * tickcount;
unitTarget->RemoveAurasDueToCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID());
@@ -2498,7 +2482,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
//addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
}
else
- addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);
+ addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
m_damage -= addhealth;
}
@@ -2539,7 +2523,7 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )
if (!caster)
return;
- uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget);
+ uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL);
caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);
unitTarget->ModifyHealth( int32(damage) );
}
@@ -2570,7 +2554,7 @@ void Spell::EffectHealthLeech(uint32 i)
if(m_caster->isAlive())
{
- new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster);
+ new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL);
m_caster->ModifyHealth(new_damage);
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 0e7fe1380f0..3172a47ca38 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -503,6 +503,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
case 37675: // Chaos Blast
case 41519: // Mark of Stormrage
case 34877: // Custodian of Time
+ case 34700:
return false;
}
@@ -1041,7 +1042,7 @@ void SpellMgr::LoadSpellProcEvents()
bar.step();
- uint16 entry = fields[0].GetUInt16();
+ uint32 entry = fields[0].GetUInt32();
const SpellEntry *spell = sSpellStore.LookupEntry(entry);
if (!spell)
@@ -1085,6 +1086,50 @@ void SpellMgr::LoadSpellProcEvents()
sLog.outString( ">> Loaded %u extra spell proc event conditions", count );
}
+void SpellMgr::LoadSpellBonusess()
+{
+ mSpellBonusMap.clear(); // need for reload case
+ uint32 count = 0;
+ // 0 1 2 3
+ QueryResult *result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus FROM spell_bonus_data");
+ if( !result )
+ {
+ barGoLink bar( 1 );
+ bar.step();
+ sLog.outString();
+ sLog.outString( ">> Loaded %u spell bonus data", count);
+ return;
+ }
+
+ barGoLink bar( result->GetRowCount() );
+ do
+ {
+ Field *fields = result->Fetch();
+ bar.step();
+ uint32 entry = fields[0].GetUInt32();
+
+ const SpellEntry *spell = sSpellStore.LookupEntry(entry);
+ if (!spell)
+ {
+ sLog.outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry);
+ continue;
+ }
+
+ SpellBonusEntry sbe;
+
+ sbe.direct_damage = fields[1].GetFloat();
+ sbe.dot_damage = fields[2].GetFloat();
+ sbe.ap_bonus = fields[3].GetFloat();
+
+ mSpellBonusMap[entry] = sbe;
+ } while( result->NextRow() );
+
+ delete result;
+
+ sLog.outString();
+ 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)
{
// No extra req need
@@ -2587,6 +2632,10 @@ uint8 GetSpellAllowedInLocationError(SpellEntry const *spellInfo,uint32 map_id,u
case 51721: // Dominion Over Acherus
case 54055: // Dominion Over Acherus
return area_id == 4281 || area_id == 4342 ? 0 : SPELL_FAILED_INCORRECT_AREA;
+ case 51852: // The Eye of Acherus
+ {
+ return map_id == 609 ? 0 : SPELL_FAILED_REQUIRES_AREA;
+ }
case 54119: // Mist of the Kvaldir
return area_id == 4028 || area_id == 4029 || area_id == 4106 || area_id == 4031 ? 0 : SPELL_FAILED_INCORRECT_AREA;
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 77ee39e2249..eb9ce0637dc 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -605,7 +605,15 @@ struct SpellProcEventEntry
uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_
};
+struct SpellBonusEntry
+{
+ float direct_damage;
+ float dot_damage;
+ float ap_bonus;
+};
+
typedef UNORDERED_MAP<uint32, SpellProcEventEntry> SpellProcEventMap;
+typedef UNORDERED_MAP<uint32, SpellBonusEntry> SpellBonusMap;
#define ELIXIR_BATTLE_MASK 0x1
#define ELIXIR_GUARDIAN_MASK 0x2
@@ -830,6 +838,23 @@ class SpellMgr
static bool IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active);
+ // Spell bonus data
+ SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const
+ {
+ // Lookup data
+ SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
+ if( itr != mSpellBonusMap.end( ) )
+ return &itr->second;
+ // Not found, try lookup for 1 spell rank if exist
+ if (uint32 rank_1 = GetFirstSpellInChain(spellId))
+ {
+ SpellBonusMap::const_iterator itr = mSpellBonusMap.find(rank_1);
+ if( itr != mSpellBonusMap.end( ) )
+ return &itr->second;
+ }
+ return NULL;
+ }
+
// Spell target coordinates
SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const
{
@@ -1041,6 +1066,7 @@ class SpellMgr
void LoadSpellAffects();
void LoadSpellElixirs();
void LoadSpellProcEvents();
+ void LoadSpellBonusess();
void LoadSpellTargetPositions();
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
@@ -1060,6 +1086,7 @@ class SpellMgr
SpellAffectMap mSpellAffectMap;
SpellElixirMap mSpellElixirs;
SpellProcEventMap mSpellProcEventMap;
+ SpellBonusMap mSpellBonusMap;
SkillLineAbilityMap mSkillLineAbilityMap;
SpellPetAuraMap mSpellPetAuraMap;
SpellCustomAttribute mSpellCustomAttr;
diff --git a/src/game/TotemAI.cpp b/src/game/TotemAI.cpp
index 7b99a8f0358..72a43cfc97b 100644
--- a/src/game/TotemAI.cpp
+++ b/src/game/TotemAI.cpp
@@ -40,7 +40,7 @@ TotemAI::Permissible(const Creature *creature)
return PERMIT_BASE_NO;
}
-TotemAI::TotemAI(Creature &c) : i_totem(static_cast<Totem&>(c)), i_victimGuid(0)
+TotemAI::TotemAI(Creature *c) : i_totem(static_cast<Totem&>(*c)), i_victimGuid(0)
{
}
diff --git a/src/game/TotemAI.h b/src/game/TotemAI.h
index 1b4f96e6067..8ce40e60c81 100644
--- a/src/game/TotemAI.h
+++ b/src/game/TotemAI.h
@@ -31,7 +31,7 @@ class TRINITY_DLL_DECL TotemAI : public CreatureAI
{
public:
- TotemAI(Creature &c);
+ TotemAI(Creature *c);
void MoveInLineOfSight(Unit *);
void AttackStart(Unit *);
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 7b5b9f09511..f47eb78bbf7 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -580,9 +580,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
// no xp,health if type 8 /critters/
if ( pVictim->GetCreatureType() == CREATURE_TYPE_CRITTER)
{
- // critters run away when hit
- pVictim->GetMotionMaster()->MoveFleeing(this);
-
// allow loot only if has loot_id in creature_template
if(damage >= pVictim->GetHealth())
{
@@ -841,13 +838,13 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(damagetype != DOT)
{
- if(getVictim())
- {
+ if(!getVictim())
+ /*{
// if have target and damage pVictim just call AI reaction
if(pVictim != getVictim() && pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->AI())
((Creature*)pVictim)->AI()->AttackedBy(this);
}
- else
+ else*/
{
// if not have main target then attack state with target (including AI call)
//start melee attacks only after melee hit
@@ -1755,6 +1752,9 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
// Get unit state (need for some absorb check)
uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS);
+ // Reflect damage spells (not cast any damage spell in aura lookup)
+ uint32 reflectSpell = 0;
+ int32 reflectDamage = 0;
// Need remove expired auras after
bool existExpired = false;
// absorb without mana cost
@@ -1810,12 +1810,11 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
// Reflective Shield (Lady Malande boss)
if (spellProto->Id == 41475)
{
- int32 reflectDamage = 0;
if(RemainingDamage < currentAbsorb)
reflectDamage = RemainingDamage / 2;
else
reflectDamage = currentAbsorb / 2;
- pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, *i);
+ reflectSpell = 33619;
break;
}
if (spellProto->Id == 39228 || // Argussian Compass
@@ -1884,14 +1883,10 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
reflectDamage = (*k)->GetModifier()->m_amount * currentAbsorb/100;
else
reflectDamage = (*k)->GetModifier()->m_amount * RemainingDamage/100;
+ reflectSpell = 33619;
} break;
default: break;
}
- if (reflectDamage)
- {
- pVictim->CastCustomSpell(this, 33619, &reflectDamage, NULL, NULL, true, NULL, *i);
- break;
- }
}
break;
}
@@ -1982,6 +1977,9 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
++i;
}
}
+ // Cast back reflect damage spell
+ if (reflectSpell)
+ pVictim->CastCustomSpell(this, reflectSpell, &reflectDamage, NULL, NULL, true);
// absorb by mana cost
AuraList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD);
@@ -4675,7 +4673,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
if(!target)
return false;
- basepoints0 = int32(damage * 2.5f); // manaregen
triggered_spell_id = 34650;
break;
}
@@ -5980,6 +5977,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
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;
}
@@ -6535,6 +6534,10 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
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;
@@ -7282,8 +7285,8 @@ bool Unit::Attack(Unit *victim, bool meleeAttack)
m_attacking = victim;
m_attacking->_addAttacker(this);
- if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI())
- ((Creature*)m_attacking)->AI()->AttackedBy(this);
+ //if(m_attacking->GetTypeId()==TYPEID_UNIT && ((Creature*)m_attacking)->AI())
+ // ((Creature*)m_attacking)->AI()->AttackedBy(this);
if(GetTypeId()==TYPEID_UNIT)
{
@@ -7402,51 +7405,7 @@ void Unit::RemoveAllAttackers()
void Unit::ModifyAuraState(AuraState flag, bool apply)
{
- if (apply)
- {
- if (!HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)))
- {
- SetFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
- if(GetTypeId() == TYPEID_PLAYER)
- {
- const PlayerSpellMap& sp_list = ((Player*)this)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !IsPassiveSpell(itr->first)) continue;
- if (spellInfo->CasterAuraState == flag)
- CastSpell(this, itr->first, true, NULL);
- }
- }
- }
- }
- else
- {
- if (HasFlag(UNIT_FIELD_AURASTATE,1<<(flag-1)))
- {
- RemoveFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1));
- Unit::AuraMap& tAuras = GetAuras();
- for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
- {
- SpellEntry const* spellProto = (*itr).second->GetSpellProto();
- if (spellProto->CasterAuraState == flag)
- {
- // exceptions (applied at state but not removed at state change)
- // Rampage
- if(spellProto->SpellIconID==2006 && spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && spellProto->SpellFamilyFlags==0x100000)
- {
- ++itr;
- continue;
- }
-
- RemoveAura(itr);
- }
- else
- ++itr;
- }
- }
- }
+ ApplyModFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1), apply);
}
Unit *Unit::GetOwner() const
@@ -7596,7 +7555,7 @@ void Unit::SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, Po
SendMessageToSet(&data, true);
}
-uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype)
+uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
return pdamage;
@@ -7611,8 +7570,8 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Taken/Done total percent damage auras
float DoneTotalMod = 1.0f;
float TakenTotalMod = 1.0f;
- uint32 DoneTotal = 0;
- uint32 TakenTotal = 0;
+ int32 DoneTotal = 0;
+ int32 TakenTotal = 0;
// ..done
// Pet damage
@@ -7799,107 +7758,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
}
}
- // ..taken
- AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
- if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
-
- // .. taken pct: dummy auras
- AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
- for(AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
- {
- switch((*i)->GetSpellProto()->SpellIconID)
- {
- //Cheat Death
- case 2109:
- if( ((*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto)) )
- {
- if(pVictim->GetTypeId() != TYPEID_PLAYER)
- continue;
- float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
- if (mod < (*i)->GetModifier()->m_amount)
- mod = (*i)->GetModifier()->m_amount;
- TakenTotalMod *= (mod+100.0f)/100.0f;
- }
- break;
- }
- }
-
- // From caster spells
- AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
- for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
- if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
-
- // Mod damage from spell mechanic
- uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
- if (mechanicMask)
- {
- AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
- for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
- if(mechanicMask & uint32(1<<((*i)->GetModifier()->m_miscvalue)))
- TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- }
-
- // Damage Done from spell damage bonus
- uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
-
- // Taken/Done fixed damage bonus auras
- int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
- int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
-
- // Pets just add their bonus damage to their spell damage
- // note that their spell damage is just gain of their own auras
- if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
- DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage();
-
- // Damage over Time spells bonus calculation
- float DotFactor = 1.0f;
- if(damagetype == DOT)
- {
- int32 DotDuration = GetSpellDuration(spellProto);
- // 200% limit
- if(DotDuration > 0)
- {
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
- }
- int DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- {
- DoneAdvertisedBenefit /= DotTicks;
- TakenAdvertisedBenefit /= DotTicks;
- }
- }
- }
- // Distribute Damage over multiple effects, reduce by AoE
- CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
-
- // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
- for(int j = 0; j < 3; ++j)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
- {
- CastingTime /= 2;
- break;
- }
- }
-
- switch(spellProto->SpellFamilyName)
+ /*switch(spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
// Siphon Essence - 0%
@@ -8090,51 +7949,143 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
{
CastingTime = 500;
}
- break;
- case SPELLFAMILY_DRUID:
- // Hurricane triggered spell
- if((spellProto->SpellFamilyFlags & 0x400000LL) && spellProto->SpellIconID == 220)
- {
- CastingTime = 500;
- }
- break;
- case SPELLFAMILY_WARRIOR:
- case SPELLFAMILY_HUNTER:
- case SPELLFAMILY_ROGUE:
- CastingTime = 0;
- break;
- default:
- break;
+ break;*/
+
+ // Custom scripted damage
+ // Ice Lance
+ if (spellProto->SpellFamilyName == SPELLFAMILY_MAGE && spellProto->SpellIconID == 186)
+ {
+ if (pVictim->isFrozen())
+ DoneTotalMod *= 3.0f;
}
- float LvlPenalty = CalculateLevelPenalty(spellProto);
+ // ..taken
+ AuraList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
+ for(AuraList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
+ if( (*i)->GetModifier()->m_miscvalue & GetSpellSchoolMask(spellProto) )
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- // Spellmod SpellDamage
- //float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = DotFactor * 100.0f;
- if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
- CoefficientPtc *= ((float)CastingTime/3500.0f);
+ // .. taken pct: dummy auras
+ if (pVictim->GetTypeId() == TYPEID_PLAYER)
+ {
+ //Cheat Death
+ if (Aura *dummy = pVictim->GetDummyAura(45182))
+ {
+ float mod = -((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2*4;
+ if (mod < dummy->GetModifier()->m_amount)
+ mod = dummy->GetModifier()->m_amount;
+ TakenTotalMod *= (mod+100.0f)/100.0f;
+ }
+ }
- if(Player* modOwner = GetSpellModOwner())
- //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,CoefficientPtc);
+ // From caster spells
+ AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
+ for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
+ if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
- //SpellModSpellDamage /= 100.0f;
- CoefficientPtc /= 100.0f;
+ // Mod damage from spell mechanic
+ uint32 mechanicMask = GetAllSpellMechanicMask(spellProto);
+ if (mechanicMask)
+ {
+ AuraList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
+ for(AuraList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
+ if(mechanicMask & uint32(1<<((*i)->GetModifier()->m_miscvalue)))
+ TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
+ }
- //float DoneActualBenefit = DoneAdvertisedBenefit * (CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty;
-
- float DoneActualBenefit = DoneAdvertisedBenefit * CoefficientPtc * LvlPenalty;
- float TakenActualBenefit = TakenAdvertisedBenefit * DotFactor * LvlPenalty;
- if(spellProto->SpellFamilyName && spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
- TakenActualBenefit *= ((float)CastingTime / 3500.0f);
+ // Taken/Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
+ int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
+ // Pets just add their bonus damage to their spell damage
+ // note that their spell damage is just gain of their own auras
+ if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isPet())
+ DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage();
- float tmpDamage = (float(pdamage)+DoneActualBenefit + DoneTotal)*DoneTotalMod;
+ // Check for table values
+ float coeff;
+ SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage;
+ else
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus)
+ DoneTotal+=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack;
+ }
+ // Default calculation
+ else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
+ {
+ // Damage Done from spell damage bonus
+ uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ int32 DotDuration = GetSpellDuration(spellProto);
+ // 200% limit
+ if(DotDuration > 0)
+ {
+ if(DotDuration > 30000) DotDuration = 30000;
+ if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
+ int x = 0;
+ for(int j = 0; j < 3; j++)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ x = j;
+ break;
+ }
+ }
+ int DotTicks = 6;
+ if(spellProto->EffectAmplitude[x] != 0)
+ DotTicks = DotDuration / spellProto->EffectAmplitude[x];
+ if(DotTicks)
+ {
+ DoneAdvertisedBenefit /= DotTicks;
+ TakenAdvertisedBenefit /= DotTicks;
+ }
+ }
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
+
+ // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
+ for(int j = 0; j < 3; ++j)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ {
+ CastingTime /= 2;
+ break;
+ }
+ }
+ if(spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
+ coeff = (CastingTime / 3500.0f) * DotFactor;
+ else
+ coeff = DotFactor;
+ }
+
+ float coeff2 = CalculateLevelPenalty(spellProto) * stack;
+ if(spellProto->SpellFamilyName) //TODO: fix this
+ TakenTotal+= TakenAdvertisedBenefit * coeff * coeff2;
+ if(Player* modOwner = GetSpellModOwner())
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, coeff);
+ coeff /= 100.0f;
+ }
+ DoneTotal += DoneAdvertisedBenefit * coeff * coeff2;
+
+ float tmpDamage = (pdamage + DoneTotal) * DoneTotalMod;
// apply spellmod to Done damage (flat and pct)
if(Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
- tmpDamage = (tmpDamage + TakenActualBenefit + TakenTotal)*TakenTotalMod;
+ tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod;
return tmpDamage > 0 ? uint32(tmpDamage) : 0;
}
@@ -8361,15 +8312,18 @@ uint32 Unit::SpellCriticalHealingBonus(SpellEntry const *spellProto, uint32 dama
return damage;
}
-uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim)
+uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
{
+ // No heal amount for this class spells
+ if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
+ return healamount;
+
// For totems get healing bonus from owner (statue isn't totem in fact)
if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem() && ((Totem*)this)->GetTotemType()!=TOTEM_STATUE)
if(Unit* owner = GetOwner())
- return owner->SpellHealingBonus(spellProto, healamount, damagetype, pVictim);
-
- // Healing Done
+ return owner->SpellHealingBonus(pVictim, spellProto, healamount, damagetype, stack);
+ // TODO: to be deleted
// These Spells are doing fixed amount of healing (TODO found less hack-like check)
if (spellProto->Id == 15290 || spellProto->Id == 39373 ||
spellProto->Id == 33778 || spellProto->Id == 379 ||
@@ -8378,11 +8332,12 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
spellProto->Id == 34299)
return healamount;
+ // Healing Done
// Taken/Done total percent damage auras
float DoneTotalMod = 1.0f;
float TakenTotalMod = 1.0f;
- uint32 DoneTotal = 0;
- uint32 TakenTotal = 0;
+ int32 DoneTotal = 0;
+ int32 TakenTotal = 0;
// Healing done percent
AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
@@ -8470,58 +8425,7 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
}
}
- int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
- int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
- if (DoneAdvertisedBenefit != 0 && TakenAdvertisedBenefit!=0)
- {
- // Healing over Time spells
- float DotFactor = 1.0f;
- if(damagetype == DOT)
- {
- int32 DotDuration = GetSpellDuration(spellProto);
- if(DotDuration > 0)
- {
- // 200% limit
- if(DotDuration > 30000) DotDuration = 30000;
- if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
- int x = 0;
- for(int j = 0; j < 3; j++)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL ||
- spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
- {
- x = j;
- break;
- }
- }
- int DotTicks = 6;
- if(spellProto->EffectAmplitude[x] != 0)
- DotTicks = DotDuration / spellProto->EffectAmplitude[x];
- if(DotTicks)
- {
- DoneAdvertisedBenefit /= DotTicks;
- TakenAdvertisedBenefit /= DotTicks;
- }
- }
- }
- uint32 CastingTime = GetSpellCastTime(spellProto);
-
- // distribute healing to all effects, reduce AoE damage
- CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
-
- // 0% bonus for damage and healing spells for leech spells from healing bonus
- for(int j = 0; j < 3; ++j)
- {
- if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
- spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
- {
- CastingTime = 0;
- break;
- }
- }
-
- // Exception
+ /*// Exception
switch (spellProto->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
@@ -8576,24 +8480,84 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
case SPELLFAMILY_HUNTER:
CastingTime = 0;
break;
- }
-
- float LvlPenalty = CalculateLevelPenalty(spellProto);
-
- // Spellmod SpellDamage
- //float SpellModSpellDamage = 100.0f;
- float CoefficientPtc = ((float)CastingTime/3500.0f)*DotFactor*100.0f;
+ }*/
- if(Player* modOwner = GetSpellModOwner())
- //modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,SpellModSpellDamage);
- modOwner->ApplySpellMod(spellProto->Id,SPELLMOD_SPELL_BONUS_DAMAGE,CoefficientPtc);
+ // Taken/Done fixed damage bonus auras
+ int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto));
+ int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
- //SpellModSpellDamage /= 100.0f;
- CoefficientPtc /= 100.0f;
+ // Check for table values
+ SpellBonusEntry const* bonus = spellmgr.GetSpellBonusData(spellProto->Id);
+ float coeff;
+ if (bonus)
+ {
+ if (damagetype == DOT)
+ coeff = bonus->dot_damage;
+ else
+ coeff = bonus->direct_damage;
+ if (bonus->ap_bonus)
+ DoneTotal+=bonus->ap_bonus * GetTotalAttackPowerValue(BASE_ATTACK) * stack;
+ }
+ // Default calculation
+ else if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
+ {
+ // Damage Done from spell damage bonus
+ uint32 CastingTime = !IsChanneledSpell(spellProto) ? GetSpellCastTime(spellProto) : GetSpellDuration(spellProto);
+ // Damage over Time spells bonus calculation
+ float DotFactor = 1.0f;
+ if(damagetype == DOT)
+ {
+ int32 DotDuration = GetSpellDuration(spellProto);
+ // 200% limit
+ if(DotDuration > 0)
+ {
+ if(DotDuration > 30000) DotDuration = 30000;
+ if(!IsChanneledSpell(spellProto)) DotFactor = DotDuration / 15000.0f;
+ int x = 0;
+ for(int j = 0; j < 3; j++)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && (
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||
+ spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH) )
+ {
+ x = j;
+ break;
+ }
+ }
+ int DotTicks = 6;
+ if(spellProto->EffectAmplitude[x] != 0)
+ DotTicks = DotDuration / spellProto->EffectAmplitude[x];
+ if(DotTicks)
+ {
+ DoneAdvertisedBenefit /= DotTicks;
+ TakenAdvertisedBenefit /= DotTicks;
+ }
+ }
+ }
+ // Distribute Damage over multiple effects, reduce by AoE
+ CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime );
+ // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
+ for(int j = 0; j < 3; ++j)
+ {
+ if( spellProto->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ||
+ spellProto->Effect[j] == SPELL_EFFECT_APPLY_AURA && spellProto->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH )
+ {
+ CastingTime /= 2;
+ break;
+ }
+ }
+ coeff = (CastingTime / 3500.0f) * DotFactor;
+ }
- DoneTotal += (float)DoneAdvertisedBenefit * CoefficientPtc * LvlPenalty;
- TakenTotal += (float)TakenAdvertisedBenefit * CoefficientPtc * LvlPenalty;
+ float coeff2 = CalculateLevelPenalty(spellProto) * 1.88f * stack;
+ TakenTotal+= TakenAdvertisedBenefit * coeff * coeff2;
+ if(Player* modOwner = GetSpellModOwner())
+ {
+ coeff *= 100.0f;
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_SPELL_BONUS_DAMAGE, coeff);
+ coeff /= 100.0f;
}
+ DoneTotal += DoneAdvertisedBenefit * coeff * coeff2;
// use float as more appropriate for negative values and percent applying
float heal = (healamount + DoneTotal)*DoneTotalMod;
@@ -8609,7 +8573,7 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,
Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr)
if((*itr)->GetId() == 29203)
- TakenTotalMod *= (*itr)->GetModifier()->m_amount;
+ TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f) / 100.0f;
}
// Healing taken percent
@@ -8859,8 +8823,8 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
TakenFlatBenefit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
// Done/Taken total percent damage auras
- float DoneTotalMod = 1;
- float TakenTotalMod = 1;
+ float DoneTotalMod = 1.0f;
+ float TakenTotalMod = 1.0f;
// ..done
// SPELL_AURA_MOD_DAMAGE_PERCENT_DONE included in weapon damage
@@ -9777,6 +9741,10 @@ Unit* Creature::SelectHostilTarget()
//next-victim-selection algorithm and evade mode are called
//threat list sorting etc.
+ //This should not be called by unit who does not have a threatlist
+ //or who does not have threat (totem/pet/critter)
+ //otherwise enterevademode every update
+
if (!this->isAlive())
return false;
@@ -9841,7 +9809,7 @@ Unit* Creature::SelectHostilTarget()
for(AttackerSet::const_iterator itr = m_attackers.begin(); itr != m_attackers.end(); ++itr)
{
if( (*itr)->IsInMap(this) && canAttack(*itr) && (*itr)->isInAccessiblePlaceFor((Creature*)this) )
- return false;
+ return NULL;
}
}*/
@@ -10754,7 +10722,7 @@ bool InitTriggerAuraData()
isTriggerAura[SPELL_AURA_DAMAGE_IMMUNITY] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL] = true;
isTriggerAura[SPELL_AURA_PROC_TRIGGER_DAMAGE] = true;
- isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED] = true;
+ isTriggerAura[SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK] = true;
isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT] = true;
isTriggerAura[SPELL_AURA_MOD_POWER_COST_SCHOOL] = true;
isTriggerAura[SPELL_AURA_REFLECT_SPELLS_SCHOOL] = true;
@@ -10998,7 +10966,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
continue;
break;
}
- case SPELL_AURA_MOD_CASTING_SPEED:
+ case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
// Skip melee hits or instant cast spells
if (procSpell == NULL || GetSpellCastTime(procSpell) == 0)
continue;
@@ -12133,6 +12101,8 @@ void Unit::SetFeared(bool apply)
Unit::AuraList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR);
if(!fearAuras.empty())
caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
+ if(!caster)
+ caster = getAttackerForHelper();
GetMotionMaster()->MoveFleeing(caster); // caster==NULL processed in MoveFleeing
}
else
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 990e1fe020b..cbb61eb3c32 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1351,8 +1351,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim);
- uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype);
- uint32 SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, Unit *pVictim);
+ uint32 SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1);
+ uint32 SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
bool isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAttackType attackType = BASE_ATTACK);
bool isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK);
uint32 SpellCriticalDamageBonus(SpellEntry const *spellProto, uint32 damage, Unit *pVictim);
diff --git a/src/game/World.cpp b/src/game/World.cpp
index 7170ab290e0..397a01ddd51 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -1161,6 +1161,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Spell Proc Event conditions..." );
spellmgr.LoadSpellProcEvents();
+ sLog.outString( "Loading Spell Bonus Data..." );
+ spellmgr.LoadSpellBonusess();
+
sLog.outString( "Loading Aggro Spells Definitions...");
spellmgr.LoadSpellThreats();
diff --git a/src/shared/revision.h b/src/shared/revision.h
index 1d590b1e7c0..e60dcfdb657 100644
--- a/src/shared/revision.h
+++ b/src/shared/revision.h
@@ -1,7 +1,7 @@
#ifndef __REVISION_H__
#define __REVISION_H__
- #define _REVISION "1091"
- #define _HASH "88c4b2b6b9a2"
+ #define _REVISION "1116"
+ #define _HASH "81edc7393bc6"
#define _REVISION_DATE "*"
#define _REVISION_TIME "*"
#endif // __REVISION_H__
diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h
index f2e3c0e71e0..d542e8dd61d 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 "7194"
+ #define REVISION_NR "7200"
#endif // __REVISION_NR_H__