aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/auth_database.sql3
-rw-r--r--sql/updates/auth/master/2020_05_19_00_auth.sql7
-rw-r--r--sql/updates/world/master/2020_06_14_00_world_2017_05_05_00_world.sql7
-rw-r--r--sql/updates/world/master/2020_06_14_01_world_2017_05_06_00_world.sql1
-rw-r--r--sql/updates/world/master/2020_06_14_02_world_2017_05_07_01_world.sql4
-rw-r--r--sql/updates/world/master/2020_06_14_03_world_2017_05_09_00_world.sql5
-rw-r--r--sql/updates/world/master/2020_06_14_04_world_2017_05_10_00_world.sql18
-rw-r--r--sql/updates/world/master/2020_06_14_05_world_2017_05_10_02_world.sql4
-rw-r--r--sql/updates/world/master/2020_06_14_06_world_2017_05_13_01_world.sql77
-rw-r--r--sql/updates/world/master/2020_06_14_07_world_2017_05_14_00_world_335.sql4
-rw-r--r--sql/updates/world/master/2020_06_14_08_world_2017_05_14_01_world.sql1
-rw-r--r--sql/updates/world/master/2020_06_14_09_world_2017_05_16_01_world.sql210
-rw-r--r--sql/updates/world/master/2020_06_14_10_world_2017_05_24_00_world.sql2
-rw-r--r--sql/updates/world/master/2020_06_14_11_world_2017_05_17_00_world.sql2
-rw-r--r--sql/updates/world/master/2020_06_14_12_world_2017_05_22_00_world.sql25
-rw-r--r--sql/updates/world/master/2020_06_14_13_world_2017_05_23_00_world.sql2
-rw-r--r--sql/updates/world/master/2020_06_14_14_world_2017_05_25_00_world.sql7
-rw-r--r--sql/updates/world/master/2020_06_14_15_world_2017_05_24_01_world.sql9
-rw-r--r--sql/updates/world/master/2020_06_14_16_world_2017_05_25_01_world.sql1
-rw-r--r--sql/updates/world/master/2020_06_14_17_world_2017_05_28_05_world.sql37
-rw-r--r--sql/updates/world/master/2020_06_14_18_world_2017_05_29_00_world.sql3
-rw-r--r--sql/updates/world/master/2020_06_14_19_world_2017_05_28_00_world.sql2
-rw-r--r--sql/updates/world/master/2020_06_14_20_world_2017_05_28_01_world.sql4
-rw-r--r--sql/updates/world/master/2020_06_14_21_world_2017_05_28_03_world.sql2
-rw-r--r--sql/updates/world/master/2020_06_14_22_world_2017_06_02_00_world.sql2
-rw-r--r--sql/updates/world/master/2020_06_14_23_world_2017_06_02_01_world.sql3
-rw-r--r--sql/updates/world/master/2020_06_14_24_world_2017_06_02_02_world.sql7
-rw-r--r--sql/updates/world/master/2020_06_14_25_world_2017_06_03_00_world.sql2
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.cpp12
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.h10
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.cpp7
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h4
-rw-r--r--src/server/game/AI/CoreAI/GuardAI.cpp4
-rw-r--r--src/server/game/AI/CoreAI/GuardAI.h2
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.cpp27
-rw-r--r--src/server/game/AI/CoreAI/PassiveAI.h10
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp10
-rw-r--r--src/server/game/AI/CoreAI/PetAI.h2
-rw-r--r--src/server/game/AI/CoreAI/ReactorAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/ReactorAI.h2
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.h2
-rw-r--r--src/server/game/AI/CreatureAI.h2
-rw-r--r--src/server/game/AI/CreatureAIFactory.h60
-rw-r--r--src/server/game/AI/CreatureAIRegistry.cpp9
-rw-r--r--src/server/game/AI/CreatureAISelector.cpp160
-rw-r--r--src/server/game/AI/CreatureAISelector.h7
-rw-r--r--src/server/game/AI/GameObjectAIFactory.h54
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedGossip.cpp1
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedGossip.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp29
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h16
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp8
-rw-r--r--src/server/game/Accounts/RBAC.h23
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.cpp2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp53
-rw-r--r--src/server/game/Entities/Creature/Creature.h5
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp9
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp68
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp59
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp19
-rw-r--r--src/server/game/Groups/GroupMgr.cpp13
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h45
-rw-r--r--src/server/game/Movement/MotionMaster.cpp19
-rw-r--r--src/server/game/Movement/MovementGenerator.cpp7
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h24
-rw-r--r--src/server/game/Movement/MovementGeneratorImpl.h29
-rw-r--r--src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/IdleMovementGenerator.h2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp5
-rw-r--r--src/server/game/Scripting/ScriptSystem.h24
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp12
-rw-r--r--src/server/game/Spells/Spell.cpp15
-rw-r--r--src/server/game/Spells/SpellEffects.cpp13
-rw-r--r--src/server/game/Spells/SpellInfo.cpp29
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rw-r--r--src/server/game/Spells/SpellMgr.cpp8
-rw-r--r--src/server/game/World/World.cpp6
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp66
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp44
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp11
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp28
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp5
-rw-r--r--src/server/scripts/EasternKingdoms/zone_ghostlands.cpp5
-rw-r--r--src/server/scripts/EasternKingdoms/zone_hinterlands.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/zone_undercity.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/zone_wetlands.cpp1
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp4
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp4
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp4
-rw-r--r--src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp4
-rw-r--r--src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp2
-rw-r--r--src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp2
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp4
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp4
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp10
-rw-r--r--src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp2
-rw-r--r--src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp7
-rw-r--r--src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp13
-rw-r--r--src/server/scripts/Kalimdor/zone_ashenvale.cpp5
-rw-r--r--src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp8
-rw-r--r--src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp3
-rw-r--r--src/server/scripts/Kalimdor/zone_silithus.cpp9
-rw-r--r--src/server/scripts/Kalimdor/zone_tanaris.cpp6
-rw-r--r--src/server/scripts/Kalimdor/zone_the_barrens.cpp5
-rw-r--r--src/server/scripts/Kalimdor/zone_winterspring.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp4
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp5
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp102
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp15
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp22
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp2117
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp61
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h76
-rw-r--r--src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp2
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp9
-rw-r--r--src/server/scripts/Northrend/northrend_script_loader.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_borean_tundra.cpp13
-rw-r--r--src/server/scripts/Northrend/zone_dragonblight.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp4
-rw-r--r--src/server/scripts/Northrend/zone_howling_fjord.cpp3
-rw-r--r--src/server/scripts/Northrend/zone_icecrown.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_sholazar_basin.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_storm_peaks.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_zuldrak.cpp2
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp2
-rw-r--r--src/server/scripts/Outland/BlackTemple/black_temple.h1
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp5
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp10
-rw-r--r--src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp6
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp6
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp2
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp4
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp2
-rw-r--r--src/server/scripts/Outland/zone_hellfire_peninsula.cpp10
-rw-r--r--src/server/scripts/Outland/zone_nagrand.cpp4
-rw-r--r--src/server/scripts/Outland/zone_netherstorm.cpp4
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp21
-rw-r--r--src/server/scripts/Outland/zone_shattrath_city.cpp7
-rw-r--r--src/server/scripts/Outland/zone_terokkar_forest.cpp14
-rw-r--r--src/server/scripts/Outland/zone_zangarmarsh.cpp5
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp41
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp2
-rw-r--r--src/server/scripts/World/npcs_special.cpp4
-rw-r--r--src/server/shared/Dynamic/FactoryHolder.h16
-rw-r--r--src/server/shared/Dynamic/ObjectRegistry.h69
188 files changed, 3585 insertions, 907 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 5ebb0a579eb..da0258f519b 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -1267,6 +1267,7 @@ INSERT INTO `rbac_linked_permissions` VALUES
(198,316),
(198,317),
(198,318),
+(198,855),
(198,367),
(198,368),
(198,369),
@@ -2084,6 +2085,7 @@ INSERT INTO `rbac_permissions` VALUES
(852,'Command: go offset'),
(853,'Command: .reload conversation_template'),
(854,'Command: .debug conversation'),
+(855,'Command: debug play music'),
(868,'Command: modify power'),
(869,'Command: debug send playerchoice'),
(872,'Command: server debug');
@@ -2331,6 +2333,7 @@ INSERT INTO `updates` VALUES
('2020_03_31_00_auth.sql','BA82A58E95730A397922B6723DA027986E6CD535','RELEASED','2020-03-31 17:00:16',0),
('2020_04_04_00_auth.sql','5F118989A9F8AFA3B2065AB9C2C0BB7D9A0EB97A','RELEASED','2020-04-04 13:23:53',0),
('2020_04_30_00_auth.sql','2FD304B8EF82D529D69287BF22EF061A267F827E','RELEASED','2020-04-30 00:39:29',0),
+('2020_05_19_00_auth.sql','12D9F26538F63546B74793499E8A71BD885E8E5F','RELEASED','2020-05-19 12:00:00',0),
('2020_06_04_00_auth.sql','BA797B558196B1A07F8FF66E5288AD04659CF6AC','RELEASED','2020-06-04 09:57:07',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/master/2020_05_19_00_auth.sql b/sql/updates/auth/master/2020_05_19_00_auth.sql
new file mode 100644
index 00000000000..7ddeabe630c
--- /dev/null
+++ b/sql/updates/auth/master/2020_05_19_00_auth.sql
@@ -0,0 +1,7 @@
+DELETE FROM `rbac_permissions` WHERE `id` = 855;
+INSERT INTO `rbac_permissions` (`id`,`name`) VALUES
+(855, 'Command: debug play music');
+
+DELETE FROM `rbac_linked_permissions` WHERE `id` = 855;
+INSERT INTO `rbac_linked_permissions` (`id`,`linkedId`) VALUES
+(198, 855);
diff --git a/sql/updates/world/master/2020_06_14_00_world_2017_05_05_00_world.sql b/sql/updates/world/master/2020_06_14_00_world_2017_05_05_00_world.sql
new file mode 100644
index 00000000000..47f6822d310
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_00_world_2017_05_05_00_world.sql
@@ -0,0 +1,7 @@
+UPDATE command SET name = 'reload achievement_reward_locale', help = 'Syntax: .reload achievement_reward_locale\nReload achievement_reward_locale table.' WHERE permission = 657;
+UPDATE command SET name = 'reload creature_template_locale', help = 'Syntax: .reload creature_template_locale\nReload creature_template_locale table.' WHERE permission = 658;
+UPDATE command SET name = 'reload creature_text_locale', help = 'Syntax: .reload creature_text_locale\nReload creature_text_locale Table.' WHERE permission = 659;
+UPDATE command SET name = 'reload gameobject_template_locale', help = 'Syntax: .reload gameobject_template_locale\nReload gameobject_template_locale table.' WHERE permission = 660;
+UPDATE command SET name = 'reload gossip_menu_option_locale', help = 'Syntax: .reload gossip_menu_option_locale\nReload gossip_menu_option_locale table.' WHERE permission = 661;
+UPDATE command SET name = 'reload page_tex_locale', help = 'Syntax: .reload page_tex_locale\nReload page_tex_locale table.' WHERE permission = 665;
+UPDATE command SET name = 'reload points_of_interest_locale', help = 'Syntax: .reload points_of_interest_locale\nReload points_of_interest_locale table.' WHERE permission = 666;
diff --git a/sql/updates/world/master/2020_06_14_01_world_2017_05_06_00_world.sql b/sql/updates/world/master/2020_06_14_01_world_2017_05_06_00_world.sql
new file mode 100644
index 00000000000..fa58a86f325
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_01_world_2017_05_06_00_world.sql
@@ -0,0 +1 @@
+UPDATE command SET name = 'reload page_text_locale', help = 'Syntax: .reload page_text_locale\nReload page_text_locale table.' WHERE permission = 665;
diff --git a/sql/updates/world/master/2020_06_14_02_world_2017_05_07_01_world.sql b/sql/updates/world/master/2020_06_14_02_world_2017_05_07_01_world.sql
new file mode 100644
index 00000000000..f33d464ab21
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_02_world_2017_05_07_01_world.sql
@@ -0,0 +1,4 @@
+--
+ALTER TABLE `gossip_menu_option_locale`
+DROP PRIMARY KEY,
+ADD PRIMARY KEY (`MenuID`, `OptionIndex`, `Locale`);
diff --git a/sql/updates/world/master/2020_06_14_03_world_2017_05_09_00_world.sql b/sql/updates/world/master/2020_06_14_03_world_2017_05_09_00_world.sql
new file mode 100644
index 00000000000..6134763d355
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_03_world_2017_05_09_00_world.sql
@@ -0,0 +1,5 @@
+--
+UPDATE `creature_template` SET `unit_flags`=768, `RegenHealth`=0 WHERE `entry`=26335;
+DELETE FROM `creature_template_addon` WHERE `entry`=26335;
+INSERT INTO `creature_template_addon` (`entry`, `bytes1`, `bytes2`) VALUES (26335, 7, 1);
+UPDATE `creature` SET `curhealth`=1 WHERE `id`=26335;
diff --git a/sql/updates/world/master/2020_06_14_04_world_2017_05_10_00_world.sql b/sql/updates/world/master/2020_06_14_04_world_2017_05_10_00_world.sql
new file mode 100644
index 00000000000..57f1bec7778
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_04_world_2017_05_10_00_world.sql
@@ -0,0 +1,18 @@
+-- Arcatraz Sentinel (20869, 21586)
+DELETE FROM `creature_template_addon` WHERE entry IN (20869, 21586);
+INSERT INTO `creature_template_addon` (entry, path_id, mount, bytes1, bytes2, emote, auras) VALUES
+(20869, 0, 0, 0, 1, 0, "31261 36716"),
+(21586, 0, 0, 0, 1, 0, "31261 38828");
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=20869;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=20869 AND `source_type`=0;
+INSERT INTO `smart_scripts` VALUES
+(20869, 0, 0, 0, 2, 0, 100, 1, 0, 10, 0, 0, 0, '', 11, 36719, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Arcatraz Sentinel - Between 0-2% Health - Cast Spell Explode'),
+(20869, 0, 1, 0, 6, 0, 100, 1, 0, 0, 0, 0, 0, '', 11, 37394, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Arcatraz Sentinel - Death - Cast Serverside - Summon Destroyed Sentinel'),
+(20869, 0, 2, 3, 10, 0, 100, 1, 0, 15, 0, 0, 1, '', 28, 31261, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Arcatraz Sentinel - ooc los - remove aura'),
+(20869, 0, 3, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, '', 49, 0, 0, 0, 0, 0, 0, 21, 50, 0, 0, 0, 0, 0, 0, 'Arcatraz Sentinel - ooc los - Start attack');
+
+-- DELETE FROM `spelldifficulty_dbc` WHERE id IN (36719,36716);
+-- INSERT INTO `spelldifficulty_dbc` (`id`,`spellid0`, `spellid1`) VALUES
+-- (36719,36719,38830),
+-- (36716,36716,38828);
diff --git a/sql/updates/world/master/2020_06_14_05_world_2017_05_10_02_world.sql b/sql/updates/world/master/2020_06_14_05_world_2017_05_10_02_world.sql
new file mode 100644
index 00000000000..fd462c4543d
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_05_world_2017_05_10_02_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `gameobject` WHERE `guid`=59;
+INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnDifficulties`,`PhaseID`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES
+(59, 194026, 571, '0', 0, 3739.33, 3566.95, 341.567, 0.242477, 0, 0, 0.139173, 0.990268, 300, 100, 0);
diff --git a/sql/updates/world/master/2020_06_14_06_world_2017_05_13_01_world.sql b/sql/updates/world/master/2020_06_14_06_world_2017_05_13_01_world.sql
new file mode 100644
index 00000000000..fe3be6bf9ed
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_06_world_2017_05_13_01_world.sql
@@ -0,0 +1,77 @@
+SET @OGUID:=47713;
+
+DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+72;
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`) VALUES
+(@OGUID+0 , 176563, 450, 0, 0, '0', 0, -40.41246, 16.34629, -5.145579, 3.455756, 0, 0, -0.9876881, 0.1564362, 7200, 255, 1, '', 23706), -- 176563 (Area: 2917)
+(@OGUID+1 , 176566, 450, 0, 0, '0', 0, 206.6491, 66.07558, 25.40491, 3.604106, 0, 0, -0.9733791, 0.2292009, 7200, 255, 0, '', 23706), -- 176566 (Area: 2917)
+(@OGUID+2 , 112317, 560, 0, 0, '1,2', 0, 1794.44, 1112.927, 12.46013, 6.204648, 0, 0, -0.03925896, 0.9992291, 7200, 255, 1, '', 23706), -- 112317 (Area: 2369)
+(@OGUID+3 , 112316, 560, 0, 0, '1,2', 0, 1795.41, 1111.976, 12.46013, 1.579522, 0, 0, 0.7101851, 0.704015, 7200, 255, 1, '', 23706), -- 112316 (Area: 2369)
+(@OGUID+4 , 112319, 560, 0, 0, '1,2', 0, 1808.012, 1112.328, 13.47555, 4.782205, 0, 0, -0.6819973, 0.7313547, 7200, 255, 1, '', 23706), -- 112319 (Area: 2369)
+(@OGUID+5 , 112321, 560, 0, 0, '1,2', 0, 1802.565, 1112.28, 13.47555, 4.721118, 0, 0, -0.7040138, 0.7101862, 7200, 255, 1, '', 23706), -- 112321 (Area: 2369)
+(@OGUID+6 , 22910, 560, 0, 0, '1,2', 0, 1820.542, 1044.187, 18.65778, 4.71239, 0, 0, -0.7071066, 0.7071069, 7200, 255, 1, '', 23706), -- 22910 (Area: 2369)
+(@OGUID+7 , 22921, 560, 0, 0, '1,2', 0, 1801.726, 1034.977, 11.06904, 5.558876, 0, 0, -0.35429, 0.9351356, 7200, 255, 1, '', 23706), -- 22921 (Area: 2369)
+(@OGUID+8 , 22923, 560, 0, 0, '1,2', 0, 1808.022, 1035.029, 11.06904, 4.057892, 0, 0, -0.8968725, 0.4422892, 7200, 255, 1, '', 23706), -- 22923 (Area: 2369)
+(@OGUID+9 , 22922, 560, 0, 0, '1,2', 0, 1803.098, 1035.267, 11.06904, 4.729844, 0, 0, -0.7009087, 0.7132511, 7200, 255, 1, '', 23706), -- 22922 (Area: 2369)
+(@OGUID+10, 22925, 560, 0, 0, '1,2', 0, 1804.703, 1035.279, 11.06904, 4.729844, 0, 0, -0.7009087, 0.7132511, 7200, 255, 1, '', 23706), -- 22925 (Area: 2369)
+(@OGUID+11, 22924, 560, 0, 0, '1,2', 0, 1806.315, 1035.295, 11.06904, 4.598942, 0, 0, -0.7460575, 0.6658815, 7200, 255, 1, '', 23706), -- 22924 (Area: 2369)
+(@OGUID+12, 22927, 560, 0, 0, '1,2', 0, 1818.748, 1044.187, 18.65778, 4.71239, 0, 0, -0.7071066, 0.7071069, 7200, 255, 1, '', 23706), -- 22927 (Area: 2369)
+(@OGUID+13, 22926, 560, 0, 0, '1,2', 0, 1801.52, 1033.646, 11.06904, 0.02617911, 0, 0, 0.01308918, 0.9999143, 7200, 255, 1, '', 23706), -- 22926 (Area: 2369)
+(@OGUID+14, 184305, 560, 0, 0, '1,2', 0, 1818.346, 1031.224, 11.09751, 3.124123, 0, 0, 0.9999619, 0.008734641, 7200, 255, 1, '', 23706), -- 184305 (Area: 2369)
+(@OGUID+15, 180570, 560, 0, 0, '1,2', 0, 1808.454, 1022.87, 13.71209, 1.518436, 0, 0, 0.6883545, 0.7253745, 7200, 255, 1, '', 23706), -- 180570 (Area: 2369)
+(@OGUID+16, 184332, 560, 0, 0, '1,2', 0, 1819.035, 1023.37, 19.71265, 4.729844, 0, 0, -0.7009087, 0.7132511, 7200, 255, 1, '', 23706), -- 184332 (Area: 2369
+(@OGUID+17, 22673, 560, 0, 0, '1,2', 0, 1885.541, 1103.728, 18.91458, 2.495818, 0, 0, 0.9483232, 0.3173059, 7200, 255, 1, '', 23706), -- 22673 (Area: 2369)
+(@OGUID+18, 22672, 560, 0, 0, '1,2', 0, 1886.727, 1103.384, 18.91458, 1.204277, 0, 0, 0.5664063, 0.8241262, 7200, 255, 1, '', 23706), -- 22672 (Area: 2369)
+(@OGUID+19, 22674, 560, 0, 0, '1,2', 0, 1885.833, 1103.073, 18.91458, 5.297076, 0, 0, -0.4733191, 0.8808911, 7200, 255, 1, '', 23706), -- 22674 (Area: 2369)
+(@OGUID+20, 22685, 560, 0, 0, '1,2', 0, 1892.805, 1090.597, 23.63159, 2.513274, 0, 0, 0.9510565, 0.3090171, 7200, 255, 1, '', 23706), -- 22685 (Area: 2369)
+(@OGUID+21, 22684, 560, 0, 0, '1,2', 0, 1890.807, 1087.847, 23.63159, 2.513274, 0, 0, 0.9510565, 0.3090171, 7200, 255, 1, '', 23706), -- 22684 (Area: 2369)
+(@OGUID+22, 22671, 560, 0, 0, '1,2', 0, 1886.854, 1103.559, 23.83143, 1.204277, 0, 0, 0.5664063, 0.8241262, 7200, 255, 1, '', 23706), -- 22671 (Area: 2369)
+(@OGUID+23, 22670, 560, 0, 0, '1,2', 0, 1885.96, 1103.248, 23.83143, 5.297076, 0, 0, -0.4733191, 0.8808911, 7200, 255, 1, '', 23706), -- 22670 (Area: 2369)
+(@OGUID+24, 112305, 560, 0, 0, '1,2', 0, 1792.475, 1129.977, 13.47555, 4.799657, 0, 0, -0.6755896, 0.7372779, 7200, 255, 1, '', 23706), -- 112305 (Area: 2369)
+(@OGUID+25, 112309, 560, 0, 0, '1,2', 0, 1788.27, 1129.94, 13.47555, 4.756022, 0, 0, -0.6915131, 0.7223639, 7200, 255, 1, '', 23706), -- 112309 (Area: 2369)
+(@OGUID+26, 112308, 560, 0, 0, '1,2', 0, 1790.442, 1129.959, 13.47555, 4.677484, 0, 0, -0.7193394, 0.6946588, 7200, 255, 1, '', 23706), -- 112308 (Area: 2369)
+(@OGUID+27, 112311, 560, 0, 0, '1,2', 0, 1807.419, 1117.274, 13.47555, 1.50098, 0, 0, 0.6819973, 0.7313547, 7200, 255, 1, '', 23706), -- 112311 (Area: 2369)
+(@OGUID+28, 112310, 560, 0, 0, '1,2', 0, 1805.387, 1117.256, 13.47555, 1.64061, 0, 0, 0.7313538, 0.6819983, 7200, 255, 1, '', 23706), -- 112310 (Area: 2369)
+(@OGUID+29, 112312, 560, 0, 0, '1,2', 0, 1809.591, 1117.293, 13.47555, 1.579522, 0, 0, 0.7101851, 0.704015, 7200, 255, 1, '', 23706), -- 112312 (Area: 2369)
+(@OGUID+30, 112301, 560, 0, 0, '1,2', 0, 1805.231, 1130.088, 13.47555, 4.721118, 0, 0, -0.7040138, 0.7101862, 7200, 255, 1, '', 23706), -- 112301 (Area: 2369)
+(@OGUID+31, 112303, 560, 0, 0, '1,2', 0, 1809.436, 1130.125, 13.47555, 4.721118, 0, 0, -0.7040138, 0.7101862, 7200, 255, 1, '', 23706), -- 112303 (Area: 2369)
+(@OGUID+32, 112302, 560, 0, 0, '1,2', 0, 1807.403, 1130.107, 13.47555, 4.81711, 0, 0, -0.6691303, 0.743145, 7200, 255, 1, '', 23706), -- 112302 (Area: 2369)
+(@OGUID+33, 174995, 560, 0, 0, '1,2', 0, 1876.241, 1105.719, 18.84545, 5.654869, 0, 0, -0.3090162, 0.9510568, 7200, 255, 1, '', 23706), -- 174995 (Area: 2369)
+(@OGUID+34, 174994, 560, 0, 0, '1,2', 0, 1874.842, 1103.794, 18.84545, 5.654869, 0, 0, -0.3090162, 0.9510568, 7200, 255, 1, '', 23706), -- 174994 (Area: 2369)
+(@OGUID+35, 174997, 560, 0, 0, '1,2', 0, 1879.806, 1104.808, 18.84545, 4.084071, 0, 0, -0.8910065, 0.4539906, 7200, 255, 1, '', 23706), -- 174997 (Area: 2369)
+(@OGUID+36, 174996, 560, 0, 0, '1,2', 0, 1878.052, 1106.083, 18.84545, 4.084071, 0, 0, -0.8910065, 0.4539906, 7200, 255, 1, '', 23706), -- 174996 (Area: 2369)
+(@OGUID+37, 174998, 560, 0, 0, '1,2', 0, 1881.476, 1103.594, 18.84545, 4.084071, 0, 0, -0.8910065, 0.4539906, 7200, 255, 1, '', 23706), -- 174998 (Area: 2369)
+(@OGUID+38, 112322, 560, 0, 0, '1,2', 0, 1781.195, 1123.755, 13.47555, 0.04363215, 0, 0, 0.02181435, 0.9997621, 7200, 255, 1, '', 23706), -- 112322 (Area: 2369)
+(@OGUID+39, 22904, 560, 0, 0, '1,2', 0, 1822.65, 1035.223, 18.54309, 4.372049, 0, 0, -0.8166418, 0.5771448, 7200, 255, 1, '', 23706), -- 22904 (Area: 2369)
+(@OGUID+40, 22909, 560, 0, 0, '1,2', 0, 1813.019, 1022.755, 18.65778, 0.1919871, 0, 0, 0.09584618, 0.9953961, 7200, 255, 1, '', 23706), -- 22909 (Area: 2369)
+(@OGUID+41, 22908, 560, 0, 0, '1,2', 0, 1821.753, 1023.72, 11.70037, 3.900813, 0, 0, -0.9288092, 0.3705584, 7200, 255, 1, '', 23706), -- 22908 (Area: 2369)
+(@OGUID+42, 36977, 560, 0, 0, '1,2', 0, 1883.635, 1096.758, 18.84545, 5.654869, 0, 0, -0.3090162, 0.9510568, 7200, 255, 1, '', 23706), -- 36977 (Area: 2369)
+(@OGUID+43, 3803, 560, 0, 0, '1,2', 0, 1847.715, 1112.489, 16.38847, 1.771508, 0, 0, 0.7743921, 0.632706, 7200, 255, 1, '', 23706), -- 3803 (Area: 2369)
+(@OGUID+44, 3804, 560, 0, 0, '1,2', 0, 1846.83, 1112.615, 16.38847, 3.063024, 0, 0, 0.9992285, 0.03927403, 7200, 255, 1, '', 23706), -- 3804 (Area: 2369)
+(@OGUID+45, 22915, 560, 0, 0, '1,2', 0, 1820.176, 1023.963, 11.70037, 4.729844, 0, 0, -0.7009087, 0.7132511, 7200, 255, 1, '', 23706), -- 22915 (Area: 2369)
+(@OGUID+46, 22915, 560, 0, 0, '1,2', 0, 1820.176, 1023.963, 11.70037, 4.729844, 0, 0, -0.7009087, 0.7132511, 7200, 255, 1, '', 23706), -- 22915 (Area: 2369)
+(@OGUID+47, 22917, 560, 0, 0, '1,2', 0, 1821.696, 1020.943, 11.70037, 2.347464, 0, 0, 0.9222002, 0.3867128, 7200, 255, 1, '', 23706), -- 22917 (Area: 2369)
+(@OGUID+48, 22916, 560, 0, 0, '1,2', 0, 1818.501, 1023.7, 11.70037, 5.297076, 0, 0, -0.4733191, 0.8808911, 7200, 255, 1, '', 23706), -- 22916 (Area: 2369)
+(@OGUID+49, 22919, 560, 0, 0, '1,2', 0, 1822.449, 1032.6, 18.54309, 1.928588, 0, 0, 0.8216467, 0.5699971, 7200, 255, 1, '', 23706), -- 22919 (Area: 2369)
+(@OGUID+50, 22918, 560, 0, 0, '1,2', 0, 1820.166, 1020.634, 11.70037, 1.544616, 0, 0, 0.6977901, 0.7163023, 7200, 255, 1, '', 23706), -- 22918 (Area: 2369)
+(@OGUID+51, 22920, 560, 0, 0, '1,2', 0, 1818.606, 1020.993, 11.70037, 1.178098, 0, 0, 0.5555706, 0.8314694, 7200, 255, 1, '', 23706), -- 22920 (Area: 2369)
+(@OGUID+52, 3803, 560, 0, 0, '1,2', 0, 1849.74, 1032.096, 16.34453, 5.131269, 0, 0, -0.5446386, 0.8386708, 7200, 255, 1, '', 23706), -- 3803 (Area: 2369)
+(@OGUID+53, 3804, 560, 0, 0, '1,2', 0, 1850.632, 1032.164, 16.34453, 0.1396245, 0, 0, 0.06975555, 0.9975641, 7200, 255, 1, '', 23706), -- 3804 (Area: 2369)
+(@OGUID+54, 38147, 560, 0, 0, '1,2', 0, 1815.941, 1012.808, 18.54309, 1.230456, 0, 0, 0.5771446, 0.816642, 7200, 255, 1, '', 23706), -- 38147 (Area: 2369)
+(@OGUID+55, 23013, 560, 0, 0, '1,2', 0, 1989.882, 1163.661, 31.64357, 2.539454, 0, 0, 0.95502, 0.2965415, 7200, 255, 1, '', 23706), -- 23013 (Area: 2369)
+(@OGUID+56, 23015, 560, 0, 0, '1,2', 0, 1982.852, 1180.465, 31.61295, 5.358162, 0, 0, -0.4461975, 0.8949345, 7200, 255, 1, '', 23706), -- 23015 (Area: 2369)
+(@OGUID+57, 23014, 560, 0, 0, '1,2', 0, 1991.932, 1166.378, 31.64357, 3.176533, 0, 0, -0.9998474, 0.01746928, 7200, 255, 1, '', 23706), -- 23014 (Area: 2
+(@OGUID+58, 4087, 560, 0, 0, '1,2', 0, 2095.073, 1633.465, 49.88202, 1.605702, 0, 0, 0.7193394, 0.6946588, 7200, 255, 1, '', 23706), -- 4087 (Area: 0)
+(@OGUID+59, 4089, 560, 0, 0, '1,2', 0, 2088.648, 1645.305, 49.88202, 0.165805, 0, 0, 0.08280754, 0.9965656, 7200, 255, 1, '', 23706), -- 4089 (Area: 0)
+(@OGUID+60, 4088, 560, 0, 0, '1,2', 0, 2094.378, 1646.551, 49.88202, 4.415687, 0, 0, -0.8038559, 0.5948241, 7200, 255, 1, '', 23706), -- 4088 (Area: 0)
+(@OGUID+61, 4090, 560, 0, 0, '1,2', 0, 2094.719, 1639.939, 48.07408, 5.654869, 0, 0, -0.3090162, 0.9510568, 7200, 255, 1, '', 23706), -- 4090 (Area: 0
+(@OGUID+62, 22603, 560, 0, 0, '1,2', 0, 2329.611, 1608.566, 60.49135, 5.873035, 0, 0, -0.2036409, 0.9790456, 7200, 255, 1, '', 23706), -- 22603 (Area: 0)
+(@OGUID+63, 22602, 560, 0, 0, '1,2', 0, 2329.339, 1609.473, 60.49135, 3.68265, 0, 0, -0.9636297, 0.267241, 7200, 255, 1, '', 23706), -- 22602 (Area: 0)
+(@OGUID+64, 22605, 560, 0, 0, '1,2', 0, 2329.837, 1609.87, 55.5745, 0.8813897, 0, 0, 0.426568, 0.9044555, 7200, 255, 1, '', 23706), -- 22605 (Area: 0)
+(@OGUID+65, 22604, 560, 0, 0, '1,2', 0, 2329.442, 1608.7, 55.5745, 5.873035, 0, 0, -0.2036409, 0.9790456, 7200, 255, 1, '', 23706), -- 22604 (Area: 0)
+(@OGUID+66, 22606, 560, 0, 0, '1,2', 0, 2329.17, 1609.607, 55.5745, 3.68265, 0, 0, -0.9636297, 0.267241, 7200, 255, 1, '', 23706), -- 22606 (Area: 0)
+(@OGUID+67, 3799, 560, 0, 0, '1,2', 0, 2223.475, 1484.469, 54.98195, 5.087637, 0, 0, -0.5628042, 0.8265902, 7200, 255, 1, '', 23706), -- 3799 (Area: 0)
+(@OGUID+68, 3800, 560, 0, 0, '1,2', 0, 2224.369, 1484.498, 54.98195, 0.09599175, 0, 0, 0.04797745, 0.9988484, 7200, 255, 1, '', 23706), -- 3800 (Area:
+(@OGUID+69, 123244, 560, 0, 0, '1,2', 0, 2101.137, 1641.488, 49.88202, 3.089183, 0, 0, 0.9996567, 0.02620165, 7200, 255, 1, '', 23706), -- 123244 (Area: 0)
+(@OGUID+70, 3799, 560, 0, 0, '1,2', 0, 2116.721, 1483.125, 46.51685, 4.965463, 0, 0, -0.6122169, 0.7906898, 7200, 255, 1, '', 23706), -- 3799 (Area: 0)
+(@OGUID+71, 3800, 560, 0, 0, '1,2', 0, 2117.612, 1483.045, 46.51685, 6.257006, 0, 0, -0.01308918, 0.9999143, 7200, 255, 1, '', 23706), -- 3800 (Area: 0)
+(@OGUID+72, 176308, 329, 0, 0, '1', 0, 3659.384, -3305.042, 127.0623, 5.009095, 0, 0, -0.5948229, 0.8038568, 7200, 255, 1, '', 23706); -- 176308 (Area: 5917)
diff --git a/sql/updates/world/master/2020_06_14_07_world_2017_05_14_00_world_335.sql b/sql/updates/world/master/2020_06_14_07_world_2017_05_14_00_world_335.sql
new file mode 100644
index 00000000000..2ac3d7bc207
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_07_world_2017_05_14_00_world_335.sql
@@ -0,0 +1,4 @@
+-- add text for use in boss_apothecary_hummel.cpp
+DELETE FROM `creature_text` WHERE `CreatureID`=36296 AND `GroupID`=6 AND `ID`=0;
+INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
+(36296,6,0,"Apothecaries! Give your life for the Crown!",12,0,100,0,0,0,38594,3,'SAY_SUMMON_ADDS');
diff --git a/sql/updates/world/master/2020_06_14_08_world_2017_05_14_01_world.sql b/sql/updates/world/master/2020_06_14_08_world_2017_05_14_01_world.sql
new file mode 100644
index 00000000000..21f69cdf106
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_08_world_2017_05_14_01_world.sql
@@ -0,0 +1 @@
+UPDATE `smart_scripts` SET `target_type`=8 WHERE `entryorguid`=2731600 AND `source_type`=9 AND `id` IN(2,3);
diff --git a/sql/updates/world/master/2020_06_14_09_world_2017_05_16_01_world.sql b/sql/updates/world/master/2020_06_14_09_world_2017_05_16_01_world.sql
new file mode 100644
index 00000000000..8e0718846b3
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_09_world_2017_05_16_01_world.sql
@@ -0,0 +1,210 @@
+/*
+ * Thorim
+ */
+
+DELETE FROM `creature_text` WHERE `CreatureID` IN (32865,32872,32873,33196);
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `comment`) VALUES
+-- Thorim
+(32865, 0,0,'Interlopers! You mortals who dare to interfere with my sport will pay... Wait--you...',14,0,100,0,0,15733,33145,'Thorim SAY_AGGRO_1'),
+(32865, 1,0,'I remember you... In the mountains... But you... what is this? Where am--',14,0,100,0,0,15734,33270,'Thorim SAY_AGGRO_2'),
+(32865, 2,0,'Do not hold back! Destroy them!',14,0,100,0,0,15736,34241,'Thorim SAY_SPECIAL'),
+(32865, 3,0,'Impertinent whelps, you dare challenge me atop my pedestal? I will crush you myself!',14,0,100,0,0,15738,33148,'Thorim SAY_JUMPDOWN'),
+(32865, 4,0,'Can''t you at least put up a fight!?',14,0,100,0,0,15739,34239,'Thorim SAY_SLAY_1'),
+(32865, 4,1,'Pathetic.',14,0,100,0,0,15740,35768,'Thorim SAY_SLAY_2'),
+(32865, 5,0,'My patience has reached its limit!',14,0,100,0,0,15741,33365,'Thorim SAY_BERSERK'),
+(32865, 6,0,'Failures! Weaklings!',14,0,100,0,0,15742,33274,'Thorim SAY_WIPE'),
+(32865, 7,0,'Stay your arms! I yield!',14,0,100,0,0,15743,33948,'Thorim SAY_DEATH'),
+(32865, 8,0,'I feel as though I am awakening from a nightmare, but the shadows in this place yet linger.',14,0,100,0,0,15744,33949,'Thorim SAY_END_NORMAL_1'),
+(32865, 9,0,'Sif... was Sif here? Impossible--she died by my brother''s hand. A dark nightmare indeed....',14,0,100,0,0,15745,33950,'Thorim SAY_END_NORMAL_2'),
+(32865,10,0,'I need time to reflect.... I will aid your cause if you should require it. I owe you at least that much. Farewell.',14,0,100,0,0,15746,33951,'Thorim SAY_END_NORMAL_3'),
+(32865,11,0,'You! Fiend! You are not my beloved! Be gone!',14,0,100,0,0,15747,33952,'Thorim SAY_END_HARD_1'),
+(32865,12,0,'Behold the hand behind all the evil that has befallen Ulduar, left my kingdom in ruins, corrupted my brother, and slain my wife.',14,0,100,0,0,15748,33953,'Thorim SAY_END_HARD_2'),
+(32865,13,0,'And now it falls to you, champions, to avenge us all. The task before you is great, but I will lend you my aid as I am able. You must prevail.',14,0,100,0,0,15749,33954,'Thorim SAY_END_HARD_3'),
+-- Runic Colossus
+(32872, 0,0,'%s surrounds itself with a crackling Runic Barrier!',41,0,100,0,0,0,33267,'Runic Colossus'),
+-- Ancient Rune Giant
+(32873, 0,0,'%s fortifies nearby allies with runic might!',41,0,100,0,0,0,33523,'Ancient Rune Giant'),
+-- Sif
+(33196, 0,0,'Thorim, my lord! Why else would these invaders have come into your sanctum but to slay you? They must be stopped!',14,0,100,0,0,15668,33325,'Sif - Start'),
+(33196, 1,0,'These pathetic mortals are harmless, beneath my station. Dispose of them!',14,0,100,0,0,15669,33368,'Sif - Despawn'),
+(33196, 2,0,'Impossible! Lord Thorim, I will bring your foes a frigid death!',14,0,100,0,0,15670,33369,'Sif - Event');
+
+-- Lever SAI
+SET @ENTRY := 194264;
+UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=@ENTRY;
+UPDATE `gameobject_template_addon` SET `flags`=32 WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=1;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,1,0,0,70,0,100,0,2,0,0,0,9,0,0,0,0,0,0,14,34155,0,0,0,0,0,0,'Lever - On Gameobject State Changed - Activate Gameobject');
+
+-- Thorim Trap Bunny SAI
+SET @ENTRY := 33054;
+UPDATE `creature_template` SET `AIName`='SmartAI', `flags_extra`=2 WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,10,0,100,0,0,12,17000,17000,11,62241,0,0,0,0,0,1,0,0,0,0,0,0,0,'Thorim Trap Bunny - Within 0-12 Range Out of Combat LoS - Cast Paralytic Field');
+
+SET @ENTRY := 33725;
+UPDATE `creature_template` SET `AIName`='SmartAI', `flags_extra`=2 WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0;
+INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES
+(@ENTRY,0,0,0,10,0,100,0,0,12,17000,17000,11,63540,0,0,0,0,0,1,0,0,0,0,0,0,0,'Thorim Trap Bunny - Within 0-12 Range Out of Combat LoS - Cast Paralytic Field');
+
+DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_thorim_blizzard_effect','spell_thorim_frostbolt_volley','spell_thorim_charge_orb','spell_thorim_runic_smash','spell_thorim_stormhammer','spell_thorim_lightning_charge','spell_thorim_stormhammer_sif','spell_thorim_stormhammer_boomerang','spell_thorim_activate_lightning_orb_periodic','spell_iron_ring_guard_impale','spell_thorim_arena_leap');
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(62576,'spell_thorim_blizzard_effect'),
+(62602,'spell_thorim_blizzard_effect'),
+(62580,'spell_thorim_frostbolt_volley'),
+(62604,'spell_thorim_frostbolt_volley'),
+(62016,'spell_thorim_charge_orb'),
+(62057,'spell_thorim_runic_smash'),
+(62058,'spell_thorim_runic_smash'),
+(62042,'spell_thorim_stormhammer'),
+(62466,'spell_thorim_lightning_charge'),
+(64767,'spell_thorim_stormhammer_sif'),
+(64909,'spell_thorim_stormhammer_boomerang'),
+(62184,'spell_thorim_activate_lightning_orb_periodic'),
+(62331,'spell_iron_ring_guard_impale'),
+(62418,'spell_iron_ring_guard_impale'),
+(61934,'spell_thorim_arena_leap');
+
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=62042;
+DELETE FROM `spell_linked_spell` WHERE `spell_trigger` = -62320;
+INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(-62320, -62398, 0, 'Aura of Celerity - Remove Visual');
+
+UPDATE `creature_template` SET `ScriptName`='boss_thorim' WHERE `entry`=32865;
+UPDATE `creature_template` SET `ScriptName`='npc_sif' WHERE `entry`=33196;
+UPDATE `creature_template` SET `ScriptName`='npc_thorim_pre_phase' WHERE `entry` IN (32885,32883,32908,32907,32882,32886);
+UPDATE `creature_template` SET `ScriptName`='npc_thorim_arena_phase' WHERE `entry` IN (32876,32904,32878,32877,32874,32875,33110);
+UPDATE `creature_template` SET `ScriptName`='npc_runic_colossus' WHERE `entry`=32872;
+UPDATE `creature_template` SET `ScriptName`='npc_ancient_rune_giant' WHERE `entry`=32873;
+UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x40000000 WHERE `entry` IN (32872, 32873, 33148, 33149);
+UPDATE `creature_template` SET `difficulty_entry_1`=33150 WHERE `entry`=32908; -- Swapped Difficulty entry npcs
+UPDATE `creature_template` SET `difficulty_entry_1`=33151 WHERE `entry`=32907; -- Caused swapped displayIDs in 25n
+UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128, `ScriptName`='' WHERE `entry` IN (33140,33141);
+UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=128 WHERE `entry` IN (33378,32879);
+UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry` IN (32892);
+UPDATE `creature_template` SET `faction`=1692 WHERE `entry` IN (32885,32883,33152,33153,32908,33150,32907,33151);
+UPDATE `creature_template` SET `faction`=1693 WHERE `entry` IN (32882,33154);
+UPDATE `creature_template` SET `speed_walk`=2.5/2.5, `speed_run`=14.0/7.0, `BaseAttackTime`=1500, `RangeAttackTime`=1500, `flags_extra`=`flags_extra`|0x00000200 WHERE `entry` IN (32865,33147);
+
+SET @THORIM_BLIZZARD_BUNNY := 136515;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (62577,62603,62016,62976,63238,64098,62466,62565,62942,64767,62560,61964,61934);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 62577, 0, 0, 31, 0, 3, 32892, @THORIM_BLIZZARD_BUNNY, 0, 0, 0, '', 'Spell Blizzard (effect 0) will hit the potential target of the spell if target is unit Thorim Event Bunny guid 136515.'),
+(13, 1, 62603, 0, 0, 31, 0, 3, 32892, @THORIM_BLIZZARD_BUNNY, 0, 0, 0, '', 'Spell Blizzard (effect 0) will hit the potential target of the spell if target is unit Thorim Event Bunny guid 136515.'),
+(13, 1, 62016, 0, 0, 31, 0, 3, 33378, 0, 0, 0, 0, '', 'Spell Charge Orb (effect 0) will hit the potential target of the spell if target is unit Thunder Orb.'),
+(13, 1, 62976, 0, 0, 31, 0, 3, 33378, 0, 0, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is unit Thunder Orb.'),
+(13, 1, 62976, 0, 0, 33, 0, 1, 0, 0, 1, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is not the same as condition target.'),
+(13, 1, 63238, 0, 0, 31, 0, 3, 33378, 0, 0, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is unit Thunder Orb.'),
+(13, 1, 63238, 0, 0, 33, 0, 1, 0, 0, 1, 0, 0, '', 'Spell Lightning Pillar (effect 0) will hit the potential target of the spell if target is not the same as condition target.'),
+(13, 1, 64098, 0, 0, 31, 0, 3, 32865, 0, 0, 0, 0, '', 'Spell Lightning Bolt (effect 0) will hit the potential target of the spell if target is unit Thorim.'),
+(13, 4, 62466, 0, 0, 31, 0, 3, 32780, 0, 0, 0, 0, '', 'Spell Lightning Charge (effect 2) will hit the potential target of the spell if target is unit Invisible Stalker (All Phases).'),
+(13, 3, 62565, 0, 0, 31, 0, 3, 32865, 0, 0, 0, 0, '', 'Spell Touch of Dominion (effects 0 & 1) will hit the potential target of the spell if target is unit Thorim.'),
+(13, 7, 62942, 0, 0, 31, 0, 3, 32874, 0, 0, 0, 0, '', 'Spell Runic Fortification (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Iron Ring Guard.'),
+(13, 7, 62942, 0, 1, 31, 0, 3, 32875, 0, 0, 0, 0, '', 'Spell Runic Fortification (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Iron Honor Guard.'),
+(13, 7, 62942, 0, 2, 31, 0, 3, 33110, 0, 0, 0, 0, '', 'Spell Runic Fortification (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Acolyte.'),
+(13, 1, 64767, 0, 0, 31, 0, 3, 33196, 0, 0, 0, 0, '', 'Spell Stormhammer (effect 0) will hit the potential target of the spell if target is unit Sif.'),
+(13, 7, 62560, 0, 0, 31, 0, 3, 32876, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Champion.'),
+(13, 7, 62560, 0, 1, 31, 0, 3, 32877, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Warbringer.'),
+(13, 7, 62560, 0, 2, 31, 0, 3, 32878, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Evoker.'),
+(13, 7, 62560, 0, 3, 31, 0, 3, 32904, 0, 0, 0, 0, '', 'Spell Berserk (effect 0 & 1 & 2) will hit the potential target of the spell if target is unit Dark Rune Commoner.'),
+(13, 1, 61964, 0, 0, 31, 0, 3, 32882, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Jormungar Behemoth.'),
+(13, 1, 61964, 0, 1, 31, 0, 3, 32883, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Soldier.'),
+(13, 1, 61964, 0, 2, 31, 0, 3, 32885, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Soldier.'),
+(13, 1, 61964, 0, 3, 31, 0, 3, 32886, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Dark Rune Acolyte.'),
+(13, 1, 61964, 0, 4, 31, 0, 3, 32907, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Captain.'),
+(13, 1, 61964, 0, 5, 31, 0, 3, 32908, 0, 0, 0, 0, '', 'Spell Circle of Healing (effect 0) will hit the potential target of the spell if target is unit Captured Mercenary Captain.'),
+(13, 1, 61934, 0, 0, 31, 0, 3, 32892, 0, 0, 0, 0, 'condition_thorim_arena_leap', 'Spell Leap (effect 0) will hit the potential target of the spell if target is unit Thorim Event Bunny.'),
+(13, 1, 61934, 0, 0, 31, 0, 3, 32892, @THORIM_BLIZZARD_BUNNY, 1, 0, 0, '', 'Spell Leap (effect 0) will hit the potential target of the spell if target is not unit Thorim Event Bunny guid 136515.');
+
+DELETE FROM `disables` WHERE `sourceType`=0 AND `entry` IN (62042,64767,45537);
+INSERT INTO `disables` (`sourceType`, `entry`, `flags`, `params_0`, `params_1`, `comment`) VALUES
+(0, 62042, 64, '', '', 'Stormhammer - Ignore LOS'),
+(0, 64767, 64, '', '', 'Stormhammer - Ignore LOS'),
+(0, 45537, 64, '', '', 'Lightning Beam Channel - Ignore LOS');
+
+DELETE FROM `creature` WHERE `id` IN (32882,32908,32907,32885,32883,32886); -- PreAdds
+DELETE FROM `creature` WHERE `id` IN (32874,32875,33110); -- Colossus, Giant Adds
+
+-- Fix Thorim Controller multi spawns
+SET @CGUID:=136446;
+DELETE FROM `creature` WHERE `id`=32879;
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnDifficulties`, `PhaseId`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES
+(@CGUID, 32879, 603, '14,33', 0, 2134.774, -262.3073, 428.6936, 1.343904, 7200, 0, 0); -- 32879 (Area: 0) (Auras: 62184 - 62184)
+
+UPDATE `gameobject_template` SET `size`=3 WHERE `entry`=194315;
+UPDATE `gameobject_template_addon` SET `faction`=94, `flags`=16 WHERE `entry` IN (194313,194314,194315);
+
+SET @OGUID := 3926; -- 4 free guids
+DELETE FROM `gameobject` WHERE `id` IN (194312,194313,194314,194315);
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnDifficulties`, `PhaseId`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) values
+(@OGUID+0,194312,603,'14',0,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0),
+(@OGUID+1,194313,603,'14',0,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0),
+(@OGUID+2,194314,603,'33',0,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0),
+(@OGUID+3,194315,603,'33',0,2134.948,-286.436,419.5051,1.588249,0,0,0.7132502,0.7009096,-604800,255,1,0);
+
+UPDATE `gameobject_loot_template` SET `LootMode`=1 WHERE `Entry`=27074;
+DELETE FROM `gameobject_loot_template` WHERE `Entry` IN (26955,26956);
+INSERT INTO `gameobject_loot_template` (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES
+(26955,1,34372,100,0,1,0,1,1,'Thorim25 HM - normal mode loot'),
+(26955,2,12033,100,0,1,0,1,2,'Thorim25 HM - T8.5 tokens'),
+(26955,3,34154,10,0,1,0,1,1,'Thorim25 HM - Random Ulduar craft recipe'),
+(26955,45038,0,18,0,1,0,1,1,'Thorim25 HM - Val''anyr fragment'),
+(26955,45087,0,10,0,1,0,1,1,'Thorim25 HM - Runed Orb'),
+(26955,45470,0,0,0,1,1,1,1,'Thorim25 HM - Wisdom''s Hold'),
+(26955,45471,0,0,0,1,1,1,1,'Thorim25 HM - Fate''s Clutch'),
+(26955,45472,0,0,0,1,1,1,1,'Thorim25 HM - Warhelm of the Champion'),
+(26955,45473,0,0,0,1,1,1,1,'Thorim25 HM - Embrace of the Gladiator'),
+(26955,45474,0,0,0,1,1,1,1,'Thorim25 HM - Pauldrons of the Combatant'),
+(26955,45570,0,0,0,1,1,1,1,'Thorim25 HM - Skyforge Crossbow'),
+(26955,45817,0,100,1,1,0,1,1,'Thorim25 HM - Thorim''s Sigil'),
+(26955,47241,0,100,0,1,0,1,1,'Thorim25 HM - Emblem of Triumph'),
+
+(26956,1,34372,100,0,1,0,1,1,'Thorim25 - normal mode loot'),
+(26956,2,12033,100,0,1,0,1,2,'Thorim25 - T8.5 tokens'),
+(26956,3,34154,10,0,1,0,1,1,'Thorim25 - Random Ulduar craft recipe'),
+(26956,45038,0,8,0,1,0,1,1,'Thorim25 - Val''anyr fragment'),
+(26956,45087,0,10,0,1,0,1,1,'Thorim25 - Runed Orb'),
+(26956,47241,0,100,0,1,0,1,1,'Thorim25 - Emblem of Triumph');
+
+-- Pathing for Thorim Event Bunny Entry: 32892 'TDB FORMAT'
+SET @PATH := @THORIM_BLIZZARD_BUNNY * 10;
+UPDATE `creature` SET `spawndist`=0,`MovementType`=2,`position_x`=2148.425,`position_y`=-276.7478,`position_z`=419.5923 WHERE `guid`=@THORIM_BLIZZARD_BUNNY;
+DELETE FROM `creature_addon` WHERE `guid`=@THORIM_BLIZZARD_BUNNY;
+INSERT INTO `creature_addon` (`guid`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES (@THORIM_BLIZZARD_BUNNY,@PATH,0,0,1,0, '');
+DELETE FROM `waypoint_data` WHERE `id`=@PATH;
+INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_type`,`action`,`action_chance`,`wpguid`) VALUES
+(@PATH,1,2148.425,-276.7478,419.5923,0,0,0,0,100,0),
+(@PATH,2,2145.229,-278.5732,419.6016,0,0,0,0,100,0),
+(@PATH,3,2142.105,-280.7194,419.5932,0,0,0,0,100,0),
+(@PATH,4,2138.419,-281.2838,419.5999,0,0,0,0,100,0),
+(@PATH,5,2134.843,-281.9885,419.5996,0,0,0,0,100,0),
+(@PATH,6,2131.128,-281.278,419.5985,0,0,0,0,100,0),
+(@PATH,7,2127.415,-280.8166,419.5875,0,0,0,0,100,0),
+(@PATH,8,2124.459,-278.4777,419.6088,0,0,0,0,100,0),
+(@PATH,9,2121.098,-276.7148,419.5924,0,0,0,0,100,0),
+(@PATH,10,2119.281,-273.4217,419.6069,0,0,0,0,100,0),
+(@PATH,11,2116.933,-270.4605,419.5851,0,0,0,0,100,0),
+(@PATH,12,2116.359,-266.7142,419.6042,0,0,0,0,100,0),
+(@PATH,13,2115.436,-263.0562,419.5847,0,0,0,0,100,0),
+(@PATH,14,2116.543,-259.411,419.6082,0,0,0,0,100,0),
+(@PATH,15,2116.943,-255.605,419.5851,0,0,0,0,100,0),
+(@PATH,16,2119.377,-252.7493,419.6096,0,0,0,0,100,0),
+(@PATH,17,2121.183,-249.3546,419.5858,0,0,0,0,100,0),
+(@PATH,18,2124.49,-247.5925,419.6089,0,0,0,0,100,0),
+(@PATH,19,2127.329,-245.1714,419.5925,0,0,0,0,100,0),
+(@PATH,20,2131.097,-244.8609,419.6089,0,0,0,0,100,0),
+(@PATH,21,2134.792,-243.7036,419.585,0,0,0,0,100,0),
+(@PATH,22,2138.466,-244.3162,419.5979,0,0,0,0,100,0),
+(@PATH,23,2142.386,-244.7266,419.5746,0,0,0,0,100,0),
+(@PATH,24,2145.455,-247.1502,419.5968,0,0,0,0,100,0),
+(@PATH,25,2148.564,-249.0781,419.5791,0,0,0,0,100,0),
+(@PATH,26,2150.63,-252.4069,419.598,0,0,0,0,100,0),
+(@PATH,27,2153.104,-255.5907,419.5758,0,0,0,0,100,0),
+(@PATH,28,2153.286,-259.4698,419.6053,0,0,0,0,100,0),
+(@PATH,29,2154.193,-263.0425,419.6039,0,0,0,0,100,0),
+(@PATH,30,2153.279,-266.768,419.6026,0,0,0,0,100,0),
+(@PATH,31,2152.758,-270.5462,419.5822,0,0,0,0,100,0),
+(@PATH,32,2150.38,-273.4614,419.605,0,0,0,0,100,0);
diff --git a/sql/updates/world/master/2020_06_14_10_world_2017_05_24_00_world.sql b/sql/updates/world/master/2020_06_14_10_world_2017_05_24_00_world.sql
new file mode 100644
index 00000000000..5d9655ebf49
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_10_world_2017_05_24_00_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `quest_template_addon` SET `PrevQuestID`=12976 WHERE `id`=12977;
diff --git a/sql/updates/world/master/2020_06_14_11_world_2017_05_17_00_world.sql b/sql/updates/world/master/2020_06_14_11_world_2017_05_17_00_world.sql
new file mode 100644
index 00000000000..3b946f6006b
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_11_world_2017_05_17_00_world.sql
@@ -0,0 +1,2 @@
+--
+DELETE FROM `creature_addon` WHERE `guid` IN (136274,136490,136555);
diff --git a/sql/updates/world/master/2020_06_14_12_world_2017_05_22_00_world.sql b/sql/updates/world/master/2020_06_14_12_world_2017_05_22_00_world.sql
new file mode 100644
index 00000000000..32a484f4dfb
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_12_world_2017_05_22_00_world.sql
@@ -0,0 +1,25 @@
+--
+DELETE FROM `creature` WHERE `guid` IN (79380,79383,79609,79614,79626,79631,79636,79650,79876,79895,79899,79921,80289,80295,80299,80300,80303,80311,80312,80315,80316,80323);
+INSERT INTO `creature` (`guid`, `id`, `map`, `spawnDifficulties`, `PhaseId`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `curhealth`, `curmana`, `MovementType`) VALUES
+(79380, 28603, 571, '0', 0, 0, 0, 6022.67, -2049.14, 238.189, 1.46482, 600, 10, 0, 0, 1),
+(79383, 28603, 571, '0', 0, 0, 0, 6042.88, -2119.83, 239.522, 5.55282, 600, 10, 0, 0, 1),
+(79609, 28603, 571, '0', 0, 0, 0, 6101.08, -2157.18, 239.578, 5.52926, 600, 10, 0, 0, 1),
+(79614, 28603, 571, '0', 0, 0, 0, 6176.72, -2208.48, 241.65, 0.110007, 600, 10, 0, 0, 1),
+(79626, 28603, 571, '0', 0, 0, 0, 6227.74, -2193.69, 236.211, 0.663713, 600, 10, 0, 0, 1),
+(79631, 28603, 571, '0', 0, 0, 0, 6270.34, -2053.92, 238.548, 1.23705, 600, 10, 0, 0, 1),
+(79636, 28603, 571, '0', 0, 0, 0, 6069.51, -1913.87, 236.212, 2.78429, 600, 10, 0, 0, 1),
+(79650, 28603, 571, '0', 0, 0, 0, 6017.94, -1903.71, 239.384, 3.56183, 600, 10, 0, 0, 1),
+(79876, 28603, 571, '0', 0, 0, 0, 5981.49, -1963.15, 237.669, 4.15088, 600, 10, 0, 0, 1),
+(79895, 28603, 571, '0', 0, 0, 0, 6017.39, -2106.46, 243.382, 5.40752, 600, 10, 0, 0, 1),
+(79899, 28603, 571, '0', 0, 0, 0, 5275.12, -1678.04, 236.349, 1.1703, 600, 10, 0, 0, 1),
+(79921, 28603, 571, '0', 0, 0, 0, 5224.69, -1751.98, 235.717, 3.17306, 600, 10, 0, 0, 1),
+(80289, 28603, 571, '0', 0, 0, 0, 5154.48, -1745.88, 238.291, 3.26731, 600, 10, 0, 0, 1),
+(80295, 28603, 571, '0', 0, 0, 0, 5082.87, -1725.64, 235.624, 3.55791, 600, 10, 0, 0, 1),
+(80299, 28603, 571, '0', 0, 0, 0, 5034.49, -1655.17, 240.16, 1.8693, 600, 10, 0, 0, 1),
+(80300, 28603, 571, '0', 0, 0, 0, 5069.11, -1540.09, 240.561, 6.1183, 600, 10, 0, 0, 1),
+(80303, 28603, 571, '0', 0, 0, 0, 5099.29, -1559.64, 238.941, 0.624444, 600, 10, 0, 0, 1),
+(80311, 28603, 571, '0', 0, 0, 0, 6183.62, -2102.73, 235.653, 3.426750, 600, 10, 0, 0, 1),
+(80312, 28603, 571, '0', 0, 0, 0, 6113.59, -2105.41, 234.909, 0.441447, 600, 10, 0, 0, 1),
+(80315, 28603, 571, '0', 0, 0, 0, 6091.98, -2019.44, 235.639, 1.670596, 600, 10, 0, 0, 1),
+(80316, 28603, 571, '0', 0, 0, 0, 6199.66, -1957.45, 234.049, 1.207211, 600, 10, 0, 0, 1),
+(80323, 28603, 571, '0', 0, 0, 0, 6242.41, -2003.27, 234.282, 4.150887, 600, 10, 0, 0, 1);
diff --git a/sql/updates/world/master/2020_06_14_13_world_2017_05_23_00_world.sql b/sql/updates/world/master/2020_06_14_13_world_2017_05_23_00_world.sql
new file mode 100644
index 00000000000..635d13558d6
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_13_world_2017_05_23_00_world.sql
@@ -0,0 +1,2 @@
+-- correct typo in account set gmlevel command help
+UPDATE `command` SET `help`="Syntax: .account set gmlevel [$account] #level [#realmID]\r\n\r\nSet the security level for targeted player (can't be used at self) or for account $name to a level of #level on the realm #realmID.\r\n\r\n#level may range from 0 to 3.\r\n\r\n#realmID may be -1 for all realms." WHERE `name`='account set gmlevel';
diff --git a/sql/updates/world/master/2020_06_14_14_world_2017_05_25_00_world.sql b/sql/updates/world/master/2020_06_14_14_world_2017_05_25_00_world.sql
new file mode 100644
index 00000000000..f8a1e0e2bfd
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_14_world_2017_05_25_00_world.sql
@@ -0,0 +1,7 @@
+UPDATE `smart_scripts` SET `link`=13 WHERE `entryorguid`=28213 AND `source_type`=0 AND `id`IN(8,10);
+UPDATE `smart_scripts` SET `event_type`=7 WHERE `entryorguid`=28213 AND `source_type`=0 AND `id`=9 AND `link`=10;
+DELETE FROM `smart_scripts` WHERE `entryorguid` =28213 AND `source_type`=0 AND `id`IN(13,14,6);
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(28213, 0, 13, 0, 61, 0, 100, 512, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hardknuckle Matriarch - On Respawn - Set Passive'),
+(28213, 0, 14, 0, 61, 0, 100, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 21, 500, 0, 0, 0, 0, 0, 0, 'Hardknuckle Matriarch - On Data Set 1 1 - Start Attacking'),
+(28213, 0, 6, 14, 61, 0, 100, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Hardknuckle Matriarch - On Data Set 1 1 - Set Aggresive');
diff --git a/sql/updates/world/master/2020_06_14_15_world_2017_05_24_01_world.sql b/sql/updates/world/master/2020_06_14_15_world_2017_05_24_01_world.sql
new file mode 100644
index 00000000000..2eb3abfea9a
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_15_world_2017_05_24_01_world.sql
@@ -0,0 +1,9 @@
+--
+UPDATE `gameobject_addon` SET `invisibilityType`=9, `invisibilityValue`=1000 WHERE `guid`=270;
+UPDATE `gameobject_addon` SET `invisibilityType`=8, `invisibilityValue`=1000 WHERE `guid`=21077;
+UPDATE `gameobject_addon` SET `invisibilityType`=5, `invisibilityValue`=1000 WHERE `guid`=21079;
+DELETE FROM `spell_area` WHERE `spell` IN (56773,56772,56774) AND `area`=4438;
+INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `flags`, `quest_start_status`, `quest_end_status`) VALUES
+(56773, 4438, 12987, 0, 0, 0, 2, 3, 66, 0),
+(56772, 4438, 13001, 0, 0, 0, 2, 3, 64, 0),
+(56774, 4438, 12976, 0, 0, 0, 2, 3, 64, 0);
diff --git a/sql/updates/world/master/2020_06_14_16_world_2017_05_25_01_world.sql b/sql/updates/world/master/2020_06_14_16_world_2017_05_25_01_world.sql
new file mode 100644
index 00000000000..eb91c138ca6
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_16_world_2017_05_25_01_world.sql
@@ -0,0 +1 @@
+UPDATE `spell_proc` SET `AttributesMask`=0x2 WHERE `SpellId`=64890;
diff --git a/sql/updates/world/master/2020_06_14_17_world_2017_05_28_05_world.sql b/sql/updates/world/master/2020_06_14_17_world_2017_05_28_05_world.sql
new file mode 100644
index 00000000000..0f85da3fb9e
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_17_world_2017_05_28_05_world.sql
@@ -0,0 +1,37 @@
+--
+UPDATE `creature_text` SET `BroadcastTextId`=22882 WHERE `CreatureID`=24151 AND `GroupID`=0 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=22880 WHERE `CreatureID`=24151 AND `GroupID`=0 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=22881 WHERE `CreatureID`=24151 AND `GroupID`=0 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=22698 WHERE `CreatureID`=24216 AND `GroupID`=0 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=22701 WHERE `CreatureID`=24216 AND `GroupID`=0 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=22699 WHERE `CreatureID`=24216 AND `GroupID`=0 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=22702 WHERE `CreatureID`=24216 AND `GroupID`=0 AND `ID`=3;
+UPDATE `creature_text` SET `BroadcastTextId`=22697 WHERE `CreatureID`=24216 AND `GroupID`=0 AND `ID`=4;
+UPDATE `creature_text` SET `BroadcastTextId`=22700 WHERE `CreatureID`=24216 AND `GroupID`=0 AND `ID`=5;
+UPDATE `creature_text` SET `BroadcastTextId`=22953 WHERE `CreatureID`=24216 AND `GroupID`=1 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=22957 WHERE `CreatureID`=24216 AND `GroupID`=1 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=22954 WHERE `CreatureID`=24216 AND `GroupID`=1 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=22955 WHERE `CreatureID`=24216 AND `GroupID`=1 AND `ID`=3;
+UPDATE `creature_text` SET `BroadcastTextId`=22956 WHERE `CreatureID`=24216 AND `GroupID`=1 AND `ID`=4;
+UPDATE `creature_text` SET `BroadcastTextId`=22698 WHERE `CreatureID`=24249 AND `GroupID`=0 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=22701 WHERE `CreatureID`=24249 AND `GroupID`=0 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=22699 WHERE `CreatureID`=24249 AND `GroupID`=0 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=22815 WHERE `CreatureID`=24249 AND `GroupID`=0 AND `ID`=3;
+UPDATE `creature_text` SET `BroadcastTextId`=22813 WHERE `CreatureID`=24249 AND `GroupID`=0 AND `ID`=4;
+UPDATE `creature_text` SET `BroadcastTextId`=22814 WHERE `CreatureID`=24249 AND `GroupID`=0 AND `ID`=5;
+UPDATE `creature_text` SET `BroadcastTextId`=23082 WHERE `CreatureID`=24249 AND `GroupID`=1 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23083 WHERE `CreatureID`=24249 AND `GroupID`=1 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=23084 WHERE `CreatureID`=24249 AND `GroupID`=1 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=22698 WHERE `CreatureID`=24250 AND `GroupID`=0 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=22701 WHERE `CreatureID`=24250 AND `GroupID`=0 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=22699 WHERE `CreatureID`=24250 AND `GroupID`=0 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=22815 WHERE `CreatureID`=24250 AND `GroupID`=0 AND `ID`=3;
+UPDATE `creature_text` SET `BroadcastTextId`=22813 WHERE `CreatureID`=24250 AND `GroupID`=0 AND `ID`=4;
+UPDATE `creature_text` SET `BroadcastTextId`=24847 WHERE `CreatureID`=24250 AND `GroupID`=0 AND `ID`=5;
+UPDATE `creature_text` SET `BroadcastTextId`=22859 WHERE `CreatureID`=24250 AND `GroupID`=1 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=22860 WHERE `CreatureID`=24250 AND `GroupID`=1 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=22857 WHERE `CreatureID`=24250 AND `GroupID`=1 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=23076 WHERE `CreatureID`=24250 AND `GroupID`=2 AND `ID`=0;
+UPDATE `creature_text` SET `BroadcastTextId`=23077 WHERE `CreatureID`=24250 AND `GroupID`=2 AND `ID`=1;
+UPDATE `creature_text` SET `BroadcastTextId`=23078 WHERE `CreatureID`=24250 AND `GroupID`=2 AND `ID`=2;
+UPDATE `creature_text` SET `BroadcastTextId`=23079 WHERE `CreatureID`=24250 AND `GroupID`=2 AND `ID`=3;
diff --git a/sql/updates/world/master/2020_06_14_18_world_2017_05_29_00_world.sql b/sql/updates/world/master/2020_06_14_18_world_2017_05_29_00_world.sql
new file mode 100644
index 00000000000..6282e1c7b69
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_18_world_2017_05_29_00_world.sql
@@ -0,0 +1,3 @@
+DELETE FROM `command` WHERE `name` = 'debug play music';
+INSERT INTO `command` (`name`,`permission`,`help`) VALUES
+('debug play music', 855, 'Syntax: .debug play music #musicId\nPlay music with #musicId.\nMusic will be played only for you. Other players will not hear this.');
diff --git a/sql/updates/world/master/2020_06_14_19_world_2017_05_28_00_world.sql b/sql/updates/world/master/2020_06_14_19_world_2017_05_28_00_world.sql
new file mode 100644
index 00000000000..964970806f3
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_19_world_2017_05_28_00_world.sql
@@ -0,0 +1,2 @@
+UPDATE `smart_scripts` SET `event_flags`=`event_flags`|0x200 WHERE `entryorguid`=28750 AND `source_type`=0 AND `id` IN(0,2,4);
+UPDATE `smart_scripts` SET `event_flags`=`event_flags`|0x200 WHERE `entryorguid`=2875000 AND `source_type`=9;
diff --git a/sql/updates/world/master/2020_06_14_20_world_2017_05_28_01_world.sql b/sql/updates/world/master/2020_06_14_20_world_2017_05_28_01_world.sql
new file mode 100644
index 00000000000..4851dcf6986
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_20_world_2017_05_28_01_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `creature` WHERE `guid` IN (129652, 129656, 129651, 129655, 129644,130577,130842,130581,130590,130582,130597,130848,130847,130846,130723,130849,130739,130855,130745,130746,130742,130748,130702,130701,130853,130703,130557,130573,130558,130700,130691,130692,130693,130834,130832,130835,130697,130694,130836,130637,130641,130838,130696,130840,130603,130685,130687,130613,130688,130686,129733,129732,129774,129765,129767,129803,129783);
+DELETE FROM `creature_addon` WHERE `guid` IN (129652, 129656, 129651, 129655, 129644,130577,130842,130581,130590,130582,130597,130848,130847,130846,130723,130849,130739,130855,130745,130746,130742,130748,130702,130701,130853,130703,130557,130573,130558,130700,130691,130692,130693,130834,130832,130835,130697,130694,130836,130637,130641,130838,130696,130840,130603,130685,130687,130613,130688,130686,129733,129732,129774,129765,129767,129803,129783);
+DELETE FROM `waypoint_data` WHERE `id` IN (1296520, 1296560, 1296510, 1296550, 1296440);
diff --git a/sql/updates/world/master/2020_06_14_21_world_2017_05_28_03_world.sql b/sql/updates/world/master/2020_06_14_21_world_2017_05_28_03_world.sql
new file mode 100644
index 00000000000..a9ffb21052a
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_21_world_2017_05_28_03_world.sql
@@ -0,0 +1,2 @@
+UPDATE `conditions` SET `SourceEntry`=3 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10118 AND `SourceEntry`=5 AND `ConditionTypeOrReference`=17 and `ConditionValue1`=1288;
+UPDATE `conditions` SET `SourceEntry`=5 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10118 AND `SourceEntry`=3 AND `ConditionTypeOrReference`=17 and `ConditionValue1` IN(1360,41);
diff --git a/sql/updates/world/master/2020_06_14_22_world_2017_06_02_00_world.sql b/sql/updates/world/master/2020_06_14_22_world_2017_06_02_00_world.sql
new file mode 100644
index 00000000000..96abdae5c20
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_22_world_2017_06_02_00_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature` SET `MovementType`=1 WHERE `guid` IN (51879,51914);
diff --git a/sql/updates/world/master/2020_06_14_23_world_2017_06_02_01_world.sql b/sql/updates/world/master/2020_06_14_23_world_2017_06_02_01_world.sql
new file mode 100644
index 00000000000..fd00cce104e
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_23_world_2017_06_02_01_world.sql
@@ -0,0 +1,3 @@
+--
+UPDATE `creature_template` SET `AIName`='NullCreatureAI' WHERE `AIName`='NullAI';
+UPDATE `creature` SET `spawndist`=5 WHERE `guid` IN (51879,51914);
diff --git a/sql/updates/world/master/2020_06_14_24_world_2017_06_02_02_world.sql b/sql/updates/world/master/2020_06_14_24_world_2017_06_02_02_world.sql
new file mode 100644
index 00000000000..1ff1d82e05c
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_24_world_2017_06_02_02_world.sql
@@ -0,0 +1,7 @@
+--
+DELETE FROM `creature` WHERE `guid` IN (80342, 80351, 80364, 80378);
+INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `PhaseId`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
+(80342, 26202, 571, 0, 0, '0', 0, 0, 0, 3247.804, 3688.892, 21.705, 3.158267, 300, 7, 0, 1, 0, 1, 0, 0, 0, -1),
+(80351, 26202, 571, 0, 0, '0', 0, 0, 0, 3180.858, 3820.200, 28.555, 3.158267, 300, 7, 0, 1, 0, 1, 0, 0, 0, -1),
+(80364, 26202, 571, 0, 0, '0', 0, 0, 0, 3190.193, 3852.021, 27.972, 3.158267, 300, 7, 0, 1, 0, 1, 0, 0, 0, -1),
+(80378, 26202, 571, 0, 0, '0', 0, 0, 0, 3158.872, 3841.474, 25.945, 3.158267, 300, 7, 0, 1, 0, 1, 0, 0, 0, -1);
diff --git a/sql/updates/world/master/2020_06_14_25_world_2017_06_03_00_world.sql b/sql/updates/world/master/2020_06_14_25_world_2017_06_03_00_world.sql
new file mode 100644
index 00000000000..75b15ae7e9b
--- /dev/null
+++ b/sql/updates/world/master/2020_06_14_25_world_2017_06_03_00_world.sql
@@ -0,0 +1,2 @@
+--
+UPDATE `creature_template` SET `AIName`='' WHERE `entry`=12999;
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index 2f2461b5ab0..160b58a9742 100644
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -32,11 +32,11 @@
// AggressorAI
/////////////////
-int AggressorAI::Permissible(const Creature* creature)
+int32 AggressorAI::Permissible(Creature const* creature)
{
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
if (!creature->IsCivilian() && !creature->IsNeutralToAll())
- return PERMIT_BASE_PROACTIVE;
+ return PERMIT_BASE_REACTIVE;
return PERMIT_BASE_NO;
}
@@ -344,3 +344,11 @@ void VehicleAI::CheckConditions(uint32 diff)
else
m_ConditionsTimer -= diff;
}
+
+int32 VehicleAI::Permissible(Creature const* creature)
+{
+ if (creature->IsVehicle())
+ return PERMIT_BASE_SPECIAL;
+
+ return PERMIT_BASE_NO;
+}
diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h
index 9e4e05d9544..9082ad515e8 100644
--- a/src/server/game/AI/CoreAI/CombatAI.h
+++ b/src/server/game/AI/CoreAI/CombatAI.h
@@ -28,7 +28,7 @@ class TC_GAME_API AggressorAI : public CreatureAI
explicit AggressorAI(Creature* c) : CreatureAI(c) { }
void UpdateAI(uint32) override;
- static int Permissible(const Creature*);
+ static int32 Permissible(Creature const* creature);
};
typedef std::vector<uint32> SpellVct;
@@ -45,7 +45,7 @@ class TC_GAME_API CombatAI : public CreatureAI
void UpdateAI(uint32 diff) override;
void SpellInterrupted(uint32 spellId, uint32 unTimeMs) override;
- static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
+ static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
protected:
EventMap events;
@@ -71,7 +71,7 @@ struct TC_GAME_API ArcherAI : public CreatureAI
void AttackStart(Unit* who) override;
void UpdateAI(uint32 diff) override;
- static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
+ static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
protected:
float m_minRange;
@@ -85,7 +85,7 @@ struct TC_GAME_API TurretAI : public CreatureAI
void AttackStart(Unit* who) override;
void UpdateAI(uint32 diff) override;
- static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
+ static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
protected:
float m_minRange;
@@ -104,7 +104,7 @@ struct TC_GAME_API VehicleAI : public CreatureAI
void AttackStart(Unit*) override { }
void OnCharmed(bool apply) override;
- static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
+ static int32 Permissible(Creature const* creature);
private:
void LoadConditions();
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.cpp b/src/server/game/AI/CoreAI/GameObjectAI.cpp
index 48caa63dbce..94fe71f449d 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.cpp
+++ b/src/server/game/AI/CoreAI/GameObjectAI.cpp
@@ -20,11 +20,8 @@
#include "GameObject.h"
#include "QuestDef.h"
-//GameObjectAI::GameObjectAI(GameObject* g) : go(g) { }
-int GameObjectAI::Permissible(const GameObject* go)
+int32 GameObjectAI::Permissible(GameObject const* /*go*/)
{
- if (go->GetAIName() == "GameObjectAI")
- return PERMIT_BASE_SPECIAL;
return PERMIT_BASE_NO;
}
@@ -35,7 +32,7 @@ uint32 GameObjectAI::GetDialogStatus(Player* /*player*/)
NullGameObjectAI::NullGameObjectAI(GameObject* g) : GameObjectAI(g) { }
-int NullGameObjectAI::Permissible(GameObject const* /*go*/)
+int32 NullGameObjectAI::Permissible(GameObject const* /*go*/)
{
return PERMIT_BASE_IDLE;
}
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index 655035d505b..4bfc6c7a2f3 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -46,7 +46,7 @@ class TC_GAME_API GameObjectAI
virtual void SetGUID(uint64 /*guid*/, int32 /*id = 0 */) { }
virtual uint64 GetGUID(int32 /*id = 0 */) const { return 0; }
- static int Permissible(GameObject const* go);
+ static int32 Permissible(GameObject const* /*go*/);
// Called when a player opens a gossip dialog with the gameobject.
virtual bool GossipHello(Player* /*player*/, bool /*reportUse*/) { return false; }
@@ -88,6 +88,6 @@ class TC_GAME_API NullGameObjectAI : public GameObjectAI
void UpdateAI(uint32 /*diff*/) override { }
- static int Permissible(GameObject const* /*go*/);
+ static int32 Permissible(GameObject const* /*go*/);
};
#endif
diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp
index f9d3b96cadb..2b358945bd9 100644
--- a/src/server/game/AI/CoreAI/GuardAI.cpp
+++ b/src/server/game/AI/CoreAI/GuardAI.cpp
@@ -26,10 +26,10 @@ GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature)
{
}
-int GuardAI::Permissible(Creature const* creature)
+int32 GuardAI::Permissible(Creature const* creature)
{
if (creature->IsGuard())
- return PERMIT_BASE_SPECIAL;
+ return PERMIT_BASE_PROACTIVE;
return PERMIT_BASE_NO;
}
diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h
index a731e160e90..037094cff4b 100644
--- a/src/server/game/AI/CoreAI/GuardAI.h
+++ b/src/server/game/AI/CoreAI/GuardAI.h
@@ -27,7 +27,7 @@ class TC_GAME_API GuardAI : public ScriptedAI
public:
explicit GuardAI(Creature* creature);
- static int Permissible(Creature const* creature);
+ static int32 Permissible(Creature const* creature);
void UpdateAI(uint32 diff) override;
bool CanSeeAlways(WorldObject const* obj) override;
diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp
index 417a3c9bf04..5c3e8026600 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.cpp
+++ b/src/server/game/AI/CoreAI/PassiveAI.cpp
@@ -22,6 +22,17 @@ PassiveAI::PassiveAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASS
PossessedAI::PossessedAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
NullCreatureAI::NullCreatureAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); }
+int32 NullCreatureAI::Permissible(Creature const* creature)
+{
+ if (creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK))
+ return PERMIT_BASE_PROACTIVE + 50;
+
+ if (creature->IsTrigger())
+ return PERMIT_BASE_REACTIVE;
+
+ return PERMIT_BASE_IDLE;
+}
+
void PassiveAI::UpdateAI(uint32)
{
if (me->IsInCombat() && me->getAttackers().empty())
@@ -76,8 +87,24 @@ void CritterAI::EnterEvadeMode(EvadeReason why)
CreatureAI::EnterEvadeMode(why);
}
+int32 CritterAI::Permissible(Creature const* creature)
+{
+ if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
+ return PERMIT_BASE_PROACTIVE;
+
+ return PERMIT_BASE_NO;
+}
+
void TriggerAI::IsSummonedBy(Unit* summoner)
{
if (me->m_spells[0])
me->CastSpell(me, me->m_spells[0], false, nullptr, nullptr, summoner->GetGUID());
}
+
+int32 TriggerAI::Permissible(Creature const* creature)
+{
+ if (creature->IsTrigger() && creature->m_spells[0])
+ return PERMIT_BASE_PROACTIVE;
+
+ return PERMIT_BASE_NO;
+}
diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h
index 43ad670e0df..41d4c2bfb12 100644
--- a/src/server/game/AI/CoreAI/PassiveAI.h
+++ b/src/server/game/AI/CoreAI/PassiveAI.h
@@ -29,7 +29,7 @@ class TC_GAME_API PassiveAI : public CreatureAI
void AttackStart(Unit*) override { }
void UpdateAI(uint32) override;
- static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
+ static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
};
class TC_GAME_API PossessedAI : public CreatureAI
@@ -47,7 +47,7 @@ class TC_GAME_API PossessedAI : public CreatureAI
void OnCharmed(bool /*apply*/) override;
- static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
+ static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
};
class TC_GAME_API NullCreatureAI : public CreatureAI
@@ -61,7 +61,7 @@ class TC_GAME_API NullCreatureAI : public CreatureAI
void EnterEvadeMode(EvadeReason /*why*/) override { }
void OnCharmed(bool /*apply*/) override { }
- static int Permissible(const Creature*) { return PERMIT_BASE_IDLE; }
+ static int32 Permissible(Creature const* creature);
};
class TC_GAME_API CritterAI : public PassiveAI
@@ -71,6 +71,8 @@ class TC_GAME_API CritterAI : public PassiveAI
void DamageTaken(Unit* done_by, uint32& /*damage*/) override;
void EnterEvadeMode(EvadeReason why) override;
+
+ static int32 Permissible(Creature const* creature);
};
class TC_GAME_API TriggerAI : public NullCreatureAI
@@ -78,6 +80,8 @@ class TC_GAME_API TriggerAI : public NullCreatureAI
public:
explicit TriggerAI(Creature* c) : NullCreatureAI(c) { }
void IsSummonedBy(Unit* summoner) override;
+
+ static int32 Permissible(Creature const* creature);
};
#endif
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index a39e4a8dfc0..c16e1f945eb 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -31,10 +31,14 @@
#include "SpellMgr.h"
#include "Util.h"
-int PetAI::Permissible(const Creature* creature)
+int32 PetAI::Permissible(Creature const* creature)
{
- if (creature->IsPet())
- return PERMIT_BASE_SPECIAL;
+ if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
+ {
+ if (reinterpret_cast<Guardian const*>(creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
+ return PERMIT_BASE_PROACTIVE;
+ return PERMIT_BASE_REACTIVE;
+ }
return PERMIT_BASE_NO;
}
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index c712d42651d..4455c1cd494 100644
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -33,7 +33,7 @@ class TC_GAME_API PetAI : public CreatureAI
explicit PetAI(Creature* c);
void UpdateAI(uint32) override;
- static int Permissible(const Creature*);
+ static int32 Permissible(Creature const* creature);
void KilledUnit(Unit* /*victim*/) override;
void AttackStart(Unit* target) override;
diff --git a/src/server/game/AI/CoreAI/ReactorAI.cpp b/src/server/game/AI/CoreAI/ReactorAI.cpp
index 836cc1e0358..8b15bed1908 100644
--- a/src/server/game/AI/CoreAI/ReactorAI.cpp
+++ b/src/server/game/AI/CoreAI/ReactorAI.cpp
@@ -18,7 +18,7 @@
#include "ReactorAI.h"
#include "Creature.h"
-int ReactorAI::Permissible(const Creature* creature)
+int32 ReactorAI::Permissible(Creature const* creature)
{
if (creature->IsCivilian() || creature->IsNeutralToAll())
return PERMIT_BASE_REACTIVE;
diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h
index fa0bd2d8ee1..be76f855781 100644
--- a/src/server/game/AI/CoreAI/ReactorAI.h
+++ b/src/server/game/AI/CoreAI/ReactorAI.h
@@ -29,6 +29,6 @@ class TC_GAME_API ReactorAI : public CreatureAI
void MoveInLineOfSight(Unit*) override { }
void UpdateAI(uint32 diff) override;
- static int Permissible(const Creature*);
+ static int32 Permissible(Creature const* creature);
};
#endif
diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp
index 4d2bda5faa0..c727ea45003 100644
--- a/src/server/game/AI/CoreAI/TotemAI.cpp
+++ b/src/server/game/AI/CoreAI/TotemAI.cpp
@@ -24,7 +24,7 @@
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
-int TotemAI::Permissible(Creature const* creature)
+int32 TotemAI::Permissible(Creature const* creature)
{
if (creature->IsTotem())
return PERMIT_BASE_PROACTIVE;
diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h
index 2938190c771..fd25ca86df6 100644
--- a/src/server/game/AI/CoreAI/TotemAI.h
+++ b/src/server/game/AI/CoreAI/TotemAI.h
@@ -35,7 +35,7 @@ class TC_GAME_API TotemAI : public CreatureAI
void EnterEvadeMode(EvadeReason /*why*/) override;
void UpdateAI(uint32 diff) override;
- static int Permissible(Creature const* creature);
+ static int32 Permissible(Creature const* creature);
private:
ObjectGuid i_victimGuid;
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index b274a4794d1..41e6ab2501d 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -204,7 +204,7 @@ class TC_GAME_API CreatureAI : public UnitAI
bool m_MoveInLineOfSight_locked;
};
-enum Permitions
+enum Permitions : int32
{
PERMIT_BASE_NO = -1,
PERMIT_BASE_IDLE = 1,
diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h
index 656435ad632..92e757d835d 100644
--- a/src/server/game/AI/CreatureAIFactory.h
+++ b/src/server/game/AI/CreatureAIFactory.h
@@ -18,66 +18,34 @@
#ifndef TRINITY_CREATUREAIFACTORY_H
#define TRINITY_CREATUREAIFACTORY_H
-//#include "Policies/Singleton.h"
#include "ObjectRegistry.h"
#include "FactoryHolder.h"
-#include "GameObjectAI.h"
-struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature>
+typedef FactoryHolder<CreatureAI, Creature> CreatureAICreator;
+
+struct SelectableAI : public CreatureAICreator, public Permissible<Creature>
{
- SelectableAI(const char* id) : FactoryHolder<CreatureAI>(id) { }
+ SelectableAI(std::string const& name) : CreatureAICreator(name), Permissible<Creature>() { }
};
template<class REAL_AI>
struct CreatureAIFactory : public SelectableAI
{
- CreatureAIFactory(const char* name) : SelectableAI(name) { }
+ CreatureAIFactory(std::string const& name) : SelectableAI(name) { }
- CreatureAI* Create(void*) const override;
+ inline CreatureAI* Create(Creature* c) const override
+ {
+ return new REAL_AI(c);
+ }
- int Permit(const Creature* c) const override { return REAL_AI::Permissible(c); }
+ int32 Permit(Creature const* c) const override
+ {
+ return REAL_AI::Permissible(c);
+ }
};
-template<class REAL_AI>
-inline CreatureAI*
-CreatureAIFactory<REAL_AI>::Create(void* data) const
-{
- Creature* creature = reinterpret_cast<Creature*>(data);
- return (new REAL_AI(creature));
-}
-
-typedef FactoryHolder<CreatureAI> CreatureAICreator;
-typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry;
+typedef CreatureAICreator::FactoryHolderRegistry CreatureAIRegistry;
#define sCreatureAIRegistry CreatureAIRegistry::instance()
-//GO
-struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject>
-{
- SelectableGameObjectAI(const char* id) : FactoryHolder<GameObjectAI>(id) { }
-};
-
-template<class REAL_GO_AI>
-struct GameObjectAIFactory : public SelectableGameObjectAI
-{
- GameObjectAIFactory(const char* name) : SelectableGameObjectAI(name) { }
-
- GameObjectAI* Create(void*) const override;
-
- int Permit(const GameObject* g) const override { return REAL_GO_AI::Permissible(g); }
-};
-
-template<class REAL_GO_AI>
-inline GameObjectAI*
-GameObjectAIFactory<REAL_GO_AI>::Create(void* data) const
-{
- GameObject* go = reinterpret_cast<GameObject*>(data);
- return (new REAL_GO_AI(go));
-}
-
-typedef FactoryHolder<GameObjectAI> GameObjectAICreator;
-typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry;
-
-#define sGameObjectAIRegistry GameObjectAIRegistry::instance()
-
#endif
diff --git a/src/server/game/AI/CreatureAIRegistry.cpp b/src/server/game/AI/CreatureAIRegistry.cpp
index 9aab7376ab2..34cc64af22b 100644
--- a/src/server/game/AI/CreatureAIRegistry.cpp
+++ b/src/server/game/AI/CreatureAIRegistry.cpp
@@ -22,10 +22,11 @@
#include "PetAI.h"
#include "TotemAI.h"
#include "RandomMovementGenerator.h"
-#include "MovementGeneratorImpl.h"
+#include "MovementGenerator.h"
#include "CreatureAIRegistry.h"
#include "WaypointMovementGenerator.h"
#include "CreatureAIFactory.h"
+#include "GameObjectAIFactory.h"
#include "SmartAI.h"
namespace AIRegistry
@@ -47,10 +48,12 @@ namespace AIRegistry
(new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf();
(new CreatureAIFactory<SmartAI>("SmartAI"))->RegisterSelf();
+ (new GameObjectAIFactory<NullGameObjectAI>("NullGameObjectAI"))->RegisterSelf();
(new GameObjectAIFactory<GameObjectAI>("GameObjectAI"))->RegisterSelf();
(new GameObjectAIFactory<SmartGameObjectAI>("SmartGameObjectAI"))->RegisterSelf();
- (new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf();
- (new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf();
+ (new IdleMovementFactory())->RegisterSelf();
+ (new MovementGeneratorFactory<RandomMovementGenerator<Creature>>(RANDOM_MOTION_TYPE))->RegisterSelf();
+ (new MovementGeneratorFactory<WaypointMovementGenerator<Creature>>(WAYPOINT_MOTION_TYPE))->RegisterSelf();
}
}
diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp
index 487511eff3e..b7181a35f76 100644
--- a/src/server/game/AI/CreatureAISelector.cpp
+++ b/src/server/game/AI/CreatureAISelector.cpp
@@ -17,130 +17,94 @@
#include "Creature.h"
#include "CreatureAISelector.h"
-#include "GameObject.h"
-#include "PassiveAI.h"
+#include "CreatureAIFactory.h"
#include "Log.h"
#include "MovementGenerator.h"
-#include "TemporarySummon.h"
-#include "CreatureAIFactory.h"
+
+#include "GameObject.h"
+#include "GameObjectAIFactory.h"
+
#include "ScriptMgr.h"
namespace FactorySelector
{
- CreatureAI* selectAI(Creature* creature)
+ template <class T, class Value>
+ inline int32 GetPermitFor(T const* obj, Value const& value)
{
- const CreatureAICreator* ai_factory = NULL;
-
- if (creature->IsPet())
- ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
-
- //scriptname in db
- if (!ai_factory)
- if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
- return scriptedAI;
+ Permissible<T> const* const p = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(value.second.get()));
+ return p->Permit(obj);
+ }
- // AIname in db
- std::string ainame=creature->GetAIName();
- if (!ai_factory && !ainame.empty())
- ai_factory = sCreatureAIRegistry->GetRegistryItem(ainame);
+ template <class T>
+ struct PermissibleOrderPred
+ {
+ public:
+ PermissibleOrderPred(T const* obj) : _obj(obj) { }
- // select by NPC flags
- if (!ai_factory)
+ template <class Value>
+ bool operator()(Value const& left, Value const& right) const
{
- if (creature->IsVehicle())
- ai_factory = sCreatureAIRegistry->GetRegistryItem("VehicleAI");
- else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
- ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
- else if (creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK))
- ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
- else if (creature->IsGuard())
- ai_factory = sCreatureAIRegistry->GetRegistryItem("GuardAI");
- else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
- ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
- else if (creature->IsTotem())
- ai_factory = sCreatureAIRegistry->GetRegistryItem("TotemAI");
- else if (creature->IsTrigger())
- {
- if (creature->m_spells[0])
- ai_factory = sCreatureAIRegistry->GetRegistryItem("TriggerAI");
- else
- ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
- }
- else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
- ai_factory = sCreatureAIRegistry->GetRegistryItem("CritterAI");
+ return GetPermitFor(_obj, left) < GetPermitFor(_obj, right);
}
- // select by permit check
- if (!ai_factory)
- {
- int best_val = -1;
- typedef CreatureAIRegistry::RegistryMapType RMT;
- RMT const& l = sCreatureAIRegistry->GetRegisteredItems();
- for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
- {
- const CreatureAICreator* factory = iter->second;
- const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory);
- ASSERT(p);
- int val = p->Permit(creature);
- if (val > best_val)
- {
- best_val = val;
- ai_factory = p;
- }
- }
- }
+ private:
+ T const* const _obj;
+ };
- // select NullCreatureAI if not another cases
- ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
+ template <class AI, class T>
+ inline FactoryHolder<AI, T> const* SelectFactory(T* obj)
+ {
+ static_assert(std::is_same<AI, CreatureAI>::value || std::is_same<AI, GameObjectAI>::value, "Invalid template parameter");
+ static_assert(std::is_same<AI, CreatureAI>::value == std::is_same<T, Creature>::value, "Incompatible AI for type");
+ static_assert(std::is_same<AI, GameObjectAI>::value == std::is_same<T, GameObject>::value, "Incompatible AI for type");
- TC_LOG_DEBUG("scripts", "Creature %s (%s DB GUID: " UI64FMTD ") is using AI type: %s.", creature->GetName().c_str(), creature->GetGUID().ToString().c_str(), creature->GetSpawnId(), ainame.c_str());
- return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature));
- }
+ using AIRegistry = typename FactoryHolder<AI, T>::FactoryHolderRegistry;
- MovementGenerator* selectMovementGenerator(Creature* creature)
- {
- MovementGeneratorRegistry& mv_registry(*MovementGeneratorRegistry::instance());
- ASSERT(creature->GetCreatureTemplate());
- const MovementGeneratorCreator* mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType());
+ // AIName in db
+ std::string const& aiName = obj->GetAIName();
+ if (!aiName.empty())
+ return AIRegistry::instance()->GetRegistryItem(aiName);
- /* if (mv_factory == NULL)
- {
- int best_val = -1;
- StringVector l;
- mv_registry.GetRegisteredItems(l);
- for (StringVector::iterator iter = l.begin(); iter != l.end(); ++iter)
- {
- const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str());
- const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory);
- ASSERT(p != NULL);
- int val = p->Permit(creature);
- if (val > best_val)
- {
- best_val = val;
- mv_factory = p;
- }
- }
- }*/
-
- return (mv_factory == NULL ? NULL : mv_factory->Create(creature));
+ // select by permit check
+ typename AIRegistry::RegistryMapType const& items = AIRegistry::instance()->GetRegisteredItems();
+ auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<T>(obj));
+ if (itr != items.end() && GetPermitFor(obj, *itr) >= 0)
+ return itr->second.get();
+
+ // should _never_ happen, Null AI types defined as PERMIT_BASE_IDLE, it must've been found
+ ABORT();
+ return nullptr;
}
- GameObjectAI* SelectGameObjectAI(GameObject* go)
+ CreatureAI* SelectAI(Creature* creature)
{
- GameObjectAICreator const* ai_factory = NULL;
+ // special pet case, if a tamed creature uses AIName (example SmartAI) we need to override it
+ if (creature->IsPet())
+ return ASSERT_NOTNULL(sCreatureAIRegistry->GetRegistryItem("PetAI"))->Create(creature);
// scriptname in db
- if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
+ if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
return scriptedAI;
- ai_factory = sGameObjectAIRegistry->GetRegistryItem(go->GetAIName());
+ return SelectFactory<CreatureAI>(creature)->Create(creature);
+ }
- //future goAI types go here
+ MovementGenerator* SelectMovementGenerator(Unit* unit)
+ {
+ MovementGeneratorType type = IDLE_MOTION_TYPE;
+ if (unit->GetTypeId() == TYPEID_UNIT)
+ type = unit->ToCreature()->GetDefaultMovementType();
- std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key();
+ MovementGeneratorCreator const* mv_factory = sMovementGeneratorRegistry->GetRegistryItem(type);
+ return ASSERT_NOTNULL(mv_factory)->Create(unit);
+ }
- TC_LOG_DEBUG("scripts", "%s used AI is %s.", go->GetGUID().ToString().c_str(), ainame.c_str());
+ GameObjectAI* SelectGameObjectAI(GameObject* go)
+ {
+ // scriptname in db
+ if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
+ return scriptedAI;
- return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go));
+ return SelectFactory<GameObjectAI>(go)->Create(go);
}
}
diff --git a/src/server/game/AI/CreatureAISelector.h b/src/server/game/AI/CreatureAISelector.h
index d22bf0bb1e7..b4046a5e982 100644
--- a/src/server/game/AI/CreatureAISelector.h
+++ b/src/server/game/AI/CreatureAISelector.h
@@ -21,13 +21,14 @@
class CreatureAI;
class Creature;
class MovementGenerator;
+class Unit;
class GameObjectAI;
class GameObject;
namespace FactorySelector
{
- TC_GAME_API CreatureAI* selectAI(Creature*);
- TC_GAME_API MovementGenerator* selectMovementGenerator(Creature*);
- TC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject*);
+ TC_GAME_API CreatureAI* SelectAI(Creature* creature);
+ TC_GAME_API MovementGenerator* SelectMovementGenerator(Unit* unit);
+ TC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject* go);
}
#endif
diff --git a/src/server/game/AI/GameObjectAIFactory.h b/src/server/game/AI/GameObjectAIFactory.h
new file mode 100644
index 00000000000..88dcb5cbb81
--- /dev/null
+++ b/src/server/game/AI/GameObjectAIFactory.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITY_GAMEOBJECTAIFACTORY_H
+#define TRINITY_GAMEOBJECTAIFACTORY_H
+
+#include "ObjectRegistry.h"
+#include "FactoryHolder.h"
+
+class GameObject;
+class GameObjectAI;
+
+typedef FactoryHolder<GameObjectAI, GameObject> GameObjectAICreator;
+
+struct SelectableGameObjectAI : public GameObjectAICreator, public Permissible<GameObject>
+{
+ SelectableGameObjectAI(std::string const& name) : GameObjectAICreator(name), Permissible<GameObject>() { }
+};
+
+template<class REAL_GO_AI>
+struct GameObjectAIFactory : public SelectableGameObjectAI
+{
+ GameObjectAIFactory(std::string const& name) : SelectableGameObjectAI(name) { }
+
+ GameObjectAI* Create(GameObject* go) const override
+ {
+ return new REAL_GO_AI(go);
+ }
+
+ int32 Permit(GameObject const* go) const override
+ {
+ return REAL_GO_AI::Permissible(go);
+ }
+};
+
+typedef GameObjectAICreator::FactoryHolderRegistry GameObjectAIRegistry;
+
+#define sGameObjectAIRegistry GameObjectAIRegistry::instance()
+
+#endif
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 71125e716a6..bde3a192642 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -537,7 +537,7 @@ bool BossAI::CanAIAttack(Unit const* target) const
return CheckBoundary(target);
}
-void BossAI::_DespawnAtEvade(uint32 delayToRespawn, Creature* who)
+void BossAI::_DespawnAtEvade(uint32 delayToRespawn /*= 30*/, Creature* who /*= nullptr*/)
{
if (delayToRespawn < 2)
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.cpp b/src/server/game/AI/ScriptedAI/ScriptedGossip.cpp
index 0e0ad589518..33e69bf850c 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedGossip.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.cpp
@@ -19,6 +19,7 @@
#include "Creature.h"
#include "Player.h"
+uint32 GetGossipActionFor(Player* player, uint32 gossipListId) { return player->PlayerTalkClass->GetGossipOptionAction(gossipListId); }
void ClearGossipMenuFor(Player* player) { player->PlayerTalkClass->ClearMenus(); }
// Using provided text, not from DB
void AddGossipItemFor(Player* player, uint32 icon, std::string const& text, uint32 sender, uint32 action) { player->PlayerTalkClass->GetGossipMenu().AddMenuItem(-1, icon, text, sender, action, "", 0); }
diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.h b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
index 3032059d81b..6963155c94a 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedGossip.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
@@ -86,6 +86,7 @@ enum eTradeskill
GOSSIP_SENDER_SEC_STABLEMASTER = 10
};
+uint32 TC_GAME_API GetGossipActionFor(Player* player, uint32 gossipListId);
void TC_GAME_API ClearGossipMenuFor(Player* player);
// Using provided text, not from DB
void TC_GAME_API AddGossipItemFor(Player* player, uint32 icon, std::string const& text, uint32 sender, uint32 action);
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 2dd122de1ee..065ca31bee0 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -74,6 +74,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c)
mJustReset = false;
mConditionsTimer = 0;
mHasConditions = sConditionMgr->HasConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, c->GetEntry());
+
+ _gossipReturn = false;
}
bool SmartAI::IsAIControlled() const
@@ -594,13 +596,6 @@ void SmartAI::JustRespawned()
mFollowCreditType = 0;
}
-int SmartAI::Permissible(const Creature* creature)
-{
- if (creature->GetAIName() == "SmartAI")
- return PERMIT_BASE_SPECIAL;
- return PERMIT_BASE_NO;
-}
-
void SmartAI::JustReachedHome()
{
GetScript()->OnReset();
@@ -810,14 +805,16 @@ void SmartAI::SetEvadeDisabled(bool disable)
bool SmartAI::GossipHello(Player* player)
{
+ _gossipReturn = false;
GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player);
- return false;
+ return _gossipReturn;
}
bool SmartAI::GossipSelect(Player* player, uint32 menuId, uint32 gossipListId)
{
+ _gossipReturn = false;
GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, menuId, gossipListId);
- return false;
+ return _gossipReturn;
}
bool SmartAI::GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, const char* /*code*/)
@@ -962,13 +959,6 @@ void SmartAI::CheckConditions(uint32 diff)
mConditionsTimer -= diff;
}
-int SmartGameObjectAI::Permissible(const GameObject* g)
-{
- if (g->GetAIName() == "SmartGameObjectAI")
- return PERMIT_BASE_SPECIAL;
- return PERMIT_BASE_NO;
-}
-
void SmartGameObjectAI::UpdateAI(uint32 diff)
{
GetScript()->OnUpdate(diff);
@@ -995,16 +985,17 @@ void SmartGameObjectAI::Reset()
// Called when a player opens a gossip dialog with the gameobject.
bool SmartGameObjectAI::GossipHello(Player* player, bool reportUse)
{
- TC_LOG_DEBUG("scripts.ai", "SmartGameObjectAI::GossipHello");
+ _gossipReturn = false;
GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player, uint32(reportUse), 0, false, nullptr, me);
- return false;
+ return _gossipReturn;
}
// Called when a player selects a gossip item in the gameobject's gossip menu.
bool SmartGameObjectAI::GossipSelect(Player* player, uint32 sender, uint32 action)
{
+ _gossipReturn = false;
GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, sender, action, false, nullptr, me);
- return false;
+ return _gossipReturn;
}
// Called when a player selects a gossip with a code in the gameobject's gossip menu.
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 1c65c9633b9..070165efa40 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -158,7 +158,7 @@ class TC_GAME_API SmartAI : public CreatureAI
ObjectGuid GetGUID(int32 id = 0) const override;
//core related
- static int Permissible(const Creature*);
+ static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; }
// Called at movepoint reached
void MovepointReached(uint32 id);
@@ -198,6 +198,8 @@ class TC_GAME_API SmartAI : public CreatureAI
void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; }
+ void SetGossipReturn(bool val) { _gossipReturn = val; }
+
private:
bool mIsCharmed;
uint32 mFollowCreditType;
@@ -241,19 +243,22 @@ class TC_GAME_API SmartAI : public CreatureAI
void CheckConditions(uint32 diff);
bool mHasConditions;
uint32 mConditionsTimer;
+
+ // Gossip
+ bool _gossipReturn;
};
class TC_GAME_API SmartGameObjectAI : public GameObjectAI
{
public:
- SmartGameObjectAI(GameObject* g) : GameObjectAI(g) { }
+ SmartGameObjectAI(GameObject* g) : GameObjectAI(g), _gossipReturn(false) { }
~SmartGameObjectAI() { }
void UpdateAI(uint32 diff) override;
void InitializeAI() override;
void Reset() override;
SmartScript* GetScript() { return &mScript; }
- static int Permissible(const GameObject* g);
+ static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_NO; }
bool GossipHello(Player* player, bool reportUse) override;
bool GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override;
@@ -268,8 +273,13 @@ class TC_GAME_API SmartGameObjectAI : public GameObjectAI
void EventInform(uint32 eventId) override;
void SpellHit(Unit* unit, const SpellInfo* spellInfo) override;
+ void SetGossipReturn(bool val) { _gossipReturn = val; }
+
private:
SmartScript mScript;
+
+ // Gossip
+ bool _gossipReturn;
};
/// Registers scripts required by the SAI scripting system
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index ebf884133a4..a1c6d3af9b6 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2411,7 +2411,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_SEND_GOSSIP_MENU:
{
- if (!GetBaseObject())
+ if (!GetBaseObject() || !IsSmart())
break;
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d",
@@ -2421,6 +2421,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!targets)
break;
+ // override default gossip
+ if (me)
+ ENSURE_AI(SmartAI, me->AI())->SetGossipReturn(true);
+ else if (go)
+ ENSURE_AI(SmartGameObjectAI, go->AI())->SetGossipReturn(true);
+
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (Player* player = (*itr)->ToPlayer())
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 05931ce840e..68b3d673a15 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -562,17 +562,17 @@ enum RBACPermissions
RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE = 654,
RBAC_PERM_COMMAND_RELOAD_ITEM_SET_NAMES = 655,
RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS = 656,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD = 657,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE = 658,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE_TEXT = 659,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT = 660,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION = 661,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM = 662, // deprecated since Draenor DON'T reuse
- RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM_SET_NAME = 663,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_NPC_TEXT = 664, // deprecated since Draenor DON'T reuse
- RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT = 665,
- RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST = 666,
- RBAC_PERM_COMMAND_RELOAD_QUEST_LOCALE = 667,
+ RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_REWARD_LOCALE = 657,
+ RBAC_PERM_COMMAND_RELOAD_CRETURE_TEMPLATE_LOCALE = 658,
+ RBAC_PERM_COMMAND_RELOAD_CRETURE_TEXT_LOCALE = 659,
+ RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_TEMPLATE_LOCALE = 660,
+ RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION_LOCALE = 661,
+ RBAC_PERM_COMMAND_RELOAD_ITEM_TEMPLATE_LOCALE = 662, // deprecated since Draenor DON'T reus
+ RBAC_PERM_COMMAND_RELOAD_ITEM_SET_NAME_LOCALE = 663,
+ RBAC_PERM_COMMAND_RELOAD_NPC_TEXT_LOCALE = 664, // deprecated since Draenor DON'T reuse
+ RBAC_PERM_COMMAND_RELOAD_PAGE_TEXT_LOCALE = 665,
+ RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST_LOCALE = 666,
+ RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE_LOCALE = 667,
RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD = 668,
RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE = 669,
RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE = 670,
@@ -760,6 +760,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_GO_OFFSET = 852,
RBAC_PERM_COMMAND_RELOAD_CONVERSATION_TEMPLATE = 853,
RBAC_PERM_COMMAND_DEBUG_CONVERSATION = 854,
+ RBAC_PERM_COMMAND_DEBUG_PLAY_MUSIC = 855,
RBAC_PERM_COMMAND_NPC_SPAWNGROUP = 856, // reserved for dynamic_spawning
RBAC_PERM_COMMAND_NPC_DESPAWNGROUP = 857, // reserved for dynamic_spawning
RBAC_PERM_COMMAND_GOBJECT_SPAWNGROUP = 858, // reserved for dynamic_spawning
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
index 6e1bba5f1a9..62e37f5d76b 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp
@@ -57,7 +57,7 @@ BfWGCoordGY const WGGraveYard[BATTLEFIELD_WG_GRAVEYARD_MAX] =
};
uint32 const ClockWorldState[] = { 3781, 4354 };
-uint32 const WintergraspFaction[] = { 1732, 1735, 35 };
+uint32 const WintergraspFaction[] = { FACTION_ALLIANCE_GENERIC_WG, FACTION_HORDE_GENERIC_WG, FACTION_FRIENDLY };
Position const WintergraspStalkerPos = { 4948.985f, 2937.789f, 550.5172f, 1.815142f };
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index edd6d3e67ed..31345c14048 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -384,7 +384,7 @@ void BattlegroundAB::_NodeOccupied(uint8 node, Team team)
//aura should only apply to players who have accupied the node, set correct faction for trigger
if (trigger)
{
- trigger->SetFaction(team == ALLIANCE ? 84 : 83);
+ trigger->SetFaction(team == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC);
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
}
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index 3fc2cd2ad8d..ff37ce06346 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -757,7 +757,7 @@ void BattlegroundAV::PopulateNode(BG_AV_Nodes node)
DelCreature(node + 302);
return;
}
- trigger->SetFaction(owner == ALLIANCE ? 84 : 83);
+ trigger->SetFaction(owner == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC);
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
}
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index c83e1ff48b1..8c4143e0ce3 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -810,7 +810,7 @@ void BattlegroundEY::EventTeamCapturedPoint(Player* player, uint32 Point)
//aura should only apply to players who have accupied the node, set correct faction for trigger
if (trigger)
{
- trigger->SetFaction(Team == ALLIANCE ? 84 : 83);
+ trigger->SetFaction(Team == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC);
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
}
}
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 2d66f88a745..ba761b95ed0 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -978,7 +978,7 @@ bool Creature::AIM_Create(CreatureAI* ai /*= nullptr*/)
Motion_Initialize();
- i_AI = ai ? ai : FactorySelector::selectAI(this);
+ i_AI = ai ? ai : FactorySelector::SelectAI(this);
return true;
}
@@ -2048,27 +2048,34 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds const& forceRespawn
{
if (timeMSToDespawn)
{
- ForcedDespawnDelayEvent* pEvent = new ForcedDespawnDelayEvent(*this, forceRespawnTimer);
-
- m_Events.AddEvent(pEvent, m_Events.CalculateTime(timeMSToDespawn));
+ m_Events.AddEvent(new ForcedDespawnDelayEvent(*this, forceRespawnTimer), m_Events.CalculateTime(timeMSToDespawn));
return;
}
+ uint32 corpseDelay = GetCorpseDelay();
+ uint32 respawnDelay = GetRespawnDelay();
+
// do it before killing creature
DestroyForNearbyPlayers();
+ bool overrideRespawnTime = false;
if (IsAlive())
- setDeathState(JUST_DIED);
-
- bool overrideRespawnTime = true;
- if (forceRespawnTimer > Seconds::zero())
{
- SetRespawnTime(forceRespawnTimer.count());
- overrideRespawnTime = false;
+ if (forceRespawnTimer > Seconds::zero())
+ {
+ SetCorpseDelay(0);
+ SetRespawnDelay(forceRespawnTimer.count());
+ overrideRespawnTime = false;
+ }
+
+ setDeathState(JUST_DIED);
}
// Skip corpse decay time
RemoveCorpse(overrideRespawnTime, false);
+
+ SetCorpseDelay(corpseDelay);
+ SetRespawnDelay(respawnDelay);
}
void Creature::DespawnOrUnsummon(uint32 msTimeToDespawn /*= 0*/, Seconds const& forceRespawnTimer /*= 0*/)
@@ -2418,14 +2425,9 @@ bool Creature::_IsTargetAcceptable(Unit const* target) const
Unit const* targetVictim = target->getAttackerForHelper();
// if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
- if (GetVictim() == target || IsHostileTo(target))
+ if (IsInCombatWith(target) || IsHostileTo(target))
return true;
- // a player is targeting me, but I'm not hostile towards it, and not currently attacking it, the target is not acceptable
- // (players may set their victim from a distance, and doesn't mean we should attack)
- if (target->GetTypeId() == TYPEID_PLAYER && targetVictim == this)
- return false;
-
// if the target's victim is friendly, and the target is neutral, the target is acceptable
if (targetVictim && IsFriendlyTo(targetVictim))
return true;
@@ -2808,7 +2810,7 @@ uint8 Creature::GetLevelForTarget(WorldObject const* target) const
return Unit::GetLevelForTarget(target);
}
-std::string Creature::GetAIName() const
+std::string const& Creature::GetAIName() const
{
return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName;
}
@@ -2943,20 +2945,6 @@ float Creature::GetPetChaseDistance() const
return range;
}
-void Creature::SetPosition(float x, float y, float z, float o)
-{
- // prevent crash when a bad coord is sent by the client
- if (!Trinity::IsValidMapCoord(x, y, z, o))
- {
- TC_LOG_DEBUG("entities.unit", "Creature::SetPosition(%f, %f, %f) .. bad coordinates!", x, y, z);
- return;
- }
-
- GetMap()->CreatureRelocation(this, x, y, z, o);
- if (IsVehicle())
- GetVehicleKit()->RelocatePassengers();
-}
-
float Creature::GetAggroRange(Unit const* target) const
{
// Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
@@ -3217,8 +3205,7 @@ bool Creature::IsMovementPreventedByCasting() const
{
if (spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive())
if (spell->GetSpellInfo()->IsMoveAllowedChannel())
- if (HasUnitState(UNIT_STATE_CASTING))
- return true;
+ return false;
}
if (const_cast<Creature*>(this)->IsFocusing(nullptr, true))
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index cc5608bfc3d..beb9ed4d64f 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -172,7 +172,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
CreatureData const* GetCreatureData() const { return m_creatureData; }
CreatureAddon const* GetCreatureAddon() const;
- std::string GetAIName() const;
+ std::string const& GetAIName() const;
std::string GetScriptName() const;
uint32 GetScriptId() const;
@@ -282,9 +282,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void SetCannotReachTarget(bool cannotReach) { if (cannotReach == m_cannotReachTarget) return; m_cannotReachTarget = cannotReach; m_cannotReachTimer = 0; }
bool CanNotReachTarget() const { return m_cannotReachTarget; }
- void SetPosition(float x, float y, float z, float o);
- void SetPosition(const Position &pos) { SetPosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); }
-
void SetHomePosition(float x, float y, float z, float o) { m_homePosition.Relocate(x, y, z, o); }
void SetHomePosition(const Position &pos) { m_homePosition.Relocate(pos); }
void GetHomePosition(float& x, float& y, float& z, float& ori) const { m_homePosition.GetPosition(x, y, z, ori); }
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 4059e6e72d6..cd3ebd306ea 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -166,12 +166,9 @@ bool GameObject::AIM_Initialize()
return true;
}
-std::string GameObject::GetAIName() const
+std::string const& GameObject::GetAIName() const
{
- if (GameObjectTemplate const* got = sObjectMgr->GetGameObjectTemplate(GetEntry()))
- return got->AIName;
-
- return "";
+ return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
}
void GameObject::CleanupsBeforeDelete(bool finalCleanup)
@@ -2121,7 +2118,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags trigge
}
else
{
- trigger->SetFaction(spellInfo->IsPositive() ? 35 : 14);
+ trigger->SetFaction(spellInfo->IsPositive() ? FACTION_FRIENDLY : FACTION_MONSTER);
// Set owner guid for target if no owner available - needed by trigger auras
// - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
trigger->CastSpell(target ? target : trigger, spellInfo, triggered, nullptr, nullptr, target ? target->GetGUID() : ObjectGuid::Empty);
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index da06d1842f8..7bbf09a26ad 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -283,7 +283,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
uint32 GetScriptId() const;
GameObjectAI* AI() const { return m_AI; }
- std::string GetAIName() const;
+ std::string const& GetAIName() const;
void SetDisplayId(uint32 displayid);
uint32 GetDisplayId() const { return m_gameObjectData->DisplayID; }
uint8 GetNameSetId() const;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 32f2be86bd9..939d7e750d1 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2105,8 +2105,8 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, NPCFlags npcFl
if (creature->GetReactionTo(this) <= REP_UNFRIENDLY)
return nullptr;
- // not too far
- if (!creature->IsWithinDistInMap(this, INTERACTION_DISTANCE))
+ // not too far, taken from CGGameUI::SetInteractTarget
+ if (!creature->IsWithinDistInMap(this, creature->GetCombatReach() + 4.0f))
return nullptr;
return creature;
@@ -2114,33 +2114,36 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid const& guid, NPCFlags npcFl
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const
{
- if (GameObject* go = GetMap()->GetGameObject(guid))
- {
- if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
- return go;
+ if (!guid)
+ return nullptr;
- TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal %f is allowed)",
- go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this), go->GetInteractionDistance());
- }
+ if (!IsInWorld())
+ return nullptr;
- return nullptr;
+ if (IsInFlight())
+ return nullptr;
+
+ // exist
+ GameObject* go = ObjectAccessor::GetGameObject(*this, guid);
+ if (!go)
+ return nullptr;
+
+ if (!go->IsWithinDistInMap(this, go->GetInteractionDistance()))
+ return nullptr;
+
+ return go;
}
GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const
{
- if (GameObject* go = GetMap()->GetGameObject(guid))
- {
- if (go->GetGoType() == type)
- {
- if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
- return go;
+ GameObject* go = GetGameObjectIfCanInteractWith(guid);
+ if (!go)
+ return nullptr;
- TC_LOG_DEBUG("maps", "Player::GetGameObjectIfCanInteractWith: GameObject '%s' (%s) is too far away from player '%s' (%s) to be used by him (Distance: %f, maximal %f is allowed)",
- go->GetGOInfo()->name.c_str(), go->GetGUID().ToString().c_str(), GetName().c_str(), GetGUID().ToString().c_str(), go->GetDistance(this), go->GetInteractionDistance());
- }
- }
+ if (go->GetGoType() != type)
+ return nullptr;
- return nullptr;
+ return go;
}
bool Player::IsUnderWater() const
@@ -2201,13 +2204,13 @@ void Player::SetGameMaster(bool on)
if (on)
{
m_ExtraFlags |= PLAYER_EXTRA_GM_ON;
- SetFaction(35);
+ SetFaction(FACTION_FRIENDLY);
AddPlayerFlag(PLAYER_FLAGS_GM);
AddUnitFlag2(UNIT_FLAG2_ALLOW_CHEAT_SPELLS);
if (Pet* pet = GetPet())
{
- pet->SetFaction(35);
+ pet->SetFaction(FACTION_FRIENDLY);
pet->getHostileRefManager().setOnlineOfflineState(false);
}
@@ -16604,7 +16607,6 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
QuestRelationBounds qr;
QuestRelationBounds qir;
- PlayerTalkClass->ClearMenus();
switch (questgiver->GetTypeId())
{
case TYPEID_GAMEOBJECT:
@@ -16832,9 +16834,7 @@ void Player::AreaExploredOrEventHappens(uint32 questId)
q_status.Explored = true;
m_QuestStatusSave[questId] = QUEST_DEFAULT_SAVE_TYPE;
- // if we cannot complete quest send exploration succeded (to mark exploration on client)
- if (!CanCompleteQuest(questId))
- SendQuestComplete(questId);
+ SendQuestComplete(questId);
}**/
}
if (CanCompleteQuest(questId))
@@ -25390,18 +25390,24 @@ void Player::ResurrectUsingRequestData()
void Player::ResurrectUsingRequestDataImpl()
{
+ // save health and mana before resurrecting, _resurrectionData can be erased
+ uint32 resurrectHealth = _resurrectionData->Health;
+ uint32 resurrectMana = _resurrectionData->Mana;
+ uint32 resurrectAura = _resurrectionData->Aura;
+ ObjectGuid resurrectGUID = _resurrectionData->GUID;
+
ResurrectPlayer(0.0f, false);
- SetHealth(_resurrectionData->Health);
- SetPower(POWER_MANA, _resurrectionData->Mana);
+ SetHealth(resurrectHealth);
+ SetPower(POWER_MANA, resurrectMana);
SetPower(POWER_RAGE, 0);
SetFullPower(POWER_ENERGY);
SetFullPower(POWER_FOCUS);
SetPower(POWER_LUNAR_POWER, 0);
- if (uint32 aura = _resurrectionData->Aura)
- CastSpell(this, aura, true, nullptr, nullptr, _resurrectionData->GUID);
+ if (uint32 aura = resurrectAura)
+ CastSpell(this, aura, true, nullptr, nullptr, resurrectGUID);
SpawnCorpseBones();
}
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index c4c7d2a971d..c261fdef73b 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -154,8 +154,8 @@ void Transport::Update(uint32 diff)
if (timer < _currentFrame->DepartureTime)
{
+ justStopped = IsMoving();
SetMoving(false);
- justStopped = true;
if (_pendingStop && GetGoState() != GO_STATE_READY)
{
SetGoState(GO_STATE_READY);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 29f2d6433ce..6d5b164f594 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3391,7 +3391,14 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask)
// Update target aura state flag
if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
- ModifyAuraState(aState, true);
+ {
+ uint32 aStateMask = (1 << (aState - 1));
+ // force update so the new caster registers it
+ if ((aStateMask & PER_CASTER_AURA_STATE_MASK) && *m_unitData->AuraState & aStateMask)
+ ForceUpdateFieldChange(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::AuraState));
+ else
+ ModifyAuraState(aState, true);
+ }
if (aurApp->GetRemoveMode())
return;
@@ -3484,9 +3491,19 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
ToTotem()->setDeathState(JUST_DIED);
}
- // Remove aurastates only if were not found
- if (!auraStateFound)
- ModifyAuraState(auraState, false);
+ // Remove aurastates only if needed and were not found
+ if (auraState)
+ {
+ if (!auraStateFound)
+ ModifyAuraState(auraState, false);
+ else
+ {
+ // update for casters, some shouldn't 'see' the aura state
+ uint32 aStateMask = (1 << (auraState - 1));
+ if ((aStateMask & PER_CASTER_AURA_STATE_MASK) != 0)
+ ForceUpdateFieldChange(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::AuraState));
+ }
+ }
aura->HandleAuraSpecificMods(aurApp, caster, false, false);
@@ -5618,13 +5635,22 @@ void Unit::_removeAttacker(Unit* pAttacker)
Unit* Unit::getAttackerForHelper() const // If someone wants to help, who to give them
{
- if (GetVictim() != NULL)
- return GetVictim();
+ if (Unit* victim = GetVictim())
+ if (!IsControlledByPlayer() || IsInCombatWith(victim) || victim->IsInCombatWith(this))
+ return victim;
if (!m_attackers.empty())
return *(m_attackers.begin());
- return NULL;
+ if (Player* owner = GetCharmerOrOwnerPlayerOrPlayerItself())
+ {
+ HostileRefManager& refs = owner->getHostileRefManager();
+ for (Reference<Unit, ThreatManager> const& ref : refs)
+ if (Unit* hostile = ref.GetSource()->GetOwner())
+ return hostile;
+ }
+
+ return nullptr;
}
bool Unit::Attack(Unit* victim, bool meleeAttack)
@@ -5640,6 +5666,11 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
if (GetTypeId() == TYPEID_PLAYER && IsMounted())
return false;
+ Creature* creature = ToCreature();
+ // creatures cannot attack while evading
+ if (creature && creature->IsInEvadeMode())
+ return false;
+
if (HasUnitFlag(UNIT_FLAG_PACIFIED))
return false;
@@ -5704,7 +5735,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
//if (GetTypeId() == TYPEID_UNIT)
// ToCreature()->SetCombatStartPosition(GetPositionX(), GetPositionY(), GetPositionZ());
- if (GetTypeId() == TYPEID_UNIT && !IsPet())
+ if (creature && !IsPet())
{
// should not let player enter combat by right clicking target - doesn't helps
AddThreat(victim, 0.0f);
@@ -5712,8 +5743,8 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
if (victim->GetTypeId() == TYPEID_PLAYER)
victim->SetInCombatWith(this);
- ToCreature()->SendAIReaction(AI_REACTION_HOSTILE);
- ToCreature()->CallAssistance();
+ creature->SendAIReaction(AI_REACTION_HOSTILE);
+ creature->CallAssistance();
// Remove emote state - will be restored on creature reset
SetEmoteState(EMOTE_ONESHOT_NONE);
@@ -5728,7 +5759,7 @@ bool Unit::Attack(Unit* victim, bool meleeAttack)
// Let the pet know we've started attacking someting. Handles melee attacks only
// Spells such as auto-shot and others handled in WorldSession::HandleCastSpellOpcode
- if (this->GetTypeId() == TYPEID_PLAYER)
+ if (GetTypeId() == TYPEID_PLAYER)
{
Pet* playerPet = this->ToPlayer()->GetPet();
@@ -8726,8 +8757,6 @@ void Unit::setDeathState(DeathState s)
if (s == JUST_DIED)
{
- ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
- ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
// remove aurastates allowing special moves
ClearAllReactives();
ClearDiminishings();
@@ -10616,13 +10645,13 @@ Player* Unit::GetSpellModOwner() const
if (Player* player = const_cast<Unit*>(this)->ToPlayer())
return player;
- if (IsPet() || IsTotem())
+ if (HasUnitTypeMask(UNIT_MASK_PET | UNIT_MASK_TOTEM | UNIT_MASK_GUARDIAN))
{
if (Unit* owner = GetOwner())
if (Player* player = owner->ToPlayer())
return player;
}
- return NULL;
+ return nullptr;
}
///----------Pet responses methods-----------------
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index e38539429ae..c616ee11270 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -21,10 +21,12 @@
#include "AzeriteItem.h"
#include "Chat.h"
#include "Containers.h"
+#include "CreatureAIFactory.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "DisableMgr.h"
#include "GameObject.h"
+#include "GameObjectAIFactory.h"
#include "GameTables.h"
#include "GridDefines.h"
#include "GossipDef.h"
@@ -935,6 +937,12 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
ok = true;
}
+ if (!cInfo->AIName.empty() && !sCreatureAIRegistry->HasItem(cInfo->AIName))
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has non-registered `AIName` '%s' set, removing", cInfo->Entry, cInfo->AIName.c_str());
+ const_cast<CreatureTemplate*>(cInfo)->AIName.clear();
+ }
+
FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction);
if (!factionTemplate)
{
@@ -2048,6 +2056,12 @@ void ObjectMgr::LoadCreatures()
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature is not in instance.", guid, data.id);
}
+ if (data.movementType >= MAX_DB_MOTION_TYPE)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u) with wrong movement generator type (%u), ignored and set to IDLE.", guid, data.id, data.movementType);
+ data.movementType = IDLE_MOTION_TYPE;
+ }
+
if (data.spawndist < 0.0f)
{
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u) with `spawndist`< 0, set to 0.", guid, data.id);
@@ -7061,6 +7075,11 @@ void ObjectMgr::LoadGameObjectTemplate()
got.ScriptId = GetScriptId(fields[44].GetString());
// Checks
+ if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName))
+ {
+ TC_LOG_ERROR("sql.sql", "GameObject (Entry: %u) has non-registered `AIName` '%s' set, removing", got.entry, got.AIName.c_str());
+ got.AIName.clear();
+ }
switch (got.type)
{
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 314c74c1766..53d8fb5a877 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -203,10 +203,13 @@ void GroupMgr::LoadGroups()
TC_LOG_INFO("server.loading", "Loading Group instance saves...");
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7
- QueryResult result = CharacterDatabase.Query("SELECT gi.guid, i.map, gi.instance, gi.permanent, i.difficulty, i.resettime, i.entranceId, COUNT(g.guid) "
- "FROM group_instance gi INNER JOIN instance i ON gi.instance = i.id "
- "LEFT JOIN character_instance ci LEFT JOIN `groups` g ON g.leaderGuid = ci.guid ON ci.instance = gi.instance AND ci.permanent = 1 GROUP BY gi.instance ORDER BY gi.guid");
+
+ // 0 1 2 3 4 5 6
+ QueryResult result = CharacterDatabase.Query("SELECT gi.guid, i.map, gi.instance, gi.permanent, i.difficulty, i.resettime, i.entranceId, "
+ // 7
+ "(SELECT COUNT(1) FROM character_instance ci LEFT JOIN groups g ON ci.guid = g.leaderGuid WHERE ci.instance = gi.instance AND ci.permanent = 1 LIMIT 1) "
+ "FROM group_instance gi LEFT JOIN instance i ON gi.instance = i.id ORDER BY guid");
+
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 group-instance saves. DB table `group_instance` is empty!");
@@ -232,7 +235,7 @@ void GroupMgr::LoadGroups()
if (!difficultyEntry || difficultyEntry->InstanceType != mapEntry->InstanceType)
continue;
- InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->ID, fields[2].GetUInt32(), Difficulty(diff), time_t(fields[5].GetUInt32()), fields[6].GetUInt32(), fields[7].GetUInt64() != 0, true);
+ InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->ID, fields[2].GetUInt32(), Difficulty(diff), time_t(fields[5].GetUInt32()), fields[6].GetUInt32(), fields[7].GetUInt64() == 0, true);
group->BindToInstance(save, fields[3].GetBool(), true);
++count;
}
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 2e7d7e81ddb..03b0f954ccd 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -189,6 +189,51 @@ enum ReputationRank
REP_EXALTED = 7
};
+enum FactionTemplates
+{
+ FACTION_NONE = 0,
+ FACTION_CREATURE = 7,
+ FACTION_ESCORTEE_A_NEUTRAL_PASSIVE = 10,
+ FACTION_MONSTER = 14,
+ FACTION_MONSTER_2 = 16,
+ FACTION_TROLL_BLOODSCALP = 28,
+ FACTION_PREY = 31,
+ FACTION_ESCORTEE_H_NEUTRAL_PASSIVE = 33,
+ FACTION_FRIENDLY = 35,
+ FACTION_OGRE = 45,
+ FACTION_ORC_DRAGONMAW = 62,
+ FACTION_HORDE_GENERIC = 83,
+ FACTION_ALLIANCE_GENERIC = 84,
+ FACTION_DEMON = 90,
+ FACTION_ELEMENTAL = 91,
+ FACTION_DRAGONFLIGHT_BLACK = 103,
+ FACTION_ESCORTEE_N_NEUTRAL_PASSIVE = 113,
+ FACTION_ENEMY = 168,
+ FACTION_ESCORTEE_A_NEUTRAL_ACTIVE = 231,
+ FACTION_ESCORTEE_H_NEUTRAL_ACTIVE = 232,
+ FACTION_ESCORTEE_N_NEUTRAL_ACTIVE = 250,
+ FACTION_ESCORTEE_N_FRIEND_PASSIVE = 290,
+ FACTION_TITAN = 415,
+ FACTION_ESCORTEE_N_FRIEND_ACTIVE = 495,
+ FACTION_GOBLIN_DARK_IRON_BAR_PATRON = 736,
+ FACTION_DARK_IRON_DWARVES = 754,
+ FACTION_ESCORTEE_A_PASSIVE = 774,
+ FACTION_ESCORTEE_H_PASSIVE = 775,
+ FACTION_UNDEAD_SCOURGE = 974,
+ FACTION_EARTHEN_RING = 1726,
+ FACTION_ALLIANCE_GENERIC_WG = 1732,
+ FACTION_HORDE_GENERIC_WG = 1735,
+ FACTION_ARAKKOA = 1738,
+ FACTION_ASHTONGUE_DEATHSWORN = 1820,
+ FACTION_FLAYER_HUNTER = 1840,
+ FACTION_MONSTER_SPAR_BUDDY = 1868,
+ FACTION_ESCORTEE_N_ACTIVE = 1986,
+ FACTION_ESCORTEE_H_ACTIVE = 2046,
+ FACTION_UNDEAD_SCOURGE_2 = 2068,
+ FACTION_UNDEAD_SCOURGE_3 = 2084,
+ FACTION_SCARLET_CRUSADE = 2089
+};
+
#define MIN_REPUTATION_RANK (REP_HATED)
#define MAX_REPUTATION_RANK 8
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 3b446733bbb..295c70039e6 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -35,9 +35,14 @@
#include "MoveSplineInit.h"
#include "PathGenerator.h"
+inline MovementGenerator* GetIdleMovementGenerator()
+{
+ return sMovementGeneratorRegistry->GetRegistryItem(IDLE_MOTION_TYPE)->Create();
+}
+
inline bool IsStatic(MovementGenerator* movement)
{
- return (movement == &si_idleMovement);
+ return (movement == GetIdleMovementGenerator());
}
MotionMaster::~MotionMaster()
@@ -75,15 +80,7 @@ void MotionMaster::Initialize()
// set new default movement generator
void MotionMaster::InitDefault()
{
- if (_owner->GetTypeId() == TYPEID_UNIT)
- {
- MovementGenerator* movement = FactorySelector::selectMovementGenerator(_owner->ToCreature());
- Mutate(movement == nullptr ? &si_idleMovement : movement, MOTION_SLOT_IDLE);
- }
- else
- {
- Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
- }
+ Mutate(FactorySelector::SelectMovementGenerator(_owner), MOTION_SLOT_IDLE);
}
void MotionMaster::UpdateMotion(uint32 diff)
@@ -198,7 +195,7 @@ void MotionMaster::MoveIdle()
{
//! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active
if (empty() || !IsStatic(top()))
- Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
+ Mutate(GetIdleMovementGenerator(), MOTION_SLOT_IDLE);
}
void MotionMaster::MoveTargetedHome()
diff --git a/src/server/game/Movement/MovementGenerator.cpp b/src/server/game/Movement/MovementGenerator.cpp
index 5ce585b483d..661267401d2 100644
--- a/src/server/game/Movement/MovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerator.cpp
@@ -16,5 +16,12 @@
*/
#include "MovementGenerator.h"
+#include "IdleMovementGenerator.h"
MovementGenerator::~MovementGenerator() { }
+
+MovementGenerator* IdleMovementFactory::Create(Unit* /*object*/) const
+{
+ static IdleMovementGenerator instance;
+ return &instance;
+}
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index fdf5506dd15..4af0709aa06 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -69,20 +69,28 @@ class MovementGeneratorMedium : public MovementGenerator
}
};
-struct SelectableMovement : public FactoryHolder<MovementGenerator, MovementGeneratorType>
+typedef FactoryHolder<MovementGenerator, Unit, MovementGeneratorType> MovementGeneratorCreator;
+
+template<class Movement>
+struct MovementGeneratorFactory : public MovementGeneratorCreator
{
- SelectableMovement(MovementGeneratorType movementGeneratorType) : FactoryHolder<MovementGenerator, MovementGeneratorType>(movementGeneratorType) { }
+ MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : MovementGeneratorCreator(movementGeneratorType) { }
+
+ MovementGenerator* Create(Unit* /*object*/) const override
+ {
+ return new Movement();
+ }
};
-template<class Movement>
-struct MovementGeneratorFactory : public SelectableMovement
+struct IdleMovementFactory : public MovementGeneratorCreator
{
- MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : SelectableMovement(movementGeneratorType) { }
+ IdleMovementFactory() : MovementGeneratorCreator(IDLE_MOTION_TYPE) { }
- MovementGenerator* Create(void *) const override;
+ MovementGenerator* Create(Unit* object) const override;
};
-typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator;
-typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRegistry MovementGeneratorRegistry;
+typedef MovementGeneratorCreator::FactoryHolderRegistry MovementGeneratorRegistry;
+
+#define sMovementGeneratorRegistry MovementGeneratorRegistry::instance()
#endif
diff --git a/src/server/game/Movement/MovementGeneratorImpl.h b/src/server/game/Movement/MovementGeneratorImpl.h
deleted file mode 100644
index 0b5474b22b3..00000000000
--- a/src/server/game/Movement/MovementGeneratorImpl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_MOVEMENTGENERATOR_IMPL_H
-#define TRINITY_MOVEMENTGENERATOR_IMPL_H
-
-#include "MovementGenerator.h"
-
-template<class Movement>
-inline MovementGenerator* MovementGeneratorFactory<Movement>::Create(void * /*data*/) const
-{
- return (new Movement());
-}
-
-#endif
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
index 76b1aca3cc2..43638197578 100644
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
@@ -20,8 +20,6 @@
#include "Creature.h"
#include <G3D/g3dmath.h>
-IdleMovementGenerator si_idleMovement;
-
// StopMoving is needed to make unit stop if its last movement generator expires
// But it should not be sent otherwise there are many redundent packets
void IdleMovementGenerator::Initialize(Unit* owner)
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
index 9bb58419433..773d4dc03b7 100755
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h
@@ -31,8 +31,6 @@ class IdleMovementGenerator : public MovementGenerator
MovementGeneratorType GetMovementGeneratorType() const override { return IDLE_MOTION_TYPE; }
};
-TC_GAME_API extern IdleMovementGenerator si_idleMovement;
-
class RotateMovementGenerator : public MovementGenerator
{
public:
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index b912f51cf9d..72354f47b21 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -1607,7 +1607,10 @@ bool ScriptMgr::CanSpawn(ObjectGuid::LowType spawnId, uint32 entry, CreatureTemp
CreatureTemplate const* baseTemplate = sObjectMgr->GetCreatureTemplate(entry);
if (!baseTemplate)
baseTemplate = actTemplate;
- GET_SCRIPT_RET(CreatureScript, (cData ? cData->ScriptId : baseTemplate->ScriptID), tmpscript, true);
+ uint32 scriptId = baseTemplate->ScriptID;
+ if (cData && cData->ScriptId)
+ scriptId = cData->ScriptId;
+ GET_SCRIPT_RET(CreatureScript, scriptId, tmpscript, true);
return tmpscript->CanSpawn(spawnId, entry, baseTemplate, actTemplate, cData, map);
}
diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h
index 9f5a0ef78ce..f058bf886ee 100644
--- a/src/server/game/Scripting/ScriptSystem.h
+++ b/src/server/game/Scripting/ScriptSystem.h
@@ -28,30 +28,6 @@ struct SplineChainLink;
#define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available
-/// @todo find better namings and definitions.
-//N=Neutral, A=Alliance, H=Horde.
-//NEUTRAL or FRIEND = Hostility to player surroundings (not a good definition)
-//ACTIVE or PASSIVE = Hostility to environment surroundings.
-enum eEscortFaction
-{
- FACTION_ESCORT_A_NEUTRAL_PASSIVE = 10,
- FACTION_ESCORT_H_NEUTRAL_PASSIVE = 33,
- FACTION_ESCORT_N_NEUTRAL_PASSIVE = 113,
-
- FACTION_ESCORT_A_NEUTRAL_ACTIVE = 231,
- FACTION_ESCORT_H_NEUTRAL_ACTIVE = 232,
- FACTION_ESCORT_N_NEUTRAL_ACTIVE = 250,
-
- FACTION_ESCORT_N_FRIEND_PASSIVE = 290,
- FACTION_ESCORT_N_FRIEND_ACTIVE = 495,
-
- FACTION_ESCORT_A_PASSIVE = 774,
- FACTION_ESCORT_H_PASSIVE = 775,
-
- FACTION_ESCORT_N_ACTIVE = 1986,
- FACTION_ESCORT_H_ACTIVE = 2046
-};
-
struct ScriptPointMove
{
uint32 uiCreatureEntry;
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index aef183d8b97..2db4d4f8b3c 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5896,18 +5896,6 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
}
else
{
- // Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags & flag128(0, 0x04000000, 0, 0))
- {
- int32 addition = int32(float(damage * GetTotalTicks()) * ((6-float(2*(GetTickNumber()-1)))/100));
-
- // Item - Druid T10 Restoration 2P Bonus
- if (AuraEffect* aurEff = caster->GetAuraEffect(70658, 0))
- // divided by 50 instead of 100 because calculated as for every 2 tick
- addition += abs(int32((addition * aurEff->GetAmount()) / 50));
-
- damage += addition;
- }
if (isAreaAura)
damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellHealingPctDone(target, m_spellInfo);
damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index f9c6b64e7f3..ca79aa1ac0e 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -778,6 +778,14 @@ void Spell::SelectSpellTargets()
if (m_spellInfo->IsChanneled())
{
+ // maybe do this for all spells?
+ if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
+ {
+ SendCastResult(SPELL_FAILED_BAD_IMPLICIT_TARGETS);
+ finish(false);
+ return;
+ }
+
uint32 mask = (1 << effect->EffectIndex);
for (std::vector<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
@@ -1241,10 +1249,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
return;
float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
- // if this is a proximity based aoe (Frost Nova, Psychic Scream, ...), include the caster's own combat reach
- if (targetType.IsProximityBasedAoe())
- radius += GetCaster()->GetCombatReach();
-
SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), effect->ImplicitTargetConditions);
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
@@ -2342,7 +2346,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (!(target->effectMask & (1 << i)))
+ // in case of immunity, check all effects to choose correct procFlags, as none has technically hit
+ if (target->effectMask && !(target->effectMask & (1 << i)))
continue;
if (!m_spellInfo->IsPositiveEffect(i))
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index a9fa7bfee03..b02c080fe9b 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -879,15 +879,12 @@ void Spell::EffectJump(SpellEffIndex /*effIndex*/)
if (!unitTarget)
return;
- float x, y, z;
- unitTarget->GetContactPoint(m_caster, x, y, z, CONTACT_DISTANCE);
-
float speedXY, speedZ;
- CalculateJumpSpeeds(effectInfo, m_caster->GetExactDist2d(x, y), speedXY, speedZ);
+ CalculateJumpSpeeds(effectInfo, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ);
JumpArrivalCastArgs arrivalCast;
arrivalCast.SpellId = effectInfo->TriggerSpell;
arrivalCast.Target = unitTarget->GetGUID();
- m_caster->GetMotionMaster()->MoveJump(x, y, z, 0.0f, speedXY, speedZ, EVENT_JUMP, false, &arrivalCast);
+ m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ, EVENT_JUMP, false, &arrivalCast);
}
void Spell::EffectJumpDest(SpellEffIndex /*effIndex*/)
@@ -2725,13 +2722,9 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (!unitTarget)
- return;
-
// this effect use before aura Taunt apply for prevent taunt already attacking target
// for spell as marked "non effective at already attacking target"
- if (!unitTarget || !unitTarget->CanHaveThreatList()
- || unitTarget->GetVictim() == m_caster)
+ if (!unitTarget || !unitTarget->CanHaveThreatList() || unitTarget->GetVictim() == m_caster)
{
SendCastResult(SPELL_FAILED_DONT_REPORT);
return;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 8dc5af047ec..084695559bd 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -75,35 +75,6 @@ bool SpellImplicitTargetInfo::IsArea() const
return GetSelectionCategory() == TARGET_SELECT_CATEGORY_AREA || GetSelectionCategory() == TARGET_SELECT_CATEGORY_CONE;
}
-bool SpellImplicitTargetInfo::IsProximityBasedAoe() const
-{
- switch (_target)
- {
- case TARGET_UNIT_SRC_AREA_ENTRY:
- case TARGET_UNIT_SRC_AREA_ENEMY:
- case TARGET_UNIT_CASTER_AREA_PARTY:
- case TARGET_UNIT_SRC_AREA_ALLY:
- case TARGET_UNIT_SRC_AREA_PARTY:
- case TARGET_UNIT_LASTTARGET_AREA_PARTY:
- case TARGET_GAMEOBJECT_SRC_AREA:
- case TARGET_UNIT_CASTER_AREA_RAID:
- case TARGET_CORPSE_SRC_AREA_ENEMY:
- return true;
-
- case TARGET_UNIT_DEST_AREA_ENTRY:
- case TARGET_UNIT_DEST_AREA_ENEMY:
- case TARGET_UNIT_DEST_AREA_ALLY:
- case TARGET_UNIT_DEST_AREA_PARTY:
- case TARGET_GAMEOBJECT_DEST_AREA:
- case TARGET_UNIT_TARGET_AREA_RAID_CLASS:
- return false;
-
- default:
- TC_LOG_WARN("spells", "SpellImplicitTargetInfo::IsProximityBasedAoe called a non-aoe spell");
- return false;
- }
-}
-
SpellTargetSelectionCategories SpellImplicitTargetInfo::GetSelectionCategory() const
{
return _data[_target].SelectionCategory;
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 4af84e40376..5a5afeff4ee 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -286,7 +286,6 @@ public:
SpellImplicitTargetInfo(uint32 target);
bool IsArea() const;
- bool IsProximityBasedAoe() const;
SpellTargetSelectionCategories GetSelectionCategory() const;
SpellTargetReferenceTypes GetReferenceType() const;
SpellTargetObjectTypes GetObjectType() const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 1e2bc42c17d..f2afcdbc474 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3363,6 +3363,14 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
});
+ // Blizzard (Thorim)
+ ApplySpellFix({ 62576, 62602 }, [](SpellInfo* spellInfo)
+ {
+ // DBC data is wrong for EFFECT_0, it's a different dynobject target than EFFECT_1
+ // Both effects should be shared by the same DynObject
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_CASTER_LEFT);
+ });
+
// Spinning Up (Mimiron)
ApplySpellFix({ 63414 }, [](SpellInfo* spellInfo)
{
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index fc45fa83113..7a64662c730 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1613,6 +1613,9 @@ void World::SetInitialWorldSettings()
MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager();
mmmgr->InitializeThreadUnsafe(mapData);
+ ///- Initialize static helper structures
+ AIRegistry::Initialize();
+
TC_LOG_INFO("server.loading", "Loading SpellInfo store...");
sSpellMgr->LoadSpellInfoStore();
@@ -2140,9 +2143,6 @@ void World::SetInitialWorldSettings()
mail_timer_expires = ((DAY * IN_MILLISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval()));
TC_LOG_INFO("server.loading", "Mail timer set to: " UI64FMTD ", mail return is called every " UI64FMTD " minutes", uint64(mail_timer), uint64(mail_timer_expires));
- ///- Initilize static helper structures
- AIRegistry::Initialize();
-
///- Initialize MapManager
TC_LOG_INFO("server.loading", "Starting Map System");
sMapMgr->Initialize();
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 11417b305a5..81bc3e533e1 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -61,6 +61,7 @@ public:
{ "cinematic", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_CINEMATIC, false, &HandleDebugPlayCinematicCommand, "" },
{ "movie", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_MOVIE, false, &HandleDebugPlayMovieCommand, "" },
{ "sound", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_SOUND, false, &HandleDebugPlaySoundCommand, "" },
+ { "music", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_MUSIC, false, &HandleDebugPlayMusicCommand, "" },
};
static std::vector<ChatCommand> debugSendCommandTable =
{
@@ -117,8 +118,8 @@ public:
static bool HandleDebugPlayCinematicCommand(ChatHandler* handler, char const* args)
{
- // USAGE: .debug play cinematic #cinematicid
- // #cinematicid - ID decimal number from CinemaicSequences.dbc (1st column)
+ // USAGE: .debug play cinematic #cinematicId
+ // #cinematicId - ID decimal number from CinemaicSequences.dbc (1st column)
if (!*args)
{
handler->SendSysMessage(LANG_BAD_VALUE);
@@ -126,12 +127,12 @@ public:
return false;
}
- uint32 id = atoul(args);
+ uint32 cinematicId = atoul(args);
- CinematicSequencesEntry const* cineSeq = sCinematicSequencesStore.LookupEntry(id);
+ CinematicSequencesEntry const* cineSeq = sCinematicSequencesStore.LookupEntry(cinematicId);
if (!cineSeq)
{
- handler->PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, id);
+ handler->PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, cinematicId);
handler->SetSentErrorMessage(true);
return false;
}
@@ -139,7 +140,7 @@ public:
// Dump camera locations
if (std::vector<FlyByCamera> const* flyByCameras = GetFlyByCameras(cineSeq->Camera[0]))
{
- handler->PSendSysMessage("Waypoints for sequence %u, camera %u", id, cineSeq->Camera[0]);
+ handler->PSendSysMessage("Waypoints for sequence %u, camera %u", cinematicId, cineSeq->Camera[0]);
uint32 count = 1;
for (FlyByCamera const& cam : *flyByCameras)
{
@@ -149,14 +150,14 @@ public:
handler->PSendSysMessage(SZFMTD " waypoints dumped", flyByCameras->size());
}
- handler->GetSession()->GetPlayer()->SendCinematicStart(id);
+ handler->GetSession()->GetPlayer()->SendCinematicStart(cinematicId);
return true;
}
static bool HandleDebugPlayMovieCommand(ChatHandler* handler, char const* args)
{
- // USAGE: .debug play movie #movieid
- // #movieid - ID decimal number from Movie.dbc (1st column)
+ // USAGE: .debug play movie #movieId
+ // #movieId - ID decimal number from Movie.dbc (1st column)
if (!*args)
{
handler->SendSysMessage(LANG_BAD_VALUE);
@@ -164,24 +165,24 @@ public:
return false;
}
- uint32 id = atoul(args);
+ uint32 movieId = atoul(args);
- if (!sMovieStore.LookupEntry(id))
+ if (!sMovieStore.LookupEntry(movieId))
{
- handler->PSendSysMessage(LANG_MOVIE_NOT_EXIST, id);
+ handler->PSendSysMessage(LANG_MOVIE_NOT_EXIST, movieId);
handler->SetSentErrorMessage(true);
return false;
}
- handler->GetSession()->GetPlayer()->SendMovieStart(id);
+ handler->GetSession()->GetPlayer()->SendMovieStart(movieId);
return true;
}
//Play sound
static bool HandleDebugPlaySoundCommand(ChatHandler* handler, char const* args)
{
- // USAGE: .debug playsound #soundid
- // #soundid - ID decimal number from SoundEntries.dbc (1st column)
+ // USAGE: .debug playsound #soundId
+ // #soundId - ID decimal number from SoundEntries.dbc (1st column)
if (!*args)
{
handler->SendSysMessage(LANG_BAD_VALUE);
@@ -198,6 +199,8 @@ public:
return false;
}
+ Player* player = handler->GetSession()->GetPlayer();
+
Unit* unit = handler->getSelectedUnit();
if (!unit)
{
@@ -206,15 +209,42 @@ public:
return false;
}
- if (!handler->GetSession()->GetPlayer()->GetTarget().IsEmpty())
- unit->PlayDistanceSound(soundId, handler->GetSession()->GetPlayer());
+ if (player->GetTarget().IsEmpty())
+ unit->PlayDistanceSound(soundId, player);
else
- unit->PlayDirectSound(soundId, handler->GetSession()->GetPlayer());
+ unit->PlayDirectSound(soundId, player);
handler->PSendSysMessage(LANG_YOU_HEAR_SOUND, soundId);
return true;
}
+ static bool HandleDebugPlayMusicCommand(ChatHandler* handler, char const* args)
+ {
+ // USAGE: .debug play music #musicId
+ // #musicId - ID decimal number from SoundEntries.dbc (1st column)
+ if (!*args)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 musicId = atoul(args);
+ if (!sSoundKitStore.LookupEntry(musicId))
+ {
+ handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, musicId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ Player* player = handler->GetSession()->GetPlayer();
+
+ player->PlayDirectMusic(musicId, player);
+
+ handler->PSendSysMessage(LANG_YOU_HEAR_SOUND, musicId);
+ return true;
+ }
+
static bool HandleDebugSendSpellFailCommand(ChatHandler* handler, char const* args)
{
if (!*args)
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 595af9223bc..4d818db8f9d 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -891,7 +891,7 @@ public:
const_cast<CreatureData*>(data)->posZ = z;
const_cast<CreatureData*>(data)->orientation = o;
}
- creature->SetPosition(x, y, z, o);
+ creature->UpdatePosition(x, y, z, o);
creature->GetMotionMaster()->Initialize();
if (creature->IsAlive()) // dead creature will reset movement generator at respawn
{
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 8917a50951f..ccb032f6c02 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -111,13 +111,13 @@ public:
{ "item_random_bonus_list_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_RANDOM_BONUS_LIST_TEMPLATE, true, &HandleReloadItemRandomBonusListTemplatesCommand, "" },
{ "item_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesItemCommand, "" },
{ "lfg_dungeon_rewards", rbac::RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS, true, &HandleReloadLfgRewardsCommand, "" },
- { "locales_achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD, true, &HandleReloadLocalesAchievementRewardCommand, "" },
- { "locales_creature", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE, true, &HandleReloadLocalesCreatureCommand, "" },
- { "locales_creature_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE_TEXT, true, &HandleReloadLocalesCreatureTextCommand, "" },
- { "locales_gameobject", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT, true, &HandleReloadLocalesGameobjectCommand, "" },
- { "locales_gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION, true, &HandleReloadLocalesGossipMenuOptionCommand, "" },
- { "locales_page_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT, true, &HandleReloadLocalesPageTextCommand, "" },
- { "locales_points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST, true, &HandleReloadLocalesPointsOfInterestCommand, "" },
+ { "achievement_reward_locale", rbac::RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_REWARD_LOCALE, true, &HandleReloadLocalesAchievementRewardCommand, "" },
+ { "creature_template_locale", rbac::RBAC_PERM_COMMAND_RELOAD_CRETURE_TEMPLATE_LOCALE, true, &HandleReloadLocalesCreatureCommand, "" },
+ { "creature_text_locale", rbac::RBAC_PERM_COMMAND_RELOAD_CRETURE_TEXT_LOCALE, true, &HandleReloadLocalesCreatureTextCommand, "" },
+ { "gameobject_template_locale", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_TEMPLATE_LOCALE, true, &HandleReloadLocalesGameobjectCommand, "" },
+ { "gossip_menu_option_locale", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION_LOCALE, true, &HandleReloadLocalesGossipMenuOptionCommand, "" },
+ { "page_text_locale", rbac::RBAC_PERM_COMMAND_RELOAD_PAGE_TEXT_LOCALE, true, &HandleReloadLocalesPageTextCommand, "" },
+ { "points_of_interest_locale", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST_LOCALE, true, &HandleReloadLocalesPointsOfInterestCommand, "" },
{ "mail_level_reward", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD, true, &HandleReloadMailLevelRewardCommand, "" },
{ "mail_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMailCommand, "" },
{ "milling_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMillingCommand, "" },
@@ -128,7 +128,7 @@ public:
{ "points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST, true, &HandleReloadPointsOfInterestCommand, "" },
{ "prospecting_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesProspectingCommand, "" },
{ "quest_greeting", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING, true, &HandleReloadQuestGreetingCommand, "" },
- { "quest_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_LOCALE, true, &HandleReloadQuestLocaleCommand, "" },
+ { "quest_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE_LOCALE, true, &HandleReloadQuestLocaleCommand, "" },
{ "quest_poi", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_POI, true, &HandleReloadQuestPOICommand, "" },
{ "quest_template", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE, true, &HandleReloadQuestTemplateCommand, "" },
{ "rbac", rbac::RBAC_PERM_COMMAND_RELOAD_RBAC, true, &HandleReloadRBACCommand, "" },
@@ -997,9 +997,9 @@ public:
static bool HandleReloadLocalesAchievementRewardCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Achievement Reward Data...");
+ TC_LOG_INFO("misc", "Re-Loading Achievement Reward Data Locale...");
sAchievementMgr->LoadRewardLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_achievement_reward` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `achievement_reward_locale` reloaded.");
return true;
}
@@ -1013,49 +1013,49 @@ public:
static bool HandleReloadLocalesCreatureCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Creature ...");
+ TC_LOG_INFO("misc", "Re-Loading Creature Template Locale...");
sObjectMgr->LoadCreatureLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_creature` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `creature_template_locale` reloaded.");
return true;
}
static bool HandleReloadLocalesCreatureTextCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Creature Texts...");
+ TC_LOG_INFO("misc", "Re-Loading Creature Texts Locale...");
sCreatureTextMgr->LoadCreatureTextLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_creature_text` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `creature_text_locale` reloaded.");
return true;
}
static bool HandleReloadLocalesGameobjectCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Gameobject ... ");
+ TC_LOG_INFO("misc", "Re-Loading Gameobject Template Locale... ");
sObjectMgr->LoadGameObjectLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_gameobject` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `gameobject_template_locale` reloaded.");
return true;
}
static bool HandleReloadLocalesGossipMenuOptionCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Gossip Menu Option ... ");
+ TC_LOG_INFO("misc", "Re-Loading Gossip Menu Option Locale... ");
sObjectMgr->LoadGossipMenuItemsLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_gossip_menu_option` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `gossip_menu_option_locale` reloaded.");
return true;
}
static bool HandleReloadLocalesPageTextCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Page Text ... ");
+ TC_LOG_INFO("misc", "Re-Loading Page Text Locale... ");
sObjectMgr->LoadPageTextLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_page_text` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `page_text_locale` reloaded.");
return true;
}
static bool HandleReloadLocalesPointsOfInterestCommand(ChatHandler* handler, const char* /*args*/)
{
- TC_LOG_INFO("misc", "Re-Loading Locales Points Of Interest ... ");
+ TC_LOG_INFO("misc", "Re-Loading Points Of Interest Locale... ");
sObjectMgr->LoadPointOfInterestLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_points_of_interest` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `points_of_interest_locale` reloaded.");
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
index 3851a74d263..14c6ec900db 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
@@ -588,7 +588,7 @@ public:
//spell by trap has effect61, this indicate the bar go hostile
if (Unit* tmp = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_PHALANX)))
- tmp->SetFaction(14);
+ tmp->SetFaction(FACTION_MONSTER);
//for later, this event(s) has alot more to it.
//optionally, DONE can trigger bar to go hostile.
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp
index 923b771b04b..39cf1b6345a 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_coren_direbrew.cpp
@@ -99,8 +99,6 @@ enum DirebrewEvents
enum DirebrewMisc
{
- COREN_DIREBREW_FACTION_HOSTILE = 736,
- COREN_DIREBREW_FACTION_FRIEND = 35,
GOSSIP_ID = 11388,
GO_MOLE_MACHINE_TRAP = 188509,
GOSSIP_OPTION_FIGHT = 0,
@@ -145,7 +143,7 @@ public:
{
_Reset();
me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFaction(COREN_DIREBREW_FACTION_FRIEND);
+ me->SetFaction(FACTION_FRIENDLY);
events.SetPhase(PHASE_ALL);
for (uint8 i = 0; i < MAX_ANTAGONISTS; ++i)
@@ -168,7 +166,7 @@ public:
{
events.SetPhase(PHASE_ONE);
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFaction(COREN_DIREBREW_FACTION_HOSTILE);
+ me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON);
me->SetInCombatWithZone();
EntryCheckPredicate pred(NPC_ANTAGONIST);
@@ -359,7 +357,7 @@ public:
void Reset() override
{
- me->SetFaction(COREN_DIREBREW_FACTION_HOSTILE);
+ me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON);
DoCastAOE(SPELL_MOLE_MACHINE_EMERGE, true);
me->SetInCombatWithZone();
}
@@ -401,7 +399,7 @@ public:
break;
case ACTION_ANTAGONIST_HOSTILE:
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFaction(COREN_DIREBREW_FACTION_HOSTILE);
+ me->SetFaction(FACTION_GOBLIN_DARK_IRON_BAR_PATRON);
me->SetInCombatWithZone();
break;
default:
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
index 9015420d079..5017f5e48bd 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
@@ -75,7 +75,7 @@ class boss_emperor_dagran_thaurissan : public CreatureScript
if (Creature* moira = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MOIRA)))
{
moira->AI()->EnterEvadeMode();
- moira->SetFaction(35);
+ moira->SetFaction(FACTION_FRIENDLY);
}
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
index d5af35b77b0..7d709fdaf42 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
@@ -149,7 +149,7 @@ class boss_doomrel : public CreatureScript
{
Initialize();
- me->SetFaction(FACTION_FRIEND);
+ me->SetFaction(FACTION_FRIENDLY);
// was set before event start, so set again
me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
@@ -239,7 +239,7 @@ class boss_doomrel : public CreatureScript
case GOSSIP_ACTION_INFO_DEF + 2:
CloseGossipMenuFor(player);
//start event here
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_DARK_IRON_DWARVES);
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
me->AI()->AttackStart(player);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp
index 219414e29a7..85a38917f2b 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp
@@ -354,7 +354,7 @@ public:
{
if (Creature* boss = instance->GetCreature(TombBossGUIDs[TombEventCounter]))
{
- boss->SetFaction(FACTION_HOSTILE);
+ boss->SetFaction(FACTION_DARK_IRON_DWARVES);
boss->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
if (Unit* target = boss->SelectNearestTarget(500))
boss->AI()->AttackStart(target);
@@ -380,7 +380,7 @@ public:
boss->GetMotionMaster()->MoveTargetedHome();
boss->SetLootRecipient(NULL);
}
- boss->SetFaction(FACTION_FRIEND);
+ boss->SetFaction(FACTION_FRIENDLY);
}
}
GhostKillCount = 0;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
index e5c2d97a9d4..f9f81e46efe 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
@@ -190,7 +190,7 @@ public:
me->SetVisible(true);
me->SetNpcFlags(UNIT_NPC_FLAG_GOSSIP);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR);
me->RemoveAura(SPELL_NEFARIANS_BARRIER);
}
@@ -207,7 +207,7 @@ public:
Talk(SAY_GAMESBEGIN_2);
- me->SetFaction(103);
+ me->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
me->SetNpcFlags(UNIT_NPC_FLAG_NONE);
DoCast(me, SPELL_NEFARIANS_BARRIER);
me->SetStandState(UNIT_STAND_STATE_STAND);
@@ -342,7 +342,7 @@ public:
CreatureID = Entry[urand(0, 4)];
if (Creature* dragon = me->SummonCreature(CreatureID, DrakeSpawnLoc[i]))
{
- dragon->SetFaction(103);
+ dragon->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
dragon->AI()->AttackStart(me->GetVictim());
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
index 184b64a9cde..e5b49dd8910 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
@@ -75,7 +75,7 @@ public:
{
Initialize();
creature->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP);
- creature->SetFaction(35);
+ creature->SetFaction(FACTION_FRIENDLY);
creature->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
@@ -153,7 +153,7 @@ public:
events.ScheduleEvent(EVENT_SPEECH_4, 16000);
break;
case EVENT_SPEECH_4:
- me->SetFaction(103);
+ me->SetFaction(FACTION_DRAGONFLIGHT_BLACK);
if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
AttackStart(player);
break;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
index cd1aeef7b97..72eb8f43cb9 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
@@ -55,7 +55,6 @@ enum Spells
enum Extras
{
OPTION_ID_YOU_CHALLENGED_US = 0,
- FACTION_FRIENDLY = 35,
MENU_OPTION_YOU_CHALLENGED_US = 4108
};
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
index 4e245db8aad..3e73c1e162e 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
@@ -175,7 +175,7 @@ class boss_ragnaros : public CreatureScript
{
//Become unbanished again
me->SetReactState(REACT_AGGRESSIVE);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetEmoteState(EMOTE_ONESHOT_NONE);
me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
@@ -253,7 +253,7 @@ class boss_ragnaros : public CreatureScript
me->InterruptNonMeleeSpells(false);
//Root self
//DoCast(me, 23973);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetEmoteState(EMOTE_STATE_SUBMERGED);
me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
index 28bdb8e9056..c3a65c24fab 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/bosses_opera.cpp
@@ -1382,7 +1382,7 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff)
{
Talk(SAY_JULIANNE_AGGRO);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- me->SetFaction(16);
+ me->SetFaction(FACTION_MONSTER_2);
AggroYellTimer = 0;
} else AggroYellTimer -= diff;
}
@@ -1410,7 +1410,7 @@ void boss_julianne::boss_julianneAI::UpdateAI(uint32 diff)
ENSURE_AI(boss_romulo::boss_romuloAI, pRomulo->AI())->Phase = PHASE_ROMULO;
DoZoneInCombat(pRomulo);
- pRomulo->SetFaction(16);
+ pRomulo->SetFaction(FACTION_MONSTER_2);
}
SummonedRomulo = true;
} else SummonRomuloTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
index 9fa6e43ae5d..1a379d8676e 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
@@ -217,7 +217,7 @@ public:
{
float x = KaelLocations[0][0];
float y = KaelLocations[0][1];
- me->SetPosition(x, y, LOCATION_Z, 0.0f);
+ me->UpdatePosition(x, y, LOCATION_Z, 0.0f);
ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
ThreatContainer::StorageType::const_iterator i = threatlist.begin();
for (i = threatlist.begin(); i != threatlist.end(); ++i)
@@ -454,7 +454,7 @@ public:
Initialize();
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
DoCast(me, SPELL_FLAMESTRIKE2, true);
}
@@ -659,7 +659,7 @@ public:
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetDisableGravity(true);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
DoCast(me, SPELL_ARCANE_SPHERE_PASSIVE, true);
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index d7e50807867..9134885bd46 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -129,7 +129,7 @@ public:
{
Initialize();
events.Reset();
- me->SetFaction(7);
+ me->SetFaction(FACTION_CREATURE);
me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
me->SetStandState(UNIT_STAND_STATE_KNEEL);
me->LoadEquipment(0, true);
@@ -235,7 +235,7 @@ public:
wait_timer -= diff;
else
{
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
phase = PHASE_ATTACKING;
@@ -484,8 +484,7 @@ enum Says_VBM
enum Misc_VBN
{
- QUEST_DEATH_CHALLENGE = 12733,
- FACTION_HOSTILE = 2068
+ QUEST_DEATH_CHALLENGE = 12733
};
class npc_death_knight_initiate : public CreatureScript
@@ -563,7 +562,7 @@ public:
{
if (m_uiDuelTimer <= uiDiff)
{
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_UNDEAD_SCOURGE_2);
if (Unit* unit = ObjectAccessor::GetUnit(*me, m_uiDuelerGUID))
AttackStart(unit);
@@ -789,7 +788,7 @@ public:
{
charmer->RemoveAurasDueToSpell(SPELL_EFFECT_STOLEN_HORSE);
caster->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
- caster->SetFaction(35);
+ caster->SetFaction(FACTION_FRIENDLY);
DoCast(caster, SPELL_CALL_DARK_RIDER, true);
if (Creature* Dark_Rider = me->FindNearestCreature(NPC_DARK_RIDER_OF_ACHERUS, 15))
ENSURE_AI(npc_dark_rider_of_acherus::npc_dark_rider_of_acherusAI, Dark_Rider->AI())->InitDespawnHorse(caster);
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
index 255e709ae90..461d326dd3e 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
@@ -621,7 +621,7 @@ public:
{
Unit* temp = me->SummonCreature(NPC_ACHERUS_GHOUL, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
temp->SetWalk(false);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiGhoulGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
}
@@ -639,7 +639,7 @@ public:
{
Unit* temp = me->SummonCreature(NPC_RAMPAGING_ABOMINATION, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
temp->SetWalk(false);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiAbominationGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
}
@@ -657,7 +657,7 @@ public:
{
Unit* temp = me->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
temp->SetWalk(false);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiWarriorGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
}
@@ -675,7 +675,7 @@ public:
{
Unit* temp = me->SummonCreature(NPC_FLESH_BEHEMOTH, (me->GetPositionX() - 20) + rand32() % 40, (me->GetPositionY() - 20) + rand32() % 40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
temp->SetWalk(false);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiBehemothGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
}
@@ -1507,7 +1507,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_ACHERUS_GHOUL, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiGhoulGUID[i] = temp->GetGUID();
}
}
@@ -1517,7 +1517,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiAbominationGUID[i] = temp->GetGUID();
}
}
@@ -1527,7 +1527,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_RAMPAGING_ABOMINATION, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiWarriorGUID[i] = temp->GetGUID();
}
}
@@ -1537,7 +1537,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_FLESH_BEHEMOTH, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2084);
+ temp->SetFaction(FACTION_UNDEAD_SCOURGE_3);
uiBehemothGUID[i] = temp->GetGUID();
}
}
@@ -1549,7 +1549,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2089);
+ temp->SetFaction(FACTION_SCARLET_CRUSADE);
me->AddThreat(temp, 0.0f);
uiDefenderGUID[i] = temp->GetGUID();
}
@@ -1560,7 +1560,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2089);
+ temp->SetFaction(FACTION_SCARLET_CRUSADE);
me->AddThreat(temp, 0.0f);
uiEarthshatterGUID[i] = temp->GetGUID();
}
@@ -1569,7 +1569,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_KORFAX_CHAMPION_OF_THE_LIGHT, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000);
- temp->SetFaction(2089);
+ temp->SetFaction(FACTION_SCARLET_CRUSADE);
me->AddThreat(temp, 0.0f);
uiKorfaxGUID = temp->GetGUID();
}
@@ -1577,7 +1577,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_LORD_MAXWELL_TYROSUS, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000);
- temp->SetFaction(2089);
+ temp->SetFaction(FACTION_SCARLET_CRUSADE);
me->AddThreat(temp, 0.0f);
uiMaxwellGUID = temp->GetGUID();
}
@@ -1585,7 +1585,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_COMMANDER_ELIGOR_DAWNBRINGER, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 600000);
- temp->SetFaction(2089);
+ temp->SetFaction(FACTION_SCARLET_CRUSADE);
me->AddThreat(temp, 0.0f);
uiEligorGUID = temp->GetGUID();
}
@@ -1593,7 +1593,7 @@ public:
if (!temp)
{
temp = me->SummonCreature(NPC_RAYNE, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 30), float(rand32() % 30), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->SetFaction(2089);
+ temp->SetFaction(FACTION_SCARLET_CRUSADE);
me->AddThreat(temp, 0.0f);
uiRayneGUID = temp->GetGUID();
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
index fea8c330b9c..e97f8a8454d 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
@@ -78,7 +78,7 @@ public:
x -= 3.5f;
y -= 5.0f;
me->GetMotionMaster()->Clear(false);
- me->SetPosition(x, y, z, 0.0f);
+ me->UpdatePosition(x, y, z, 0.0f);
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
index d27c334a0de..75ff54ac3eb 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
@@ -805,7 +805,7 @@ public:
{
float x, y, z;
me->GetPosition(x, y, z); //this visual aura some under ground
- me->SetPosition(x, y, z + 0.35f, 0.0f);
+ me->UpdatePosition(x, y, z + 0.35f, 0.0f);
debuffGUID.Clear();
Despawn();
Creature* debuff = DoSpawnCreature(HELPER, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 14500);
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp
index a1714085160..1cfbabb638d 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/boss_apothecary_hummel.cpp
@@ -56,6 +56,7 @@ enum ApothecarySays
SAY_CALL_BAXTER = 3,
SAY_CALL_FRYE = 4,
SAY_HUMMEL_DEATH = 5,
+ SAY_SUMMON_ADDS = 6,
SAY_BAXTER_DEATH = 0,
SAY_FRYE_DEATH = 0
};
@@ -77,8 +78,6 @@ enum ApothecaryMisc
{
ACTION_START_EVENT = 1,
ACTION_START_FIGHT = 2,
- FACTION_APOTHECARY_HOSTILE = 14,
- FACTION_APOTHECARY_FRIENDLY = 35,
GOSSIP_OPTION_START = 0,
GOSSIP_MENU_HUMMEL = 10847,
QUEST_YOUVE_BEEN_SERVED = 14488,
@@ -119,7 +118,7 @@ class boss_apothecary_hummel : public CreatureScript
_deadCount = 0;
_isDead = false;
events.SetPhase(PHASE_ALL);
- me->SetFaction(FACTION_APOTHECARY_FRIENDLY);
+ me->SetFaction(FACTION_FRIENDLY);
me->SummonCreatureGroup(1);
}
@@ -138,7 +137,7 @@ class boss_apothecary_hummel : public CreatureScript
events.ScheduleEvent(EVENT_HUMMEL_SAY_0, Milliseconds(1));
me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFaction(FACTION_APOTHECARY_HOSTILE);
+ me->SetFaction(FACTION_MONSTER);
DummyEntryCheckPredicate pred;
summons.DoAction(ACTION_START_EVENT, pred);
}
@@ -226,6 +225,7 @@ class boss_apothecary_hummel : public CreatureScript
events.ScheduleEvent(EVENT_PERFUME_SPRAY, Milliseconds(3640));
events.ScheduleEvent(EVENT_CHAIN_REACTION, Seconds(15));
+ Talk(SAY_SUMMON_ADDS);
std::vector<Creature*> trashs;
me->GetCreatureListWithEntryInGrid(trashs, NPC_CROWN_APOTHECARY);
for (Creature* crea : trashs)
@@ -294,7 +294,7 @@ struct npc_apothecary_genericAI : public ScriptedAI
if (action == ACTION_START_EVENT)
{
me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFaction(FACTION_APOTHECARY_HOSTILE);
+ me->SetFaction(FACTION_MONSTER);
me->GetMotionMaster()->MovePoint(1, _movePos);
}
else if (action == ACTION_START_FIGHT)
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
index e7ee54390ed..0a0f528ffdd 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
@@ -161,7 +161,7 @@ public:
if (Creature* Sath = ObjectAccessor::GetCreature(*me, SathGUID))
Sath->AI()->EnterEvadeMode();
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
if (!bJustReset) //first reset at create
{
me->RemoveUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE));
@@ -388,7 +388,7 @@ public:
switch (TalkSequence)
{
case 1:
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
TalkTimer = 1000;
break;
case 2:
@@ -676,7 +676,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_SATH_DEATH);
- me->SetPosition(me->GetPositionX(), me->GetPositionY(), DRAGON_REALM_Z, me->GetOrientation());
+ me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), DRAGON_REALM_Z, me->GetOrientation());
TeleportAllPlayersBack();
if (Creature* Kalecgos = ObjectAccessor::GetCreature(*me, KalecgosGUID))
{
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index 0eff7cda638..146ebefceaf 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -294,7 +294,7 @@ public:
me->RemoveDynObject(SPELL_RING_OF_BLUE_FLAMES);
for (uint8 i = 0; i < 4; ++i)
if (GameObject* pOrb = GetOrb(i))
- pOrb->SetFaction(0);
+ pOrb->SetFaction(FACTION_NONE);
}
void EmpowerOrb(bool all)
@@ -311,7 +311,7 @@ public:
if (GameObject* pOrb = GetOrb(i))
{
pOrb->CastSpell(me, SPELL_RING_OF_BLUE_FLAMES);
- pOrb->SetFaction(35);
+ pOrb->SetFaction(FACTION_FRIENDLY);
pOrb->setActive(true);
pOrb->Refresh();
}
@@ -323,7 +323,7 @@ public:
if (GameObject* pOrb = GetOrb(urand(0, 3)))
{
pOrb->CastSpell(me, SPELL_RING_OF_BLUE_FLAMES);
- pOrb->SetFaction(35);
+ pOrb->SetFaction(FACTION_FRIENDLY);
pOrb->setActive(true);
pOrb->Refresh();
@@ -381,7 +381,7 @@ class go_orb_of_the_blue_flight : public GameObjectScript
{
player->SummonCreature(NPC_POWER_OF_THE_BLUE_DRAGONFLIGHT, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 121000);
player->CastSpell(player, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT, false);
- me->SetFaction(0);
+ me->SetFaction(FACTION_NONE);
if (Creature* pKalec = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_KALECGOS_KJ)))
ENSURE_AI(boss_kalecgos_kj::boss_kalecgos_kjAI, pKalec->AI())->SetRingOfBlueFlames();
diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp
index 1b301d553dc..6d2e392e18d 100644
--- a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp
+++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp
@@ -100,7 +100,7 @@ class boss_archaedas : public CreatureScript
Initialize();
instance->SetData(0, 5); // respawn any dead minions
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(true, UNIT_STATE_ROOT);
me->AddAura(SPELL_FREEZE_ANIM, me);
@@ -116,14 +116,14 @@ class boss_archaedas : public CreatureScript
minion->CastSpell(minion, SPELL_ARCHAEDAS_AWAKEN, true);
minion->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
minion->SetControlled(false, UNIT_STATE_ROOT);
- minion->SetFaction(14);
+ minion->SetFaction(FACTION_MONSTER);
minion->RemoveAura(SPELL_MINION_FREEZE_ANIM);
}
}
void EnterCombat(Unit* /*who*/) override
{
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
}
@@ -272,7 +272,7 @@ class npc_archaedas_minions : public CreatureScript
void EnterCombat(Unit* /*who*/) override
{
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
me->RemoveAllAuras();
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
@@ -352,7 +352,7 @@ class npc_stonekeepers : public CreatureScript
void Reset() override
{
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(true, UNIT_STATE_ROOT);
me->RemoveAllAuras();
@@ -361,7 +361,7 @@ class npc_stonekeepers : public CreatureScript
void EnterCombat(Unit* /*who*/) override
{
- me->SetFaction(14);
+ me->SetFaction(FACTION_FRIENDLY);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetControlled(false, UNIT_STATE_ROOT);
}
diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp
index ac3d2aa110f..0b6128af171 100644
--- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp
+++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp
@@ -149,7 +149,7 @@ class instance_uldaman : public InstanceMapScript
void SetFrozenState(Creature* creature)
{
- creature->SetFaction(35);
+ creature->SetFaction(FACTION_FRIENDLY);
creature->RemoveAllAuras();
creature->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
creature->SetControlled(true, UNIT_STATE_ROOT);
@@ -184,7 +184,7 @@ class instance_uldaman : public InstanceMapScript
if (!target || !target->IsAlive())
continue;
target->SetControlled(false, UNIT_STATE_ROOT);
- target->SetFaction(14);
+ target->SetFaction(FACTION_MONSTER);
target->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
target->RemoveAura(SPELL_MINION_FREEZE_ANIM);
@@ -205,11 +205,11 @@ class instance_uldaman : public InstanceMapScript
for (GuidVector::const_iterator i = archaedasWallMinions.begin(); i != archaedasWallMinions.end(); ++i)
{
Creature* target = instance->GetCreature(*i);
- if (!target || !target->IsAlive() || target->GetFaction() == 14)
+ if (!target || !target->IsAlive() || target->GetFaction() == FACTION_MONSTER)
continue;
target->SetControlled(false, UNIT_STATE_ROOT);
target->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- target->SetFaction(14);
+ target->SetFaction(FACTION_MONSTER);
target->RemoveAura(SPELL_MINION_FREEZE_ANIM);
archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true);
target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true);
@@ -269,7 +269,7 @@ class instance_uldaman : public InstanceMapScript
if (!ironaya)
return;
- ironaya->SetFaction(415);
+ ironaya->SetFaction(FACTION_TITAN);
ironaya->SetControlled(false, UNIT_STATE_ROOT);
ironaya->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
index 3ad749d537d..f9cd1192777 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
@@ -93,7 +93,6 @@ enum Misc
DATA_OHGANOT_SO_FAST = 5762,
- FACTION_NONE = 1665
};
enum SummonGroups
diff --git a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp
index f9f0985b416..0225040f053 100644
--- a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp
@@ -56,8 +56,7 @@ enum ProfessorPhizzlethorpe
QUEST_SUNKEN_TREASURE = 665,
QUEST_GOGGLE_BOGGLE = 26050,
// Creatures
- NPC_VENGEFUL_SURGE = 2776,
- FACTION_SUNKEN_TREASURE = 113
+ NPC_VENGEFUL_SURGE = 2776
};
class npc_professor_phizzlethorpe : public CreatureScript
@@ -113,7 +112,7 @@ class npc_professor_phizzlethorpe : public CreatureScript
{
Talk(SAY_PROGRESS_1, player);
npc_escortAI::Start(false, false, player->GetGUID(), quest);
- me->SetFaction(FACTION_SUNKEN_TREASURE);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
}
}
diff --git a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp
index fd4617bb183..b00f3a0ee9d 100644
--- a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp
@@ -52,8 +52,7 @@ enum RangerLilatha
GO_CAGE = 181152,
NPC_CAPTAIN_HELIOS = 16220,
NPC_MUMMIFIED_HEADHUNTER = 16342,
- NPC_SHADOWPINE_ORACLE = 16343,
- FACTION_QUEST_ESCAPE = 113
+ NPC_SHADOWPINE_ORACLE = 16343
};
class npc_ranger_lilatha : public CreatureScript
@@ -132,7 +131,7 @@ public:
{
if (quest->GetQuestId() == QUEST_ESCAPE_FROM_THE_CATACOMBS)
{
- me->SetFaction(FACTION_QUEST_ESCAPE);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
Start(true, false, player->GetGUID());
}
}
diff --git a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp
index 3fd9345ef0e..96f5b757c88 100644
--- a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp
@@ -45,9 +45,7 @@ enum eOOX
SAY_OOX_END = 4,
QUEST_RESQUE_OOX_09 = 836,
NPC_MARAUDING_OWL = 7808,
- NPC_VILE_AMBUSHER = 7809,
- FACTION_ESCORTEE_A = 774,
- FACTION_ESCORTEE_H = 775
+ NPC_VILE_AMBUSHER = 7809
};
class npc_oox09hl : public CreatureScript
@@ -79,7 +77,7 @@ public:
if (quest->GetQuestId() == QUEST_RESQUE_OOX_09)
{
me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetFaction(player->GetTeam() == ALLIANCE ? FACTION_ESCORTEE_A : FACTION_ESCORTEE_H);
+ me->SetFaction(player->GetTeam() == ALLIANCE ? FACTION_ESCORTEE_A_PASSIVE : FACTION_ESCORTEE_H_PASSIVE);
Talk(SAY_OOX_START, player);
npc_escortAI::Start(false, false, player->GetGUID(), quest);
}
diff --git a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp
index 16306014b1d..5015ff30cc2 100644
--- a/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_stranglethorn_vale.cpp
@@ -39,8 +39,6 @@ enum Yenniku
{
SPELL_YENNIKUS_RELEASE = 3607,
QUEST_SAVING_YENNIKU = 592,
- FACTION_HORDE_GENERIC = 83,
- FACTION_TROLL_BLOODSCALP = 28
};
class npc_yenniku : public CreatureScript
diff --git a/src/server/scripts/EasternKingdoms/zone_undercity.cpp b/src/server/scripts/EasternKingdoms/zone_undercity.cpp
index 56cc8d49c25..f28570dc5d5 100644
--- a/src/server/scripts/EasternKingdoms/zone_undercity.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_undercity.cpp
@@ -150,7 +150,7 @@ public:
if (Creature* target = ObjectAccessor::GetCreature(*summoned, targetGUID))
{
target->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ() + 15.0f, me->GetOrientation(), 0);
- target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f);
+ target->UpdatePosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f);
summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false);
}
@@ -298,7 +298,7 @@ public:
{
me->SetDisableGravity(true);
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetDistance(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW) / (5000 * 0.001f));
- me->SetPosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation());
+ me->UpdatePosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation());
EventMove = false;
} else EventMoveTimer -= diff;
}
diff --git a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp
index 856080be6fa..f192a4bcf8f 100644
--- a/src/server/scripts/EasternKingdoms/zone_wetlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_wetlands.cpp
@@ -39,7 +39,6 @@ EndContentData */
enum TapokeSlim
{
QUEST_MISSING_DIPLO_PT11 = 1249,
- FACTION_ENEMY = 168,
SPELL_STEALTH = 1785,
SPELL_CALL_FRIENDS = 16457, //summons 1x friend
NPC_SLIMS_FRIEND = 4971,
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
index 823ddd33aa9..39a1cbd7dde 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
@@ -917,7 +917,7 @@ void hyjalAI::HideNearPos(float x, float y)
for (std::list<Creature*>::const_iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
{
(*itr)->SetVisible(false);
- (*itr)->SetFaction(35);//make them friendly so mobs won't attack them
+ (*itr)->SetFaction(FACTION_FRIENDLY);//make them friendly so mobs won't attack them
}
}
}
@@ -995,7 +995,7 @@ void hyjalAI::DoOverrun(uint32 faction, const uint32 diff)
if ((*itr) && (*itr)->IsAlive())
{
(*itr)->CastSpell(*itr, SPELL_TELEPORT_VISUAL, true);
- (*itr)->SetFaction(35);//make them friendly so mobs won't attack them
+ (*itr)->SetFaction(FACTION_FRIENDLY);//make them friendly so mobs won't attack them
(*itr)->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index 00ff25951df..4e280a1ca18 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -1175,7 +1175,7 @@ public:
me->GetPosition(x, y, z);
me->UpdateGroundPositionZ(x, y, z);
me->GetMotionMaster()->MovePoint(0, x, y, z);
- me->SetPosition(x, y, z, 0);
+ me->UpdatePosition(x, y, z, 0);
}
void EnterCombat(Unit* /*who*/) override { }
@@ -1293,7 +1293,7 @@ public:
me->GetPosition(x, y, z);
me->UpdateGroundPositionZ(x, y, z);
me->GetMotionMaster()->MovePoint(0, x, y, z);
- me->SetPosition(x, y, z, 0);
+ me->UpdatePosition(x, y, z, 0);
hyjal_trashAI::JustDied(killer);
}
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
index cb715b6f1e2..298a3535107 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
@@ -82,7 +82,7 @@ public:
if (Invisible && InvisibleTimer <= diff)
{
//Become visible again
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
//Noxxion model
me->SetDisplayId(11172);
@@ -122,7 +122,7 @@ public:
//Interrupt any spell casting
//me->m_canMove = true;
me->InterruptNonMeleeSpells(false);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
// Invisible Model
me->SetDisplayId(11686);
diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp
index 2c1059a9bd9..6d1f4c70be9 100644
--- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp
+++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp
@@ -58,8 +58,6 @@ enum Belnistrasz
EVENT_FIREBALL = 5,
EVENT_FROST_NOVA = 6,
- FACTION_ESCORT = 250,
-
PATH_ESCORT = 871710,
POINT_REACH_IDOL = 17,
@@ -137,7 +135,7 @@ public:
eventInProgress = true;
Talk(SAY_QUEST_ACCEPTED);
me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
- me->SetFaction(FACTION_ESCORT);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE);
me->GetMotionMaster()->MovePath(PATH_ESCORT, false);
}
}
diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp
index 19c999033d7..470908d9a5d 100644
--- a/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp
+++ b/src/server/scripts/Kalimdor/RazorfenKraul/instance_razorfen_kraul.cpp
@@ -57,7 +57,7 @@ public:
switch (go->GetEntry())
{
case 21099: DoorWardGUID = go->GetGUID(); break;
- case 20920: go->SetFaction(0); break; // big fat fugly hack
+ case 20920: go->SetFaction(FACTION_NONE); break; // big fat fugly hack
}
}
diff --git a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp
index 3f1ed9792ff..68d11185f33 100644
--- a/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp
+++ b/src/server/scripts/Kalimdor/RazorfenKraul/razorfen_kraul.cpp
@@ -58,7 +58,7 @@ public:
{
Start(true, false, player->GetGUID());
Talk(SAY_READY, player);
- me->SetFaction(113);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
}
}
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp
index 340ae314f92..59d33f235f4 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp
@@ -1042,7 +1042,7 @@ public:
if (!target->HasAura(SPELL_DIGESTIVE_ACID))
{
- me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
+ me->UpdatePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
if (Creature* pPortal = me->SummonCreature(NPC_SMALL_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
{
pPortal->SetReactState(REACT_PASSIVE);
@@ -1159,7 +1159,7 @@ public:
if (!target->HasAura(SPELL_DIGESTIVE_ACID))
{
- me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
+ me->UpdatePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
if (Creature* pPortal = me->SummonCreature(NPC_GIANT_PORTAL, *me, TEMPSUMMON_CORPSE_DESPAWN))
{
pPortal->SetReactState(REACT_PASSIVE);
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp
index 3495a1a6d2b..067f326e011 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_ouro.cpp
@@ -111,7 +111,7 @@ public:
//Cast
me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
DoCast(me, SPELL_DIRTMOUND_PASSIVE);
Submerged = true;
@@ -134,7 +134,7 @@ public:
if (Submerged && Back_Timer <= diff)
{
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
DoCastVictim(SPELL_GROUND_RUPTURE);
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
index 4dd49bb1c66..b27a339ed7b 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
@@ -227,8 +227,8 @@ struct boss_twinemperorsAI : public ScriptedAI
thisPos.Relocate(me);
Position otherPos;
otherPos.Relocate(pOtherBoss);
- pOtherBoss->SetPosition(thisPos);
- me->SetPosition(otherPos);
+ pOtherBoss->UpdatePosition(thisPos);
+ me->UpdatePosition(otherPos);
SetAfterTeleport();
ENSURE_AI(boss_twinemperorsAI, pOtherBoss->AI())->SetAfterTeleport();
@@ -332,7 +332,7 @@ struct boss_twinemperorsAI : public ScriptedAI
if (c->isDead())
{
c->Respawn();
- c->SetFaction(7);
+ c->SetFaction(FACTION_CREATURE);
c->RemoveAllAuras();
}
if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE))
@@ -427,7 +427,7 @@ public:
void CastSpellOnBug(Creature* target) override
{
- target->SetFaction(14);
+ target->SetFaction(FACTION_MONSTER);
target->AI()->AttackStart(me->getThreatManager().getHostilTarget());
target->AddAura(SPELL_MUTATE_BUG, target);
target->SetFullHealth();
@@ -518,7 +518,7 @@ public:
void CastSpellOnBug(Creature* target) override
{
- target->SetFaction(14);
+ target->SetFaction(FACTION_MONSTER);
target->AddAura(SPELL_EXPLODEBUG, target);
target->SetFullHealth();
}
diff --git a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp
index e3019c885bd..2c99ade96d3 100644
--- a/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp
+++ b/src/server/scripts/Kalimdor/WailingCaverns/wailing_caverns.cpp
@@ -329,7 +329,7 @@ public:
Talk(SAY_MAKE_PREPARATIONS);
- me->SetFaction(250);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE);
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
Start(false, false, player->GetGUID());
diff --git a/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp b/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp
index f8b39df3d93..03443d77c6f 100644
--- a/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp
+++ b/src/server/scripts/Kalimdor/ZulFarrak/boss_zum_rah.cpp
@@ -48,11 +48,6 @@ enum Events
EVENT_HEALING_WAVE = 4
};
-enum Faction
-{
- ZUMRAH_FRIENDLY_FACTION = 35
-};
-
class boss_zum_rah : public CreatureScript
{
public:
@@ -74,7 +69,7 @@ public:
void Reset() override
{
- me->SetFaction(ZUMRAH_FRIENDLY_FACTION); // areatrigger sets faction to enemy
+ me->SetFaction(FACTION_FRIENDLY); // areatrigger sets faction to enemy
Initialize();
}
diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp
index 6b74f7d0221..3589c70fbec 100644
--- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp
+++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp
@@ -43,13 +43,6 @@ EndContentData */
## npc_sergeant_bly
######*/
-enum blyAndCrewFactions
-{
- FACTION_HOSTILE = 14,
- FACTION_FRIENDLY = 35, //while in cages (so the trolls won't attack them while they're caged)
- FACTION_FREED = 250 //after release (so they'll be hostile towards trolls)
-};
-
enum blySays
{
SAY_1 = 0,
@@ -120,7 +113,7 @@ public:
Text_Timer = 5000;
break;
case 3:
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_MONSTER);
if (Player* target = ObjectAccessor::GetPlayer(*me, PlayerGUID))
AttackStart(target);
@@ -165,7 +158,7 @@ public:
{
if (Creature* crew = ObjectAccessor::GetCreature(*me, instance->GetGuidData(entry)))
if (crew->IsAlive())
- crew->SetFaction(FACTION_HOSTILE);
+ crew->SetFaction(FACTION_MONSTER);
}
bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
@@ -239,7 +232,7 @@ public:
crew->SetWalk(true);
crew->SetHomePosition(x, y, z, 0);
crew->GetMotionMaster()->MovePoint(1, x, y, z);
- crew->SetFaction(FACTION_FREED);
+ crew->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_ACTIVE);
}
}
};
diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp
index 854e5322667..5fcf56a797e 100644
--- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp
+++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp
@@ -44,7 +44,6 @@ enum RuulSnowhoof
NPC_THISTLEFUR_TOTEMIC = 3922,
NPC_THISTLEFUR_PATHFINDER = 3926,
QUEST_FREEDOM_TO_RUUL = 6482,
- FACTION_QUEST = 113,
GO_CAGE = 178147
};
@@ -84,7 +83,7 @@ public:
{
if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL)
{
- me->SetFaction(FACTION_QUEST);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
npc_escortAI::Start(true, false, player->GetGUID());
}
}
@@ -227,7 +226,7 @@ public:
if (quest->GetQuestId() == QUEST_VORSHA)
{
Talk(SAY_MUG_START1);
- me->SetFaction(FACTION_QUEST);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
npc_escortAI::Start(true, false, player->GetGUID());
}
}
diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp
index b834317359b..4bef27b450a 100644
--- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp
+++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp
@@ -188,7 +188,6 @@ enum Overgrind
AREA_COVE = 3579,
AREA_ISLE = 3639,
QUEST_GNOMERCY = 9537,
- FACTION_HOSTILE = 14,
SPELL_DYNAMITE = 7978
};
@@ -233,7 +232,7 @@ public:
bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
CloseGossipMenuFor(player);
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_MONSTER);
me->Attack(player, true);
return false;
}
@@ -339,8 +338,7 @@ enum Magwin
EVENT_STAND = 3,
EVENT_TALK_END = 4,
EVENT_COWLEN_TALK = 5,
- QUEST_A_CRY_FOR_HELP = 9528,
- FACTION_QUEST = 113
+ QUEST_A_CRY_FOR_HELP = 9528
};
class npc_magwin : public CreatureScript
@@ -405,7 +403,7 @@ public:
case EVENT_ACCEPT_QUEST:
if (Player* player = ObjectAccessor::GetPlayer(*me, _player))
Talk(SAY_START, player);
- me->SetFaction(FACTION_QUEST);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
_events.ScheduleEvent(EVENT_START_ESCORT, Seconds(1));
break;
case EVENT_START_ESCORT:
diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
index 99cc3ce925c..88429574c30 100644
--- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
@@ -99,7 +99,6 @@ enum Hendel
EMOTE_SURRENDER = 4,
QUEST_MISSING_DIPLO_PT16 = 1324,
- FACTION_HOSTILE = 168, //guessed, may be different
NPC_SENTRY = 5184, //helps hendel
NPC_JAINA = 4968, //appears once hendel gives up
@@ -149,7 +148,7 @@ public:
void QuestAccept(Player* /*player*/, Quest const* quest) override
{
if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT16)
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_ENEMY);
}
};
diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp
index bf1dc96d5e4..661eef0ad1f 100644
--- a/src/server/scripts/Kalimdor/zone_silithus.cpp
+++ b/src/server/scripts/Kalimdor/zone_silithus.cpp
@@ -54,9 +54,6 @@ enum EternalBoard
{
QUEST_A_PAWN_ON_THE_ETERNAL_BOARD = 8519,
- FACTION_HOSTILE = 14,
- FACTION_FRIENDLY = 35,
-
EVENT_AREA_RADIUS = 65, // 65yds
EVENT_COOLDOWN = 500000, // in ms. appears after event completed or failed (should be = Adds despawn time)
@@ -985,7 +982,7 @@ public:
Merithra->SetNpcFlags(UNIT_NPC_FLAG_NONE);
Merithra->SetStandState(UNIT_STAND_STATE_STAND);
Merithra->SetDisplayId(MERITHRA_NIGHT_ELF_FORM);
- Merithra->SetFaction(35);
+ Merithra->SetFaction(FACTION_FRIENDLY);
}
if (Caelestrasz)
@@ -993,7 +990,7 @@ public:
Caelestrasz->SetNpcFlags(UNIT_NPC_FLAG_NONE);
Caelestrasz->SetStandState(UNIT_STAND_STATE_STAND);
Caelestrasz->SetDisplayId(CAELESTRASZ_NIGHT_ELF_FORM);
- Caelestrasz->SetFaction(35);
+ Caelestrasz->SetFaction(FACTION_FRIENDLY);
}
if (Arygos)
@@ -1001,7 +998,7 @@ public:
Arygos->SetNpcFlags(UNIT_NPC_FLAG_NONE);
Arygos->SetStandState(UNIT_STAND_STATE_STAND);
Arygos->SetDisplayId(ARYGOS_GNOME_FORM);
- Arygos->SetFaction(35);
+ Arygos->SetFaction(FACTION_FRIENDLY);
}
if (Anachronos)
diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp
index 78d64e4d21a..6a070468b38 100644
--- a/src/server/scripts/Kalimdor/zone_tanaris.cpp
+++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp
@@ -90,7 +90,7 @@ public:
void Reset() override
{
Initialize();
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
}
void SendItem(Unit* receiver)
@@ -120,7 +120,7 @@ public:
{
if (SwitchFactionTimer <= diff)
{
- me->SetFaction(91);
+ me->SetFaction(FACTION_ELEMENTAL);
isFriendly = false;
} else SwitchFactionTimer -= diff;
}
@@ -362,7 +362,7 @@ public:
{
if (quest->GetQuestId() == Q_OOX17)
{
- me->SetFaction(113);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
me->SetFullHealth();
me->SetStandState(UNIT_STAND_STATE_STAND);
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
index fd602f78a6d..734f14e65f4 100644
--- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp
+++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
@@ -87,8 +87,7 @@ enum Gilthares
SAY_GIL_FREED = 7,
QUEST_FREE_FROM_HOLD = 898,
- AREA_MERCHANT_COAST = 391,
- FACTION_ESCORTEE = 232 //guessed, possible not needed for this quest
+ AREA_MERCHANT_COAST = 391
};
class npc_gilthares : public CreatureScript
@@ -150,7 +149,7 @@ public:
{
if (quest->GetQuestId() == QUEST_FREE_FROM_HOLD)
{
- me->SetFaction(FACTION_ESCORTEE);
+ me->SetFaction(FACTION_ESCORTEE_H_NEUTRAL_ACTIVE);
me->SetStandState(UNIT_STAND_STATE_STAND);
Talk(SAY_GIL_START, player);
diff --git a/src/server/scripts/Kalimdor/zone_winterspring.cpp b/src/server/scripts/Kalimdor/zone_winterspring.cpp
index d29175c8985..81b79d276cb 100644
--- a/src/server/scripts/Kalimdor/zone_winterspring.cpp
+++ b/src/server/scripts/Kalimdor/zone_winterspring.cpp
@@ -587,7 +587,7 @@ public:
if (quest->GetQuestId() == QUEST_GUARDIANS_ALTAR)
{
Talk(SAY_QUEST_START);
- me->SetFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE);
+ me->SetFaction(FACTION_ESCORTEE_A_NEUTRAL_PASSIVE);
Start(false, false, player->GetGUID(), quest);
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
index 81dcf1846a6..895b9e15cc4 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
@@ -195,7 +195,7 @@ public:
{
damage = 0;
EnterEvadeMode();
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
bDone = true;
}
}
@@ -323,7 +323,7 @@ public:
{
damage = 0;
EnterEvadeMode();
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
bDone = true;
}
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index 868bb4e07c8..34af2872fdd 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -226,7 +226,7 @@ class boss_anubarak_trial : public CreatureScript
for (int i = 0; i < 10; i++)
if (Creature* scarab = me->SummonCreature(NPC_SCARAB, AnubarakLoc[1].GetPositionX()+urand(0, 50)-25, AnubarakLoc[1].GetPositionY()+urand(0, 50)-25, AnubarakLoc[1].GetPositionZ()))
{
- scarab->SetFaction(31);
+ scarab->SetFaction(FACTION_PREY);
scarab->GetMotionMaster()->MoveRandom(10);
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index d4976c75255..cdf2feee3e8 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -204,7 +204,6 @@ enum Actions
enum Misc
{
DATA_MADE_A_MESS = 45374613, // 4537, 4613 are achievement IDs
- FACTION_SCOURGE = 974,
GOSSIP_MENU_MURADIN_BRONZEBEARD = 10934,
GOSSIP_MENU_HIGH_OVERLORD_SAURFANG = 10952
@@ -463,7 +462,7 @@ class boss_deathbringer_saurfang : public CreatureScript
{
case EVENT_INTRO_ALLIANCE_2:
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(FACTION_SCOURGE);
+ me->SetFaction(FACTION_UNDEAD_SCOURGE);
Talk(SAY_INTRO_ALLIANCE_2);
break;
case EVENT_INTRO_ALLIANCE_3:
@@ -476,7 +475,7 @@ class boss_deathbringer_saurfang : public CreatureScript
break;
case EVENT_INTRO_HORDE_2:
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(FACTION_SCOURGE);
+ me->SetFaction(FACTION_UNDEAD_SCOURGE);
Talk(SAY_INTRO_HORDE_2);
break;
case EVENT_INTRO_HORDE_4:
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index f4e8d4e10b1..638c600905f 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -57,62 +57,68 @@ enum ScriptTexts
enum Spells
{
// Lady Deathwhisper
- SPELL_MANA_BARRIER = 70842,
- SPELL_SHADOW_BOLT = 71254,
- SPELL_DEATH_AND_DECAY = 71001,
- SPELL_DOMINATE_MIND = 71289,
- SPELL_DOMINATE_MIND_SCALE = 71290,
- SPELL_FROSTBOLT = 71420,
- SPELL_FROSTBOLT_VOLLEY = 72905,
- SPELL_TOUCH_OF_INSIGNIFICANCE = 71204,
- SPELL_SUMMON_SHADE = 71363,
- SPELL_SHADOW_CHANNELING = 43897,
- SPELL_DARK_TRANSFORMATION_T = 70895,
- SPELL_DARK_EMPOWERMENT_T = 70896,
- SPELL_DARK_MARTYRDOM_T = 70897,
- SPELL_SUMMON_SPIRITS = 72478,
+ SPELL_MANA_BARRIER = 70842,
+ SPELL_SHADOW_BOLT = 71254,
+ SPELL_DEATH_AND_DECAY = 71001,
+ SPELL_DOMINATE_MIND = 71289,
+ SPELL_DOMINATE_MIND_SCALE = 71290,
+ SPELL_FROSTBOLT = 71420,
+ SPELL_FROSTBOLT_VOLLEY = 72905,
+ SPELL_TOUCH_OF_INSIGNIFICANCE = 71204,
+ SPELL_SUMMON_SHADE = 71363,
+ SPELL_SHADOW_CHANNELING = 43897,
+ SPELL_DARK_TRANSFORMATION_T = 70895,
+ SPELL_DARK_EMPOWERMENT_T = 70896,
+ SPELL_DARK_MARTYRDOM_T = 70897,
+ SPELL_SUMMON_SPIRITS = 72478,
// Achievement
- SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check
+ SPELL_FULL_HOUSE = 72827, // does not exist in dbc but still can be used for criteria check
// Both Adds
- SPELL_TELEPORT_VISUAL = 41236,
- SPELL_CLEAR_ALL_DEBUFFS = 34098,
- SPELL_FULL_HEAL = 17683,
- SPELL_PERMANENT_FEIGN_DEATH = 70628,
+ SPELL_TELEPORT_VISUAL = 41236,
+ SPELL_CLEAR_ALL_DEBUFFS = 34098,
+ SPELL_FULL_HEAL = 17683,
+ SPELL_PERMANENT_FEIGN_DEATH = 70628,
// Fanatics
- SPELL_DARK_TRANSFORMATION = 70900,
- SPELL_NECROTIC_STRIKE = 70659,
- SPELL_SHADOW_CLEAVE = 70670,
- SPELL_VAMPIRIC_MIGHT = 70674,
- SPELL_FANATIC_S_DETERMINATION = 71235,
- SPELL_DARK_MARTYRDOM_FANATIC = 71236,
+ SPELL_DARK_TRANSFORMATION = 70900,
+ SPELL_NECROTIC_STRIKE = 70659,
+ SPELL_SHADOW_CLEAVE = 70670,
+ SPELL_VAMPIRIC_MIGHT = 70674,
+ SPELL_FANATIC_S_DETERMINATION = 71235,
+ SPELL_DARK_MARTYRDOM_FANATIC = 71236,
+ SPELL_DARK_MARTYRDOM_FANATIC_25N = 72495,
+ SPELL_DARK_MARTYRDOM_FANATIC_10H = 72496,
+ SPELL_DARK_MARTYRDOM_FANATIC_25H = 72497,
// Adherents
- SPELL_DARK_EMPOWERMENT = 70901,
- SPELL_FROST_FEVER = 67767,
- SPELL_DEATHCHILL_BOLT = 70594,
- SPELL_DEATHCHILL_BLAST = 70906,
- SPELL_CURSE_OF_TORPOR = 71237,
- SPELL_SHROUD_OF_THE_OCCULT = 70768,
- SPELL_ADHERENT_S_DETERMINATION = 71234,
- SPELL_DARK_MARTYRDOM_ADHERENT = 70903,
+ SPELL_DARK_EMPOWERMENT = 70901,
+ SPELL_FROST_FEVER = 67767,
+ SPELL_DEATHCHILL_BOLT = 70594,
+ SPELL_DEATHCHILL_BLAST = 70906,
+ SPELL_CURSE_OF_TORPOR = 71237,
+ SPELL_SHROUD_OF_THE_OCCULT = 70768,
+ SPELL_ADHERENT_S_DETERMINATION = 71234,
+ SPELL_DARK_MARTYRDOM_ADHERENT = 70903,
+ SPELL_DARK_MARTYRDOM_ADHERENT_25N = 72498,
+ SPELL_DARK_MARTYRDOM_ADHERENT_10H = 72499,
+ SPELL_DARK_MARTYRDOM_ADHERENT_25H = 72500,
// Vengeful Shade
- SPELL_VENGEFUL_BLAST = 71544,
- SPELL_VENGEFUL_BLAST_PASSIVE = 71494,
- SPELL_VENGEFUL_BLAST_25N = 72010,
- SPELL_VENGEFUL_BLAST_10H = 72011,
- SPELL_VENGEFUL_BLAST_25H = 72012,
+ SPELL_VENGEFUL_BLAST = 71544,
+ SPELL_VENGEFUL_BLAST_PASSIVE = 71494,
+ SPELL_VENGEFUL_BLAST_25N = 72010,
+ SPELL_VENGEFUL_BLAST_10H = 72011,
+ SPELL_VENGEFUL_BLAST_25H = 72012,
// Darnavan
- SPELL_BLADESTORM = 65947,
- SPELL_CHARGE = 65927,
- SPELL_INTIMIDATING_SHOUT = 65930,
- SPELL_MORTAL_STRIKE = 65926,
- SPELL_SHATTERING_THROW = 65940,
- SPELL_SUNDER_ARMOR = 65936,
+ SPELL_BLADESTORM = 65947,
+ SPELL_CHARGE = 65927,
+ SPELL_INTIMIDATING_SHOUT = 65930,
+ SPELL_MORTAL_STRIKE = 65926,
+ SPELL_SHATTERING_THROW = 65940,
+ SPELL_SUNDER_ARMOR = 65936,
};
enum EventTypes
@@ -359,7 +365,7 @@ class boss_lady_deathwhisper : public CreatureScript
{
if (darnavan->IsAlive())
{
- darnavan->SetFaction(35);
+ darnavan->SetFaction(FACTION_FRIENDLY);
darnavan->CombatStop(true);
darnavan->GetMotionMaster()->MoveIdle();
darnavan->SetReactState(REACT_PASSIVE);
@@ -640,6 +646,9 @@ class npc_cult_fanatic : public CreatureScript
DoCastSelf(SPELL_DARK_MARTYRDOM_FANATIC);
break;
case SPELL_DARK_MARTYRDOM_FANATIC:
+ case SPELL_DARK_MARTYRDOM_FANATIC_25N:
+ case SPELL_DARK_MARTYRDOM_FANATIC_10H:
+ case SPELL_DARK_MARTYRDOM_FANATIC_25H:
_scheduler
.Schedule(Seconds(2), [this](TaskContext /*context*/)
{
@@ -739,6 +748,9 @@ class npc_cult_adherent : public CreatureScript
DoCastSelf(SPELL_DARK_MARTYRDOM_ADHERENT);
break;
case SPELL_DARK_MARTYRDOM_ADHERENT:
+ case SPELL_DARK_MARTYRDOM_ADHERENT_25N:
+ case SPELL_DARK_MARTYRDOM_ADHERENT_10H:
+ case SPELL_DARK_MARTYRDOM_ADHERENT_25H:
_scheduler
.Schedule(Seconds(2), [this](TaskContext /*context*/)
{
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index 0a7857225ad..97ba864358a 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -264,7 +264,7 @@ class ValithriaDespawner : public BasicEvent
creature->SetRespawnDelay(10);
if (CreatureData const* data = creature->GetCreatureData())
- creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation);
+ creature->UpdatePosition(data->posX, data->posY, data->posZ, data->orientation);
creature->DespawnOrUnsummon();
creature->SetCorpseDelay(corpseDelay);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 1e857d6164c..1462ebc1df1 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -358,7 +358,7 @@ class FrostwingGauntletRespawner
creature->SetRespawnDelay(2);
if (CreatureData const* data = creature->GetCreatureData())
- creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation);
+ creature->UpdatePosition(data->posX, data->posY, data->posZ, data->orientation);
creature->DespawnOrUnsummon();
creature->SetCorpseDelay(corpseDelay);
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 0aa77ef0eb2..cb85a35c884 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -175,12 +175,6 @@ enum Seats
SEAT_0 = 0
};
-enum Factions
-{
- // Needed for melee hover disks /when Nexus Lords die/
- FACTION_FRIENDLY = 35
-};
-
enum Actions
{
// Malygos
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp
index a75650dd6ba..48b1772ea95 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp
@@ -261,7 +261,7 @@ public:
for (uint8 n = 0; n < 3; ++n)
time[n] = 0;
me->GetMotionMaster()->Clear();
- me->SetPosition(CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation());
+ me->UpdatePosition(CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation());
DoCast(me, SPELL_TELESTRA_BACK);
me->SetVisible(true);
if (Phase == 1)
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp
index 857ce9c32b4..5b3228e6413 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/instance_nexus.cpp
@@ -23,11 +23,6 @@
#include "nexus.h"
#include "Player.h"
-enum Factions
-{
- FACTION_HOSTILE_FOR_ALL = 16
-};
-
class instance_nexus : public InstanceMapScript
{
public:
@@ -61,31 +56,31 @@ class instance_nexus : public InstanceMapScript
// Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
case NPC_ALLIANCE_BERSERKER:
if (ServerAllowsTwoSideGroups())
- creature->SetFaction(FACTION_HOSTILE_FOR_ALL);
+ creature->SetFaction(FACTION_MONSTER_2);
if (_teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_HORDE_BERSERKER);
break;
case NPC_ALLIANCE_RANGER:
if (ServerAllowsTwoSideGroups())
- creature->SetFaction(FACTION_HOSTILE_FOR_ALL);
+ creature->SetFaction(FACTION_MONSTER_2);
if (_teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_HORDE_RANGER);
break;
case NPC_ALLIANCE_CLERIC:
if (ServerAllowsTwoSideGroups())
- creature->SetFaction(FACTION_HOSTILE_FOR_ALL);
+ creature->SetFaction(FACTION_MONSTER_2);
if (_teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_HORDE_CLERIC);
break;
case NPC_ALLIANCE_COMMANDER:
if (ServerAllowsTwoSideGroups())
- creature->SetFaction(FACTION_HOSTILE_FOR_ALL);
+ creature->SetFaction(FACTION_MONSTER_2);
if (_teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_HORDE_COMMANDER);
break;
case NPC_COMMANDER_STOUTBEARD:
if (ServerAllowsTwoSideGroups())
- creature->SetFaction(FACTION_HOSTILE_FOR_ALL);
+ creature->SetFaction(FACTION_MONSTER_2);
if (_teamInInstance == ALLIANCE)
creature->UpdateEntry(NPC_COMMANDER_KOLURG);
break;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index 3f622a72c83..201655985d1 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -538,7 +538,7 @@ class boss_algalon_the_observer : public CreatureScript
damage = 0;
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
DoCast(me, SPELL_SELF_STUN);
events.Reset();
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 09240de5649..004760c07ee 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -780,7 +780,7 @@ class boss_flame_leviathan_safety_container : public CreatureScript
me->GetPosition(x, y, z);
z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z);
me->GetMotionMaster()->MovePoint(0, x, y, z);
- me->SetPosition(x, y, z, 0);
+ me->UpdatePosition(x, y, z, 0);
}
void UpdateAI(uint32 /*diff*/) override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
index 33e346e0c94..e0a73d09571 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
@@ -226,7 +226,7 @@ class npc_iron_roots : public CreatureScript
SetCombatMovement(false);
me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
me->SetReactState(REACT_PASSIVE);
}
@@ -270,6 +270,7 @@ class boss_freya : public CreatureScript
{
boss_freyaAI(Creature* creature) : BossAI(creature, BOSS_FREYA)
{
+ _encounterFinished = false;
Initialize();
memset(elementalTimer, 0, sizeof(elementalTimer));
diffTimer = 0;
@@ -312,9 +313,13 @@ class boss_freya : public CreatureScript
bool checkElementalAlive[2];
bool trioDefeated[2];
bool random[3];
+ bool _encounterFinished;
void Reset() override
{
+ if (_encounterFinished)
+ return;
+
_Reset();
Initialize();
}
@@ -595,6 +600,11 @@ class boss_freya : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
+ if (_encounterFinished)
+ return;
+
+ _encounterFinished = true;
+
//! Freya's chest is dynamically spawned on death by different spells.
const uint32 summonSpell[2][4] =
{
@@ -606,15 +616,15 @@ class boss_freya : public CreatureScript
me->CastSpell((Unit*)NULL, summonSpell[me->GetMap()->GetDifficultyID() - DIFFICULTY_10_N][elderCount], true);
Talk(SAY_DEATH);
+
me->SetReactState(REACT_PASSIVE);
- _JustDied();
- me->RemoveAllAuras();
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAllAttackers();
me->AttackStop();
- me->SetFaction(35);
- me->DeleteThreatList();
- me->CombatStop(true);
+ me->SetFaction(FACTION_FRIENDLY);
me->DespawnOrUnsummon(7500);
me->CastSpell(me, SPELL_KNOCK_ON_WOOD_CREDIT, true);
+ _JustDied();
for (uint8 n = 0; n < 3; ++n)
{
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
index a320994dc07..6635ece7ee9 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
@@ -408,7 +408,7 @@ class boss_hodir : public CreatureScript
DoCastAOE(SPELL_KILL_CREDIT, true); /// need to be cast before changing boss faction
/// spell will target enemies only
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->DespawnOrUnsummon(10000);
_JustDied();
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
index cfe2d3879d1..76acc9e7c45 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_ignis.cpp
@@ -180,7 +180,7 @@ class boss_ignis : public CreatureScript
{
if (summon->GetEntry() == NPC_IRON_CONSTRUCT)
{
- summon->SetFaction(16);
+ summon->SetFaction(FACTION_MONSTER_2);
summon->SetReactState(REACT_AGGRESSIVE);
summon->RemoveUnitFlag(UnitFlags(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED | UNIT_FLAG_STUNNED | UNIT_FLAG_IMMUNE_TO_PC));
summon->SetControlled(false, UNIT_STATE_ROOT);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
index 690a1ecdbfc..b23e296f0df 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp
@@ -638,7 +638,7 @@ class boss_mimiron : public CreatureScript
case EVENT_OUTTRO_1:
me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL_1);
DoCast(me, SPELL_SLEEP_VISUAL_2);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
events.ScheduleEvent(EVENT_OUTTRO_2, 3000);
break;
case EVENT_OUTTRO_2:
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp
index a833e13aeec..825718bd3ee 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_thorim.cpp
@@ -15,27 +15,427 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "MoveSplineInit.h"
+#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "TypeContainerVisitor.h"
+#include "CellImpl.h"
+#include "GridNotifiersImpl.h"
#include "ulduar.h"
+#include "SpellAuras.h"
+#include "SpellMgr.h"
+#include <G3D/Vector3.h>
+#include "AreaBoundary.h"
+#include "InstanceScript.h"
+#include "ObjectAccessor.h"
+#include "MotionMaster.h"
+
+enum Spells
+{
+ // Thorim
+ SPELL_SHEATH_OF_LIGHTNING = 62276,
+ SPELL_STORMHAMMER = 62042,
+ SPELL_STORMHAMMER_SIF = 64767,
+ SPELL_STORMHAMMER_BOOMERANG = 64909,
+ SPELL_DEAFENING_THUNDER = 62470,
+ SPELL_CHARGE_ORB = 62016,
+ SPELL_SUMMON_LIGHTNING_ORB = 62391,
+ SPELL_LIGHTNING_DESTRUCTION = 62393,
+ SPELL_TOUCH_OF_DOMINION = 62507,
+ SPELL_TOUCH_OF_DOMINION_TRIGGERED = 62565,
+ SPELL_CHAIN_LIGHTNING = 62131,
+ SPELL_LIGHTNING_ORB_CHARGED = 62186, // wrong duration, triggered spell should handle lightning release
+ SPELL_LIGHTNING_CHARGE = 62279,
+ SPELL_LIGHTNING_RELEASE = 62466,
+ SPELL_LIGHTNING_PILLAR_2 = 62976, // caster high position, target low position
+ SPELL_LIGHTNING_PILLAR_1 = 63238, // caster high position, target low position
+ SPELL_UNBALANCING_STRIKE = 62130,
+ SPELL_BERSERK_PHASE_1 = 62560,
+ SPELL_BERSERK_PHASE_2 = 62555,
+ SPELL_ACTIVATE_LIGHTNING_ORB_PERIODIC = 62184,
+
+ // Credits
+ SPELL_CREDIT_SIFFED = 64980,
+ SPELL_CREDIT_KILL = 64985,
+
+ // Lightning Field
+ SPELL_LIGHTNING_FIELD = 64972,
+ SPELL_LIGHTNING_BEAM_CHANNEL = 45537,
+
+ // Sif
+ SPELL_BLIZZARD = 62577,
+ SPELL_BLINK = 62578,
+ SPELL_FROSTBOLT_VOLLEY = 62580,
+ SPELL_FROSTBOLT = 62583,
+ SPELL_FROSTNOVA = 62597,
+ SPELL_SIF_TRANSFORM = 64778,
+
+ // Runic Colossus
+ SPELL_SMASH = 62339,
+ SPELL_RUNIC_BARRIER = 62338,
+ SPELL_RUNIC_CHARGE = 62613,
+ SPELL_RUNIC_SMASH = 62465,
+ SPELL_RUNIC_SMASH_RIGHT = 62057,
+ SPELL_RUNIC_SMASH_LEFT = 62058,
+
+ // Ancient Rune Giant
+ SPELL_RUNIC_FORTIFICATION = 62942,
+ SPELL_RUNE_DETONATION = 62526,
+ SPELL_STOMP = 62411
+};
+
+enum Phases
+{
+ PHASE_NULL,
+ PHASE_1,
+ PHASE_2
+};
+
+enum Events
+{
+ // Thorim
+ EVENT_SAY_AGGRO_2 = 1,
+ EVENT_SAY_SIF_START,
+ EVENT_START_SIF_CHANNEL,
+ EVENT_STORMHAMMER,
+ EVENT_CHARGE_ORB,
+ EVENT_SUMMON_ADDS,
+ EVENT_BERSERK,
+ EVENT_JUMPDOWN,
+ EVENT_UNBALANCING_STRIKE,
+ EVENT_CHAIN_LIGHTNING,
+ EVENT_START_PERIODIC_CHARGE,
+ EVENT_LIGHTNING_CHARGE,
+ EVENT_ACTIVATE_LIGHTNING_FIELD,
+ EVENT_OUTRO_1,
+ EVENT_OUTRO_2,
+ EVENT_OUTRO_3,
+
+ // Runic Colossus
+ EVENT_RUNIC_BARRIER,
+ EVENT_SMASH,
+ EVENT_RUNIC_CHARGE,
+ EVENT_RUNIC_SMASH,
+
+ // Ancient Rune Giant
+ EVENT_RUNIC_FORTIFICATION,
+ EVENT_STOMP,
+ EVENT_RUNE_DETONATION,
+
+ // Arena NPC
+ EVENT_PRIMARY_ABILITY,
+ EVENT_SECONDARY_ABILITY,
+ EVENT_THIRD_ABILITY,
+ EVENT_ABILITY_CHARGE,
+
+ // Sif
+ EVENT_BLINK,
+ EVENT_FROST_NOVA,
+ EVENT_FROSTBOLT,
+ EVENT_FROSTBOLT_VOLLEY,
+ EVENT_BLIZZARD
+};
enum Yells
{
- SAY_AGGRO = 0,
- SAY_SPECIAL_1 = 1,
- SAY_SPECIAL_2 = 2,
- SAY_SPECIAL_3 = 3,
- SAY_JUMPDOWN = 4,
- SAY_SLAY = 5,
- SAY_BERSERK = 6,
- SAY_WIPE = 7,
- SAY_DEATH = 8,
- SAY_END_NORMAL_1 = 9,
- SAY_END_NORMAL_2 = 10,
- SAY_END_NORMAL_3 = 11,
- SAY_END_HARD_1 = 12,
- SAY_END_HARD_2 = 13,
- SAY_END_HARD_3 = 14
+ // Thorim
+ SAY_AGGRO_1 = 0,
+ SAY_AGGRO_2 = 1,
+ SAY_SPECIAL = 2,
+ SAY_JUMPDOWN = 3,
+ SAY_SLAY = 4,
+ SAY_BERSERK = 5,
+ SAY_WIPE = 6,
+ SAY_DEATH = 7,
+ SAY_END_NORMAL_1 = 8,
+ SAY_END_NORMAL_2 = 9,
+ SAY_END_NORMAL_3 = 10,
+ SAY_END_HARD_1 = 11,
+ SAY_END_HARD_2 = 12,
+ SAY_END_HARD_3 = 13,
+
+ // Runic Colossus
+ EMOTE_RUNIC_BARRIER = 0,
+
+ // Ancient Rune Giant
+ EMOTE_RUNIC_MIGHT = 0,
+
+ // Sif
+ SAY_SIF_START = 0,
+ SAY_SIF_DESPAWN = 1,
+ SAY_SIF_EVENT = 2
+};
+
+enum PreAddSpells
+{
+ SPELL_ACID_BREATH = 62315,
+ SPELL_SWEEP = 62316,
+
+ SPELL_DEVASTATE = 62317,
+ SPELL_HEROIC_SWIPE = 62444,
+ SPELL_SUNDER_ARMOR = 57807,
+
+ SPELL_BARBED_SHOT = 62318,
+ SPELL_SHOOT = 16496,
+
+ SPELL_RENEW = 62333,
+ SPELL_GREATER_HEAL = 62334, /// 61965
+ SPELL_CIRCLE_OF_HEALING = 61964,
+
+ SPELL_HOLY_SMITE = 62335,
+
+ SPELL_LEAP = 61934,
+
+ SPELL_CHARGE = 32323,
+ SPELL_MORTAL_STRIKE = 35054,
+ SPELL_WHIRLWIND = 33500,
+
+ SPELL_LOW_BLOW = 62326,
+ SPELL_PUMMEL = 38313,
+
+ SPELL_RUNIC_LIGHTNING = 62327,
+ SPELL_RUNIC_MENDING = 62328,
+ SPELL_RUNIC_SHIELD = 62321,
+
+ SPELL_RUNIC_STRIKE = 62322,
+ SPELL_AURA_OF_CELERITY = 62320,
+
+ SPELL_IMPALE = 62331,
+ SPELL_WHIRLING_TRIP = 64151,
+
+ SPELL_CLEAVE = 42724,
+ SPELL_HAMSTRING = 48639,
+ SPELL_SHIELD_SMASH = 62332,
+};
+
+enum TrashTypes
+{
+ // Pre Phase Trash
+ BEHEMOTH,
+ MERCENARY_CAPTAIN,
+ MERCENARY_SOLDIER,
+
+ // Arena Phase Trash
+ DARK_RUNE_CHAMPION,
+ DARK_RUNE_WARBRINGER,
+ DARK_RUNE_COMMONER,
+ DARK_RUNE_EVOKER,
+
+ // Hall Way Trash
+ IRON_RING_GUARD,
+ IRON_HONOR_GUARD,
+
+ // Shared
+ DARK_RUNE_ACOLYTE
+};
+
+struct ThorimTrashInfo
+{
+ uint32 Type;
+ uint32 Entry;
+ uint32 PrimaryAbility;
+ uint32 SecondaryAbility;
+ uint32 ThirdAbility;
+};
+
+uint8 const ThorimTrashCount = 13;
+ThorimTrashInfo const StaticThorimTrashInfo[ThorimTrashCount] =
+{
+ // Pre Phase
+ { BEHEMOTH, NPC_JORMUNGAR_BEHEMOTH, SPELL_ACID_BREATH, SPELL_SWEEP, 0 },
+ { MERCENARY_CAPTAIN, NPC_MERCENARY_CAPTAIN_A, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR },
+ { MERCENARY_SOLDIER, NPC_MERCENARY_SOLDIER_A, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 },
+ { DARK_RUNE_ACOLYTE, NPC_DARK_RUNE_ACOLYTE_PRE, SPELL_RENEW, SPELL_GREATER_HEAL, SPELL_CIRCLE_OF_HEALING },
+ { MERCENARY_CAPTAIN, NPC_MERCENARY_CAPTAIN_H, SPELL_DEVASTATE, SPELL_HEROIC_SWIPE, SPELL_SUNDER_ARMOR },
+ { MERCENARY_SOLDIER, NPC_MERCENARY_SOLDIER_H, SPELL_BARBED_SHOT, SPELL_SHOOT, 0 },
+
+ // Arena Phase
+ { DARK_RUNE_CHAMPION, NPC_DARK_RUNE_CHAMPION, SPELL_MORTAL_STRIKE, SPELL_WHIRLWIND, 0 },
+ { DARK_RUNE_WARBRINGER, NPC_DARK_RUNE_WARBRINGER, SPELL_RUNIC_STRIKE, 0, 0 },
+ { DARK_RUNE_EVOKER, NPC_DARK_RUNE_EVOKER, SPELL_RUNIC_LIGHTNING, SPELL_RUNIC_SHIELD, SPELL_RUNIC_MENDING },
+ { DARK_RUNE_COMMONER, NPC_DARK_RUNE_COMMONER, SPELL_LOW_BLOW, SPELL_PUMMEL, 0 },
+
+ // Hall Way
+ { IRON_RING_GUARD, NPC_IRON_RING_GUARD, SPELL_WHIRLING_TRIP, SPELL_IMPALE, 0 },
+ { IRON_HONOR_GUARD, NPC_IRON_HONOR_GUARD, SPELL_CLEAVE, SPELL_SHIELD_SMASH, 0 },
+ { DARK_RUNE_ACOLYTE, NPC_DARK_RUNE_ACOLYTE, SPELL_RENEW, SPELL_GREATER_HEAL, 0 }
+};
+
+enum Actions
+{
+ ACTION_INCREASE_PREADDS_COUNT,
+ ACTION_ACTIVATE_RUNIC_SMASH,
+ ACTION_ACTIVATE_ADDS,
+ ACTION_PILLAR_CHARGED,
+ ACTION_START_HARD_MODE,
+ ACTION_BERSERK
+};
+
+struct SummonLocation
+{
+ Position pos;
+ uint32 entry;
+};
+
+SummonLocation const PreAddLocations[] =
+{
+ { { 2149.68f, -263.477f, 419.679f, 3.120f }, NPC_JORMUNGAR_BEHEMOTH },
+ { { 2131.31f, -271.640f, 419.840f, 2.188f }, NPC_MERCENARY_CAPTAIN_A },
+ { { 2127.24f, -259.182f, 419.974f, 5.917f }, NPC_MERCENARY_SOLDIER_A },
+ { { 2123.32f, -254.770f, 419.840f, 6.170f }, NPC_MERCENARY_SOLDIER_A },
+ { { 2120.10f, -258.990f, 419.840f, 6.250f }, NPC_MERCENARY_SOLDIER_A },
+ { { 2129.09f, -277.142f, 419.756f, 1.222f }, NPC_DARK_RUNE_ACOLYTE_PRE }
+};
+
+SummonLocation const ColossusAddLocations[] =
+{
+ { { 2218.38f, -297.50f, 412.18f, 1.030f }, NPC_IRON_RING_GUARD },
+ { { 2235.07f, -297.98f, 412.18f, 1.613f }, NPC_IRON_RING_GUARD },
+ { { 2235.26f, -338.34f, 412.18f, 1.589f }, NPC_IRON_RING_GUARD },
+ { { 2217.69f, -337.39f, 412.18f, 1.241f }, NPC_IRON_RING_GUARD },
+ { { 2227.58f, -308.30f, 412.18f, 1.591f }, NPC_DARK_RUNE_ACOLYTE },
+ { { 2227.47f, -345.37f, 412.18f, 1.566f }, NPC_DARK_RUNE_ACOLYTE }
+};
+
+SummonLocation const GiantAddLocations[] =
+{
+ { { 2198.05f, -428.77f, 419.95f, 6.056f }, NPC_IRON_HONOR_GUARD },
+ { { 2220.31f, -436.22f, 412.26f, 1.064f }, NPC_IRON_HONOR_GUARD },
+ { { 2158.88f, -441.73f, 438.25f, 0.127f }, NPC_IRON_HONOR_GUARD },
+ { { 2198.29f, -436.92f, 419.95f, 0.261f }, NPC_DARK_RUNE_ACOLYTE },
+ { { 2230.93f, -434.27f, 412.26f, 1.931f }, NPC_DARK_RUNE_ACOLYTE }
+};
+
+Position const SifSpawnPosition = { 2148.301f, -297.8453f, 438.3308f, 2.687807f };
+
+enum Data
+{
+ DATA_CHARGED_PILLAR = 1
+};
+
+enum DisplayIds
+{
+ THORIM_WEAPON_DISPLAY_ID = 45900
+};
+
+uint32 const LightningOrbPathSize = 8;
+G3D::Vector3 const LightningOrbPath[LightningOrbPathSize] =
+{
+ { 2134.889893f, -298.632996f, 438.247467f },
+ { 2134.570068f, -440.317993f, 438.247467f },
+ { 2167.820312f, -440.330261f, 438.247589f },
+ { 2213.394287f, -433.318298f, 412.665863f },
+ { 2227.766113f, -433.275818f, 412.177032f },
+ { 2227.551270f, -263.081085f, 412.176880f },
+ { 2202.208008f, -262.939270f, 412.168976f },
+ { 2182.310059f, -263.233093f, 414.739410f }
+};
+
+// used for trash jump calculation
+Position const ArenaCenter = { 2134.77f, -262.307f };
+
+// used for lightning field calculation
+Position const LightningFieldCenter = { 2135.178f, -321.122f };
+
+CircleBoundary const ArenaFloorCircle(ArenaCenter, 45.4);
+CircleBoundary const InvertedBalconyCircle(LightningFieldCenter, 32.0, true);
+
+CreatureBoundary const ArenaBoundaries =
+{
+ &ArenaFloorCircle,
+ &InvertedBalconyCircle
+};
+
+class HeightPositionCheck
+{
+ public:
+ HeightPositionCheck(bool ret) : _ret(ret) { }
+
+ bool operator()(Position const* pos) const
+ {
+ return pos->GetPositionZ() > THORIM_BALCONY_Z_CHECK == _ret;
+ }
+
+ private:
+ bool _ret;
+
+ static float const THORIM_BALCONY_Z_CHECK;
+};
+float const HeightPositionCheck::THORIM_BALCONY_Z_CHECK = 428.0f;
+
+class RunicSmashExplosionEvent : public BasicEvent
+{
+ public:
+ RunicSmashExplosionEvent(Creature* owner) : _owner(owner) { }
+
+ bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
+ {
+ _owner->CastSpell((Unit*)nullptr, SPELL_RUNIC_SMASH);
+ return true;
+ }
+
+ private:
+ Creature* _owner;
+};
+
+class TrashJumpEvent : public BasicEvent
+{
+ public:
+ TrashJumpEvent(Creature* owner) : _owner(owner), _stage(0) { }
+
+ bool Execute(uint64 eventTime, uint32 /*updateTime*/) override
+ {
+ switch (_stage)
+ {
+ case 0:
+ _owner->CastSpell((Unit*)nullptr, SPELL_LEAP);
+ ++_stage;
+ _owner->m_Events.AddEvent(this, eventTime + 2000);
+ return false;
+ case 1:
+ _owner->SetReactState(REACT_AGGRESSIVE);
+ _owner->AI()->DoZoneInCombat(_owner);
+ _owner->AI()->SetBoundary(&ArenaBoundaries);
+ return true;
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+ private:
+ Creature* _owner;
+ uint8 _stage;
+};
+
+class LightningFieldEvent : public BasicEvent
+{
+ public:
+ LightningFieldEvent(Creature* owner) : _owner(owner) { }
+
+ bool Execute(uint64 eventTime, uint32 /*updateTime*/) override
+ {
+ if (InstanceScript* instance = _owner->GetInstanceScript())
+ {
+ if (instance->GetBossState(BOSS_THORIM) == IN_PROGRESS)
+ {
+ _owner->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_FIELD);
+ _owner->m_Events.AddEvent(this, eventTime + 1000);
+ return false;
+ }
+ }
+
+ _owner->InterruptNonMeleeSpells(false);
+ _owner->AI()->EnterEvadeMode();
+ return true;
+ }
+
+ private:
+ Creature* _owner;
};
class boss_thorim : public CreatureScript
@@ -47,17 +447,76 @@ class boss_thorim : public CreatureScript
{
boss_thorimAI(Creature* creature) : BossAI(creature, BOSS_THORIM)
{
+ _encounterFinished = false;
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ _killedCount = 0;
+ _waveType = 0;
+ _hardMode = true;
+ _orbSummoned = false;
+ _dontStandInTheLightning = true;
}
void Reset() override
{
+ if (_encounterFinished)
+ return;
+
+ SetBoundary(nullptr);
_Reset();
+ Initialize();
+
+ me->SetReactState(REACT_PASSIVE);
+ me->SetDisableGravity(true);
+ me->SetControlled(true, UNIT_STATE_ROOT);
+ me->AddUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+
+ events.SetPhase(PHASE_NULL);
+
+ // Respawn Mini Bosses
+ for (uint8 i = DATA_RUNIC_COLOSSUS; i <= DATA_RUNE_GIANT; ++i)
+ if (Creature* miniBoss = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i)))
+ miniBoss->Respawn(true);
+
+ // Spawn Pre Phase Adds
+ for (SummonLocation const& s : PreAddLocations)
+ me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
+
+ if (GameObject* lever = instance->GetGameObject(DATA_THORIM_LEVER))
+ lever->AddFlag(GO_FLAG_NOT_SELECTABLE);
+
+ // Remove trigger auras
+ if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID))
+ pillar->RemoveAllAuras();
+
+ if (Creature* controller = instance->GetCreature(DATA_THORIM_CONTROLLER))
+ controller->RemoveAllAuras();
+
+ _activePillarGUID.Clear();
}
- void EnterEvadeMode(EvadeReason why) override
+ void EnterEvadeMode(EvadeReason /*why*/) override
{
- Talk(SAY_WIPE);
- _EnterEvadeMode(why);
+ summons.DespawnAll();
+ _DespawnAtEvade();
+ }
+
+ void SetGUID(ObjectGuid guid, int32 type) override
+ {
+ if (type == DATA_CHARGED_PILLAR)
+ {
+ _activePillarGUID = guid;
+
+ if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID))
+ {
+ pillar->CastSpell(pillar, SPELL_LIGHTNING_ORB_CHARGED, true);
+ pillar->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_2);
+ events.ScheduleEvent(EVENT_LIGHTNING_CHARGE, 8000, 0, PHASE_2);
+ }
+ }
}
void KilledUnit(Unit* who) override
@@ -66,27 +525,410 @@ class boss_thorim : public CreatureScript
Talk(SAY_SLAY);
}
- void JustDied(Unit* /*killer*/) override
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
- Talk(SAY_DEATH);
+ if (spellInfo->Id == SPELL_TOUCH_OF_DOMINION_TRIGGERED)
+ {
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ {
+ sif->AI()->Talk(SAY_SIF_DESPAWN);
+ sif->DespawnOrUnsummon(6000);
+ _hardMode = false;
+ }
+ }
+ }
+
+ void SpellHitTarget(Unit* who, SpellInfo const* spellInfo) override
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER && spellInfo->Id == SPELL_LIGHTNING_RELEASE)
+ _dontStandInTheLightning = false;
+ }
+
+ void FinishEncounter()
+ {
+ if (_encounterFinished)
+ return;
+
+ _encounterFinished = true;
+
+ DoCastAOE(SPELL_CREDIT_KILL, true); // before change faction
+
+ me->SetReactState(REACT_PASSIVE);
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAllAttackers();
+ me->AttackStop();
+ me->SetFaction(FACTION_FRIENDLY);
+ me->AddUnitFlag(UNIT_FLAG_RENAME);
+
+ if (Creature* controller = instance->GetCreature(DATA_THORIM_CONTROLLER))
+ controller->RemoveAllAuras();
+ if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID))
+ pillar->RemoveAllAuras();
+
+ if (_hardMode)
+ {
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ {
+ summons.Despawn(sif);
+ sif->DespawnOrUnsummon(10000);
+ }
+ }
+
_JustDied();
+
+ Talk(SAY_DEATH);
+ events.ScheduleEvent(EVENT_OUTRO_1, 4000);
+ events.ScheduleEvent(EVENT_OUTRO_2, _hardMode ? 8000 : 11000);
+ events.ScheduleEvent(EVENT_OUTRO_3, _hardMode ? 19000 : 21000);
+
+ me->m_Events.AddEvent(new KeeperDespawnEvent(me), me->m_Events.CalculateTime(35000));
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != EFFECT_MOTION_TYPE || id != EVENT_JUMP)
+ return;
+
+ me->getThreatManager().resetAllAggro();
+ SetBoundary(&ArenaBoundaries);
}
void EnterCombat(Unit* /*who*/) override
{
- Talk(SAY_AGGRO);
_EnterCombat();
+ Talk(SAY_AGGRO_1);
+
+ events.SetPhase(PHASE_1);
+
+ events.ScheduleEvent(EVENT_SAY_AGGRO_2, 9000, 0, PHASE_1);
+ events.ScheduleEvent(EVENT_SAY_SIF_START, 16500, 0, PHASE_1);
+ events.ScheduleEvent(EVENT_START_SIF_CHANNEL, 22500, 0, PHASE_1);
+
+ events.ScheduleEvent(EVENT_STORMHAMMER, 40000, 0, PHASE_1);
+ events.ScheduleEvent(EVENT_CHARGE_ORB, 30000, 0, PHASE_1);
+ events.ScheduleEvent(EVENT_SUMMON_ADDS, 15000, 0, PHASE_1);
+ events.ScheduleEvent(EVENT_BERSERK, 369000);
+
+ DoCast(me, SPELL_SHEATH_OF_LIGHTNING);
+
+ if (Creature* runicColossus = instance->GetCreature(DATA_RUNIC_COLOSSUS))
+ {
+ runicColossus->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ runicColossus->AI()->DoAction(ACTION_ACTIVATE_ADDS);
+ }
+
+ if (GameObject* lever = instance->GetGameObject(DATA_THORIM_LEVER))
+ lever->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+
+ // Summon Sif
+ me->SummonCreature(NPC_SIF, SifSpawnPosition);
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ switch (summon->GetEntry())
+ {
+ case NPC_LIGHTNING_ORB:
+ {
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CastSpell(summon, SPELL_LIGHTNING_DESTRUCTION, true);
+
+ summon->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, LightningOrbPath[LightningOrbPathSize - 1].x, LightningOrbPath[LightningOrbPathSize - 1].y, LightningOrbPath[LightningOrbPathSize - 1].z, false);
+
+ Movement::PointsArray path(LightningOrbPath, LightningOrbPath + LightningOrbPathSize);
+
+ Movement::MoveSplineInit init(summon);
+ init.MovebyPath(path);
+ init.Launch();
+ break;
+ }
+ case NPC_DARK_RUNE_CHAMPION:
+ case NPC_DARK_RUNE_WARBRINGER:
+ case NPC_DARK_RUNE_EVOKER:
+ case NPC_DARK_RUNE_COMMONER:
+ summon->SetReactState(REACT_PASSIVE);
+ summon->m_Events.AddEvent(new TrashJumpEvent(summon), summon->m_Events.CalculateTime(3000));
+ break;
+ case NPC_SIF:
+ summon->SetReactState(REACT_PASSIVE);
+ break;
+ default:
+ break;
+ }
+
+ BossAI::JustSummoned(summon);
}
- void UpdateAI(uint32 /*diff*/) override
+ void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
- //SPELLS @todo
- //
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SAY_AGGRO_2:
+ Talk(SAY_AGGRO_2);
+ break;
+ case EVENT_SAY_SIF_START:
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ sif->AI()->Talk(SAY_SIF_START);
+ break;
+ case EVENT_START_SIF_CHANNEL:
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ sif->CastSpell(me, SPELL_TOUCH_OF_DOMINION);
+ break;
+ case EVENT_STORMHAMMER:
+ DoCast(SPELL_STORMHAMMER);
+ events.Repeat(15000, 20000);
+ break;
+ case EVENT_CHARGE_ORB:
+ DoCastAOE(SPELL_CHARGE_ORB);
+ events.Repeat(15000, 20000);
+ break;
+ case EVENT_SUMMON_ADDS:
+ SummonWave();
+ events.Repeat(_orbSummoned ? 3000 : 10000);
+ break;
+ case EVENT_JUMPDOWN:
+ if (_hardMode)
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ sif->AI()->DoAction(ACTION_START_HARD_MODE);
+ me->RemoveAurasDueToSpell(SPELL_SHEATH_OF_LIGHTNING);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetDisableGravity(false);
+ me->SetControlled(false, UNIT_STATE_ROOT);
+ me->GetMotionMaster()->MoveJump(2134.8f, -263.056f, 419.983f, me->GetOrientation(), 30.0f, 20.0f);
+ events.ScheduleEvent(EVENT_START_PERIODIC_CHARGE, 2000, 0, PHASE_2);
+ events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 15000, 0, PHASE_2);
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 20000, 0, PHASE_2);
+ break;
+ case EVENT_UNBALANCING_STRIKE:
+ DoCastVictim(SPELL_UNBALANCING_STRIKE);
+ events.Repeat(15000, 20000);
+ break;
+ case EVENT_CHAIN_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_CHAIN_LIGHTNING);
+ events.Repeat(7000, 15000);
+ break;
+ case EVENT_START_PERIODIC_CHARGE:
+ if (Creature* controller = instance->GetCreature(DATA_THORIM_CONTROLLER))
+ controller->CastSpell(controller, SPELL_ACTIVATE_LIGHTNING_ORB_PERIODIC, true);
+ break;
+ case EVENT_LIGHTNING_CHARGE:
+ if (Creature* pillar = ObjectAccessor::GetCreature(*me, _activePillarGUID))
+ DoCast(pillar, SPELL_LIGHTNING_RELEASE);
+ break;
+ case EVENT_BERSERK:
+ if (events.IsInPhase(PHASE_1))
+ {
+ Talk(SAY_WIPE);
+ DoCastAOE(SPELL_BERSERK_PHASE_1, true);
+ DoCast(me, SPELL_SUMMON_LIGHTNING_ORB, true);
+ }
+ else
+ {
+ Talk(SAY_BERSERK);
+ DoCast(me, SPELL_BERSERK_PHASE_2, true);
+ }
+ break;
+ case EVENT_ACTIVATE_LIGHTNING_FIELD:
+ {
+ std::list<Creature*> triggers;
+ me->GetCreatureListWithEntryInGrid(triggers, NPC_THORIM_EVENT_BUNNY, 100.0f);
+ triggers.remove_if([](Creature* bunny)
+ {
+ if (HeightPositionCheck(false)(bunny))
+ return true;
+ return LightningFieldCenter.GetExactDist2dSq(bunny) > 1296.0f;
+ });
+
+ uint64 timer = 1000;
+ for (Creature* bunny : triggers)
+ bunny->m_Events.AddEvent(new LightningFieldEvent(bunny), bunny->m_Events.CalculateTime(timer += 100));
+
+ triggers.remove_if([](Creature* bunny)
+ {
+ return LightningFieldCenter.GetExactDist2dSq(bunny) < 576.0f;
+ });
+
+ triggers.sort([](Creature* a, Creature* b)
+ {
+ return a->GetPositionX() < b->GetPositionX();
+ });
+
+ for (auto itr = triggers.cbegin(); itr != triggers.cend();)
+ {
+ auto prev = itr++;
+ if (itr != triggers.end())
+ (*prev)->CastSpell(*itr, SPELL_LIGHTNING_BEAM_CHANNEL);
+ }
+ break;
+ }
+ case EVENT_OUTRO_1:
+ Talk(_hardMode ? SAY_END_HARD_1 : SAY_END_NORMAL_1);
+ if (_hardMode)
+ DoCast(me, SPELL_STORMHAMMER_SIF);
+ break;
+ case EVENT_OUTRO_2:
+ Talk(_hardMode ? SAY_END_HARD_2 : SAY_END_NORMAL_2);
+ if (_hardMode)
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ sif->SetStandState(UNIT_STAND_STATE_DEAD);
+ break;
+ case EVENT_OUTRO_3:
+ Talk(_hardMode ? SAY_END_HARD_3 : SAY_END_NORMAL_3);
+ break;
+ default:
+ break;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
DoMeleeAttackIfReady();
}
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_BERSERK:
+ if (events.IsInPhase(PHASE_2))
+ return;
+
+ if (!_orbSummoned)
+ {
+ _orbSummoned = true;
+ events.RescheduleEvent(EVENT_BERSERK, 1000);
+ }
+ return;
+ case ACTION_INCREASE_PREADDS_COUNT:
+ if (++_killedCount >= 6)
+ {
+ // Event starts
+ me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ DoZoneInCombat(me);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void GetTrashSpawnTriggers(std::list<Creature*>& triggerList, uint32 count = 1)
+ {
+ me->GetCreatureListWithEntryInGrid(triggerList, NPC_THORIM_EVENT_BUNNY, 100.0f);
+ triggerList.remove_if([](Creature* bunny)
+ {
+ if (HeightPositionCheck(false)(bunny))
+ return true;
+ return ArenaCenter.GetExactDist2dSq(bunny) < 3025.0f;
+ });
+
+ if (triggerList.empty())
+ return;
+
+ if (count == 1)
+ {
+ Creature* bunny = Trinity::Containers::SelectRandomContainerElement(triggerList);
+ triggerList.clear();
+ triggerList.push_back(bunny);
+ }
+ else
+ Trinity::Containers::RandomResize(triggerList, count);
+ }
+
+ void SummonWave()
+ {
+ switch (_waveType)
+ {
+ case 0:
+ {
+ // Dark Rune Commoner
+ std::list<Creature*> triggers;
+ GetTrashSpawnTriggers(triggers, urand(5, 6));
+
+ for (Creature* bunny : triggers)
+ me->SummonCreature(StaticThorimTrashInfo[6 + 3].Entry, *bunny, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
+
+ ++_waveType;
+ break;
+ }
+ case 1:
+ if (urand(0, 1))
+ {
+ // Dark Rune Champion or Dark Rune Evoker
+ std::list<Creature*> triggers;
+ GetTrashSpawnTriggers(triggers, urand(2, 4));
+
+ for (Creature* bunny : triggers)
+ me->SummonCreature(StaticThorimTrashInfo[6 + RAND(0, 2)].Entry, *bunny, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
+ }
+ else
+ {
+ // Dark Rune Warbringer
+ std::list<Creature*> triggers;
+ GetTrashSpawnTriggers(triggers);
+
+ for (Creature* bunny : triggers)
+ me->SummonCreature(StaticThorimTrashInfo[6 + 1].Entry, *bunny, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
+ }
+ --_waveType;
+ break;
+ }
+ }
+
+ bool CanStartPhase2(Unit* actor) const
+ {
+ if (actor->GetTypeId() != TYPEID_PLAYER || !me->IsWithinDistInMap(actor, 10.0f))
+ return false;
+
+ Creature* runicColossus = instance->GetCreature(DATA_RUNIC_COLOSSUS);
+ Creature* runeGiant = instance->GetCreature(DATA_RUNE_GIANT);
+ return runicColossus && !runicColossus->IsAlive() && runeGiant && !runeGiant->IsAlive();
+ }
+
+ void DamageTaken(Unit* attacker, uint32& damage) override
+ {
+ if (events.IsInPhase(PHASE_1) && CanStartPhase2(attacker))
+ {
+ Talk(SAY_JUMPDOWN);
+ events.SetPhase(PHASE_2);
+ events.ScheduleEvent(EVENT_JUMPDOWN, 8000);
+ events.ScheduleEvent(EVENT_ACTIVATE_LIGHTNING_FIELD, 15000);
+ events.RescheduleEvent(EVENT_BERSERK, 300000, 0, PHASE_2);
+
+ if (Creature* sif = instance->GetCreature(DATA_SIF))
+ sif->InterruptNonMeleeSpells(false);
+
+ // Hard Mode
+ if (_hardMode)
+ DoCastAOE(SPELL_CREDIT_SIFFED, true);
+ }
+ else if (me->HealthBelowPctDamaged(1, damage))
+ {
+ damage = 0;
+ FinishEncounter();
+ }
+ }
+
+ private:
+ ObjectGuid _activePillarGUID;
+ uint8 _killedCount;
+ uint8 _waveType;
+ bool _hardMode;
+ bool _encounterFinished;
+ bool _orbSummoned;
+ bool _dontStandInTheLightning;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -95,7 +937,1234 @@ class boss_thorim : public CreatureScript
}
};
+struct npc_thorim_trashAI : public ScriptedAI
+{
+ npc_thorim_trashAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ for (uint8 i = 0; i < ThorimTrashCount; ++i)
+ if (me->GetEntry() == StaticThorimTrashInfo[i].Entry)
+ _info = &StaticThorimTrashInfo[i];
+
+ ASSERT(_info);
+ }
+
+ struct AIHelper
+ {
+ /// returns heal amount of the given spell including hots
+ static uint32 GetTotalHeal(SpellInfo const* spellInfo, Unit const* caster)
+ {
+ uint32 heal = 0;
+ for (SpellEffectInfo const* effect : spellInfo->GetEffects())
+ {
+ if (effect->IsEffect(SPELL_EFFECT_HEAL))
+ heal += effect->CalcValue(caster);
+
+ if (effect->IsEffect(SPELL_EFFECT_APPLY_AURA) && effect->IsAura(SPELL_AURA_PERIODIC_HEAL))
+ heal += spellInfo->GetMaxTicks() * effect->CalcValue(caster);
+ }
+ return heal;
+ }
+
+ /// returns remaining heal amount on given target
+ static uint32 GetRemainingHealOn(Unit* target)
+ {
+ uint32 heal = 0;
+ Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL);
+ for (AuraEffect const* aurEff : auras)
+ heal += aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber());
+
+ return heal;
+ }
+
+ class MostHPMissingInRange
+ {
+ public:
+ MostHPMissingInRange(Unit const* referer, float range, uint32 hp, uint32 exclAura = 0, bool exclSelf = false)
+ : _referer(referer), _range(range), _hp(hp), _exclAura(exclAura), _exclSelf(exclSelf) { }
+
+ bool operator()(Unit* u)
+ {
+ if (_exclSelf && u == _referer)
+ return false;
+
+ if (_exclAura && u->HasAura(_exclAura))
+ return false;
+
+ if ((u->GetHealth() + GetRemainingHealOn(u) + _hp) > u->GetMaxHealth())
+ return false;
+
+ uint32 missingHP = u->GetMaxHealth() - u->GetHealth();
+ if (u->IsAlive() && _referer->IsFriendlyTo(u) && _referer->IsWithinDistInMap(u, _range) && missingHP > _hp)
+ {
+ _hp = missingHP;
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ Unit const* _referer;
+ float _range;
+ uint32 _hp;
+ uint32 _exclAura;
+ bool _exclSelf;
+ };
+
+ static Unit* GetUnitWithMostMissingHp(SpellInfo const* spellInfo, Unit* caster)
+ {
+ // use positive range, it's a healing spell
+ float const range = spellInfo->GetMaxRange(true);
+ uint32 const heal = GetTotalHeal(spellInfo, caster);
+
+ Unit* target = nullptr;
+ Trinity::MostHPMissingInRange checker(caster, range, heal);
+ Trinity::UnitLastSearcher<Trinity::MostHPMissingInRange> searcher(caster, target, checker);
+ Cell::VisitGridObjects(caster, searcher, 60.0f);
+
+ return target;
+ }
+
+ static Unit* GetHealTarget(SpellInfo const* spellInfo, Unit* caster)
+ {
+ Unit* healTarget = nullptr;
+ if (!spellInfo->HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && !roll_chance_f(caster->GetHealthPct()) && ((caster->GetHealth() + GetRemainingHealOn(caster) + GetTotalHeal(spellInfo, caster)) <= caster->GetMaxHealth()))
+ healTarget = caster;
+ else
+ healTarget = GetUnitWithMostMissingHp(spellInfo, caster);
+
+ return healTarget;
+ }
+ };
+
+ bool UseAbility(uint32 spellId)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetDifficulty());
+ if (!spellInfo)
+ return false;
+
+ Unit* target = nullptr;
+ if (AIHelper::GetTotalHeal(spellInfo, me))
+ target = AIHelper::GetHealTarget(spellInfo, me);
+ else
+ target = me->GetVictim();
+
+ if (!target)
+ return false;
+
+ if (_info->Type == MERCENARY_SOLDIER)
+ {
+ bool allowMove = true;
+ if (me->IsInRange(target, spellInfo->GetMinRange(), spellInfo->GetMaxRange()))
+ allowMove = false;
+
+ if (IsCombatMovementAllowed() != allowMove)
+ {
+ SetCombatMovement(allowMove);
+
+ // need relaunch movement
+ ScriptedAI::AttackStart(target);
+
+ // give some time to allow reposition, try again in a second
+ if (allowMove)
+ return false;
+ }
+ }
+
+ DoCast(target, spellId);
+ return true;
+ }
+
+ void UpdateAI(uint32 diff) final override
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ ExecuteEvent(eventId);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
+ if (_info->Type == DARK_RUNE_ACOLYTE)
+ DoSpellAttackIfReady(SPELL_HOLY_SMITE);
+ else
+ DoMeleeAttackIfReady();
+ }
+
+ virtual void ExecuteEvent(uint32 eventId) = 0;
+
+protected:
+ InstanceScript* _instance;
+ EventMap _events;
+
+ ThorimTrashInfo const* _info = nullptr;
+};
+
+class npc_thorim_pre_phase : public CreatureScript
+{
+ public:
+ npc_thorim_pre_phase() : CreatureScript("npc_thorim_pre_phase") { }
+
+ struct npc_thorim_pre_phaseAI : public npc_thorim_trashAI
+ {
+ npc_thorim_pre_phaseAI(Creature* creature) : npc_thorim_trashAI(creature)
+ {
+ me->setActive(true); // prevent grid unload
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ if (_info->PrimaryAbility)
+ _events.ScheduleEvent(EVENT_PRIMARY_ABILITY, urand(3000, 6000));
+ if (_info->SecondaryAbility)
+ _events.ScheduleEvent(EVENT_SECONDARY_ABILITY, _info->SecondaryAbility == SPELL_SHOOT ? 2000 : urand(12000, 15000));
+ if (_info->ThirdAbility)
+ _events.ScheduleEvent(EVENT_THIRD_ABILITY, urand(6000, 8000));
+ if (_info->Type == MERCENARY_SOLDIER)
+ SetCombatMovement(false);
+ }
+
+ void JustDied(Unit* /*victim*/) override
+ {
+ if (Creature* thorim = _instance->GetCreature(BOSS_THORIM))
+ thorim->AI()->DoAction(ACTION_INCREASE_PREADDS_COUNT);
+ }
+
+ bool ShouldSparWith(Unit const* target) const override
+ {
+ return !target->GetAffectingPlayer();
+ }
+
+ void DamageTaken(Unit* attacker, uint32& damage) override
+ {
+ // nullify spell damage
+ if (!attacker->GetAffectingPlayer())
+ damage = 0;
+ }
+
+ void ExecuteEvent(uint32 eventId) override
+ {
+ switch (eventId)
+ {
+ case EVENT_PRIMARY_ABILITY:
+ if (UseAbility(_info->PrimaryAbility))
+ _events.ScheduleEvent(eventId, urand(15000, 20000));
+ else
+ _events.ScheduleEvent(eventId, 1000);
+ break;
+ case EVENT_SECONDARY_ABILITY:
+ if (UseAbility(_info->SecondaryAbility))
+ _events.ScheduleEvent(eventId, _info->SecondaryAbility == SPELL_SHOOT ? 2000 : urand(4000, 8000));
+ else
+ _events.ScheduleEvent(eventId, 1000);
+ break;
+ case EVENT_THIRD_ABILITY:
+ if (UseAbility(_info->ThirdAbility))
+ _events.ScheduleEvent(eventId, urand(6000, 8000));
+ else
+ _events.ScheduleEvent(eventId, 1000);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_thorim_pre_phaseAI>(creature);
+ }
+};
+
+class npc_thorim_arena_phase : public CreatureScript
+{
+ public:
+ npc_thorim_arena_phase() : CreatureScript("npc_thorim_arena_phase") { }
+
+ struct npc_thorim_arena_phaseAI : public npc_thorim_trashAI
+ {
+ npc_thorim_arena_phaseAI(Creature* creature) : npc_thorim_trashAI(creature)
+ {
+ switch (_info->Type)
+ {
+ case DARK_RUNE_CHAMPION:
+ case DARK_RUNE_WARBRINGER:
+ case DARK_RUNE_COMMONER:
+ case DARK_RUNE_EVOKER:
+ _isInArena = true;
+ break;
+ case DARK_RUNE_ACOLYTE:
+ {
+ _isInArena = (_info->Entry == NPC_DARK_RUNE_ACOLYTE_PRE);
+ SetBoundary(&ArenaBoundaries, !_isInArena);
+ break;
+ }
+ default:
+ _isInArena = false;
+ break;
+ }
+ }
+
+ bool CanAIAttack(Unit const* who) const override
+ {
+ // don't try to attack players in balcony
+ if (_isInArena && HeightPositionCheck(true)(who))
+ return false;
+
+ return CheckBoundary(who);
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ if (_info->PrimaryAbility)
+ _events.ScheduleEvent(EVENT_PRIMARY_ABILITY, urand(3000, 6000));
+ if (_info->SecondaryAbility)
+ _events.ScheduleEvent(EVENT_SECONDARY_ABILITY, urand(7000, 9000));
+ if (_info->ThirdAbility)
+ _events.ScheduleEvent(EVENT_THIRD_ABILITY, urand(6000, 8000));
+ if (_info->Type == DARK_RUNE_CHAMPION)
+ _events.ScheduleEvent(EVENT_ABILITY_CHARGE, 8000);
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ if (_info->Type == DARK_RUNE_WARBRINGER)
+ DoCast(me, SPELL_AURA_OF_CELERITY);
+
+ if (!_isInArena)
+ if (Creature* colossus = _instance->GetCreature(DATA_RUNIC_COLOSSUS))
+ colossus->AI()->DoAction(ACTION_ACTIVATE_RUNIC_SMASH);
+ }
+
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (why != EVADE_REASON_NO_HOSTILES && why != EVADE_REASON_BOUNDARY)
+ return;
+
+ // this should only happen if theres no alive player in the arena -> summon orb
+ if (Creature* thorim = _instance->GetCreature(BOSS_THORIM))
+ thorim->AI()->DoAction(ACTION_BERSERK);
+ ScriptedAI::EnterEvadeMode(why);
+ }
+
+ void ExecuteEvent(uint32 eventId) override
+ {
+ switch (eventId)
+ {
+ case EVENT_PRIMARY_ABILITY:
+ if (UseAbility(_info->PrimaryAbility))
+ _events.Repeat(3000, 6000);
+ else
+ _events.Repeat(1000);
+ break;
+ case EVENT_SECONDARY_ABILITY:
+ if (UseAbility(_info->SecondaryAbility))
+ _events.Repeat(12000, 16000);
+ else
+ _events.Repeat(1000);
+ break;
+ case EVENT_THIRD_ABILITY:
+ if (UseAbility(_info->ThirdAbility))
+ _events.Repeat(6000, 8000);
+ else
+ _events.Repeat(1000);
+ break;
+ case EVENT_ABILITY_CHARGE:
+ {
+ Unit* referer = me;
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [referer](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(referer, 8.0f, 25.0f); }))
+ DoCast(target, SPELL_CHARGE);
+ _events.ScheduleEvent(eventId, 12000);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ private:
+ bool _isInArena;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_thorim_arena_phaseAI>(creature);
+ }
+};
+
+struct npc_thorim_minibossAI : public ScriptedAI
+{
+ npc_thorim_minibossAI(Creature* creature) : ScriptedAI(creature), _summons(me)
+ {
+ _instance = creature->GetInstanceScript();
+
+ SetBoundary(&ArenaBoundaries, true);
+ }
+
+ bool CanAIAttack(Unit const* who) const final override
+ {
+ return CheckBoundary(who);
+ }
+
+ void JustSummoned(Creature* summon) final override
+ {
+ _summons.Summon(summon);
+ }
+
+ void SummonedCreatureDespawn(Creature* summon) final override
+ {
+ _summons.Despawn(summon);
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_ACTIVATE_ADDS)
+ {
+ for (ObjectGuid const& guid : _summons)
+ if (Creature* summon = ObjectAccessor::GetCreature(*me, guid))
+ summon->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ }
+ }
+
+protected:
+ InstanceScript* _instance;
+ EventMap _events;
+ SummonList _summons;
+};
+
+class npc_runic_colossus : public CreatureScript
+{
+ public:
+ npc_runic_colossus() : CreatureScript("npc_runic_colossus") { }
+
+ struct npc_runic_colossusAI : public npc_thorim_minibossAI
+ {
+ npc_runic_colossusAI(Creature* creature) : npc_thorim_minibossAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ _runicActive = false;
+ }
+
+ void Reset() override
+ {
+ Initialize();
+ _events.Reset();
+
+ // close the Runic Door
+ _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), false);
+
+ // Spawn trashes
+ _summons.DespawnAll();
+ for (SummonLocation const& s : ColossusAddLocations)
+ me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) override
+ {
+ // don't enter combat
+ }
+
+ void DoAction(int32 action) override
+ {
+ npc_thorim_minibossAI::DoAction(action);
+
+ if (_runicActive)
+ return;
+
+ if (action == ACTION_ACTIVATE_RUNIC_SMASH)
+ {
+ _runicActive = true;
+ _events.ScheduleEvent(EVENT_RUNIC_SMASH, 7000);
+ }
+ }
+
+ void JustDied(Unit* /*victim*/) override
+ {
+ // open the Runic Door
+ _instance->HandleGameObject(_instance->GetGuidData(DATA_RUNIC_DOOR), true);
+
+ if (Creature* thorim = _instance->GetCreature(BOSS_THORIM))
+ thorim->AI()->Talk(SAY_SPECIAL);
+
+ if (Creature* giant = _instance->GetCreature(DATA_RUNE_GIANT))
+ {
+ giant->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ giant->AI()->DoAction(ACTION_ACTIVATE_ADDS);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ DoZoneInCombat();
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_RUNIC_BARRIER, urand(12000, 15000));
+ _events.ScheduleEvent(EVENT_SMASH, urand(15000, 18000));
+ _events.ScheduleEvent(EVENT_RUNIC_CHARGE, urand(20000, 24000));
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RUNIC_BARRIER:
+ Talk(EMOTE_RUNIC_BARRIER);
+ DoCastAOE(SPELL_RUNIC_BARRIER);
+ _events.Repeat(35000, 45000);
+ break;
+ case EVENT_SMASH:
+ DoCastAOE(SPELL_SMASH);
+ _events.Repeat(15000, 18000);
+ break;
+ case EVENT_RUNIC_CHARGE:
+ {
+ Unit* referer = me;
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [referer](Unit* unit){ return unit->GetTypeId() == TYPEID_PLAYER && unit->IsInRange(referer, 8.0f, 40.0f); }))
+ DoCast(target, SPELL_RUNIC_CHARGE);
+ _events.Repeat(20000);
+ break;
+ }
+ case EVENT_RUNIC_SMASH:
+ DoCast(me, RAND(SPELL_RUNIC_SMASH_LEFT, SPELL_RUNIC_SMASH_RIGHT));
+ _events.Repeat(6000);
+ break;
+ default:
+ break;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ bool _runicActive;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_runic_colossusAI>(creature);
+ }
+};
+
+class npc_ancient_rune_giant : public CreatureScript
+{
+ public:
+ npc_ancient_rune_giant() : CreatureScript("npc_ancient_rune_giant") { }
+
+ struct npc_ancient_rune_giantAI : public npc_thorim_minibossAI
+ {
+ npc_ancient_rune_giantAI(Creature* creature) : npc_thorim_minibossAI(creature) { }
+
+ void Reset() override
+ {
+ _events.Reset();
+
+ // close the Stone Door
+ _instance->HandleGameObject(_instance->GetGuidData(DATA_STONE_DOOR), false);
+
+ // Spawn trashes
+ _summons.DespawnAll();
+ for (SummonLocation const& s : GiantAddLocations)
+ me->SummonCreature(s.entry, s.pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
+ }
+
+ void EnterCombat(Unit* /*who*/) override
+ {
+ DoZoneInCombat();
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_RUNIC_FORTIFICATION, 1);
+ _events.ScheduleEvent(EVENT_STOMP, urand(10000, 12000));
+ _events.ScheduleEvent(EVENT_RUNE_DETONATION, 25000);
+ }
+
+ void JustDied(Unit* /*victim*/) override
+ {
+ // opem the Stone Door
+ _instance->HandleGameObject(_instance->GetGuidData(DATA_STONE_DOOR), true);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RUNIC_FORTIFICATION:
+ Talk(EMOTE_RUNIC_MIGHT);
+ DoCastAOE(SPELL_RUNIC_FORTIFICATION);
+ break;
+ case EVENT_STOMP:
+ DoCastAOE(SPELL_STOMP);
+ _events.Repeat(10000, 12000);
+ break;
+ case EVENT_RUNE_DETONATION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
+ DoCast(target, SPELL_RUNE_DETONATION);
+ _events.Repeat(10000, 12000);
+ break;
+ default:
+ break;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_ancient_rune_giantAI>(creature);
+ }
+};
+
+class npc_sif : public CreatureScript
+{
+ public:
+ npc_sif() : CreatureScript("npc_sif") { }
+
+ struct npc_sifAI : public ScriptedAI
+ {
+ npc_sifAI(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ _instance = creature->GetInstanceScript();
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_STORMHAMMER_SIF)
+ {
+ me->InterruptSpell(CURRENT_GENERIC_SPELL);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ }
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_START_HARD_MODE)
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat(me, 250.0f);
+ Talk(SAY_SIF_EVENT);
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FROSTBOLT, 2000);
+ _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 15000);
+ _events.ScheduleEvent(EVENT_BLINK, urand(20000, 25000));
+ _events.ScheduleEvent(EVENT_BLIZZARD, 30000);
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BLINK:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_BLINK);
+ _events.ScheduleEvent(EVENT_FROST_NOVA, 0);
+ _events.Repeat(20000, 25000);
+ return;
+ case EVENT_FROST_NOVA:
+ DoCastAOE(SPELL_FROSTNOVA);
+ return;
+ case EVENT_FROSTBOLT:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_FROSTBOLT);
+ _events.Repeat(2000);
+ return;
+ case EVENT_FROSTBOLT_VOLLEY:
+ DoCastAOE(SPELL_FROSTBOLT_VOLLEY);
+ _events.Repeat(15000, 20000);
+ return;
+ case EVENT_BLIZZARD:
+ DoCastAOE(SPELL_BLIZZARD);
+ _events.Repeat(35000, 45000);
+ return;
+ default:
+ break;
+ }
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ }
+
+ // no melee attack
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_sifAI>(creature);
+ }
+};
+
+// 62576 - Blizzard
+// 62602 - Blizzard
+class spell_thorim_blizzard_effect : public SpellScriptLoader
+{
+ public:
+ spell_thorim_blizzard_effect() : SpellScriptLoader("spell_thorim_blizzard_effect") { }
+
+ class spell_thorim_blizzard_effect_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_thorim_blizzard_effect_AuraScript);
+
+ bool CheckAreaTarget(Unit* target)
+ {
+ /// @todo: fix this for all dynobj auras
+ if (target != GetOwner())
+ {
+ // check if not stacking aura already on target
+ // this one prevents overriding auras periodically by 2 near area aura owners
+ Unit::AuraApplicationMap const& auraMap = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator iter = auraMap.begin(); iter != auraMap.end(); ++iter)
+ {
+ Aura const* aura = iter->second->GetBase();
+ if (GetId() == aura->GetId() && GetOwner() != aura->GetOwner() /*!GetAura()->CanStackWith(aura)*/)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ void Register() override
+ {
+ DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_thorim_blizzard_effect_AuraScript::CheckAreaTarget);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_thorim_blizzard_effect_AuraScript();
+ }
+};
+
+// 62580, 62604 - Frostbolt Volley
+class spell_thorim_frostbolt_volley : public SpellScriptLoader
+{
+ public:
+ spell_thorim_frostbolt_volley() : SpellScriptLoader("spell_thorim_frostbolt_volley") { }
+
+ class spell_thorim_frostbolt_volley_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_frostbolt_volley_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ unitList.remove_if([](WorldObject* target)
+ {
+ return target->GetTypeId() != TYPEID_PLAYER && (target->GetTypeId() != TYPEID_UNIT || !target->ToUnit()->IsPet());
+ });
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_frostbolt_volley_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_frostbolt_volley_SpellScript();
+ }
+};
+
+// 62016 - Charge Orb
+class spell_thorim_charge_orb : public SpellScriptLoader
+{
+ public:
+ spell_thorim_charge_orb() : SpellScriptLoader("spell_thorim_charge_orb") { }
+
+ class spell_thorim_charge_orb_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_charge_orb_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_LIGHTNING_PILLAR_1 });
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(HeightPositionCheck(false));
+
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleScript()
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell((Unit*)nullptr, SPELL_LIGHTNING_PILLAR_1, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_charge_orb_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ AfterHit += SpellHitFn(spell_thorim_charge_orb_SpellScript::HandleScript);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_charge_orb_SpellScript();
+ }
+};
+
+// 62466 - Lightning Charge
+class spell_thorim_lightning_charge : public SpellScriptLoader
+{
+ public:
+ spell_thorim_lightning_charge() : SpellScriptLoader("spell_thorim_lightning_charge") { }
+
+ class spell_thorim_lightning_charge_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_lightning_charge_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_LIGHTNING_CHARGE });
+ }
+
+ void HandleFocus()
+ {
+ /// @workaround: focus target is not working because spell is triggered and instant
+ if (Creature* creature = GetCaster()->ToCreature())
+ creature->FocusTarget(GetSpell(), GetExplTargetWorldObject());
+ }
+
+ void HandleCharge()
+ {
+ GetCaster()->CastSpell(GetCaster(), SPELL_LIGHTNING_CHARGE);
+ }
+
+ void Register() override
+ {
+ BeforeCast += SpellCastFn(spell_thorim_lightning_charge_SpellScript::HandleFocus);
+ AfterCast += SpellCastFn(spell_thorim_lightning_charge_SpellScript::HandleCharge);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_lightning_charge_SpellScript();
+ }
+};
+
+// 61934 - Leap
+class spell_thorim_arena_leap : public SpellScriptLoader
+{
+ public:
+ spell_thorim_arena_leap() : SpellScriptLoader("spell_thorim_arena_leap") { }
+
+ class spell_thorim_arena_leap_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_arena_leap_SpellScript);
+
+ bool Load() override
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Position const* pos = GetHitDest())
+ GetCaster()->ToCreature()->SetHomePosition(*pos);
+ }
+
+ void Register() override
+ {
+ OnEffectLaunch += SpellEffectFn(spell_thorim_arena_leap_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_JUMP_DEST);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_arena_leap_SpellScript();
+ }
+};
+
+struct OutOfArenaCheck
+{
+ bool operator()(Position const* who) const
+ {
+ return !CreatureAI::IsInBounds(ArenaBoundaries, who);
+ }
+};
+
+// 62042 - Stormhammer
+class spell_thorim_stormhammer : public SpellScriptLoader
+{
+ public:
+ spell_thorim_stormhammer() : SpellScriptLoader("spell_thorim_stormhammer") { }
+
+ class spell_thorim_stormhammer_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_stormhammer_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo(
+ {
+ SPELL_STORMHAMMER_BOOMERANG,
+ SPELL_DEAFENING_THUNDER
+ });
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if([](WorldObject* target) -> bool { return HeightPositionCheck(true)(target) || OutOfArenaCheck()(target); });
+
+ if (targets.empty())
+ {
+ FinishCast(SPELL_FAILED_NO_VALID_TARGETS);
+ return;
+ }
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->CastSpell(target, SPELL_DEAFENING_THUNDER, true);
+ target->CastSpell(GetCaster(), SPELL_STORMHAMMER_BOOMERANG, true);
+ }
+ }
+
+ void LoseHammer()
+ {
+ GetCaster()->SetVirtualItem(0, 0);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thorim_stormhammer_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
+ AfterCast += SpellCastFn(spell_thorim_stormhammer_SpellScript::LoseHammer);
+ OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_stormhammer_SpellScript();
+ }
+};
+
+// 64767 - Stormhammer
+class spell_thorim_stormhammer_sif : public SpellScriptLoader
+{
+ public:
+ spell_thorim_stormhammer_sif() : SpellScriptLoader("spell_thorim_stormhammer_sif") { }
+
+ class spell_thorim_stormhammer_sif_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_stormhammer_sif_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo(
+ {
+ SPELL_STORMHAMMER_BOOMERANG,
+ SPELL_SIF_TRANSFORM
+ });
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->CastSpell(GetCaster(), SPELL_STORMHAMMER_BOOMERANG, true);
+ target->CastSpell(target, SPELL_SIF_TRANSFORM, true);
+ }
+ }
+
+ void LoseHammer()
+ {
+ GetCaster()->SetVirtualItem(0, 0);
+ }
+
+ void Register() override
+ {
+ AfterCast += SpellCastFn(spell_thorim_stormhammer_sif_SpellScript::LoseHammer);
+ OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_sif_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_stormhammer_sif_SpellScript();
+ }
+};
+
+// 64909 - Stormhammer
+class spell_thorim_stormhammer_boomerang : public SpellScriptLoader
+{
+ public:
+ spell_thorim_stormhammer_boomerang() : SpellScriptLoader("spell_thorim_stormhammer_boomerang") { }
+
+ class spell_thorim_stormhammer_boomerang_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_stormhammer_boomerang_SpellScript);
+
+ void RecoverHammer(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->SetVirtualItem(0, THORIM_WEAPON_DISPLAY_ID);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_thorim_stormhammer_boomerang_SpellScript::RecoverHammer, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_stormhammer_boomerang_SpellScript();
+ }
+};
+
+// 62057, 62058 - Runic Smash
+class spell_thorim_runic_smash : public SpellScriptLoader
+{
+ public:
+ spell_thorim_runic_smash() : SpellScriptLoader("spell_thorim_runic_smash") { }
+
+ class spell_thorim_runic_smash_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thorim_runic_smash_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_RUNIC_SMASH });
+ }
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+
+ std::vector<Creature*> triggers;
+ GetCaster()->GetCreatureListWithEntryInGrid(triggers, GetSpellInfo()->Id == SPELL_RUNIC_SMASH_LEFT ? NPC_GOLEM_LEFT_HAND_BUNNY : NPC_GOLEM_RIGHT_HAND_BUNNY, 150.0f);
+ for (Creature* trigger : triggers)
+ {
+ float dist = GetCaster()->GetExactDist(trigger);
+ trigger->m_Events.AddEvent(new RunicSmashExplosionEvent(trigger), trigger->m_Events.CalculateTime(uint64(dist * 30.f)));
+ };
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_thorim_runic_smash_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_TRIGGER_SPELL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_thorim_runic_smash_SpellScript();
+ }
+};
+
+class UpperOrbCheck
+{
+ public:
+ UpperOrbCheck() : _check(true) { }
+
+ bool operator() (Creature* target) const
+ {
+ return target->GetEntry() == NPC_THUNDER_ORB && _check(target);
+ }
+
+ private:
+ HeightPositionCheck const _check;
+};
+
+// 62184 - Activate Lightning Orb Periodic
+class spell_thorim_activate_lightning_orb_periodic : public SpellScriptLoader
+{
+ public:
+ spell_thorim_activate_lightning_orb_periodic() : SpellScriptLoader("spell_thorim_activate_lightning_orb_periodic") { }
+
+ class spell_thorim_activate_lightning_orb_periodic_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_thorim_activate_lightning_orb_periodic_AuraScript);
+
+ InstanceScript* instance = nullptr;
+
+ void PeriodicTick(AuraEffect const* /*aurEff*/)
+ {
+ PreventDefaultAction();
+
+ Unit* caster = GetCaster();
+ std::vector<Creature*> triggers;
+
+ UpperOrbCheck check;
+ Trinity::CreatureListSearcher<UpperOrbCheck> searcher(caster, triggers, check);
+ Cell::VisitGridObjects(caster, searcher, 100.f);
+
+ if (!triggers.empty())
+ {
+ Creature* target = Trinity::Containers::SelectRandomContainerElement(triggers);
+ if (Creature* thorim = instance->GetCreature(BOSS_THORIM))
+ thorim->AI()->SetGUID(target->GetGUID(), DATA_CHARGED_PILLAR);
+ }
+ }
+
+ bool Load() override
+ {
+ if (Unit* caster = GetCaster())
+ instance = caster->GetInstanceScript();
+
+ return instance != nullptr;
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_thorim_activate_lightning_orb_periodic_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_thorim_activate_lightning_orb_periodic_AuraScript();
+ }
+};
+
+// 62331, 62418 - Impale
+class spell_iron_ring_guard_impale : public SpellScriptLoader
+{
+ public:
+ spell_iron_ring_guard_impale() : SpellScriptLoader("spell_iron_ring_guard_impale") { }
+
+ class spell_iron_ring_guard_impale_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_iron_ring_guard_impale_AuraScript);
+
+ void PeriodicTick(AuraEffect const* /*aurEff*/)
+ {
+ if (GetTarget()->HealthAbovePct(GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue()))
+ {
+ Remove(AURA_REMOVE_BY_ENEMY_SPELL);
+ PreventDefaultAction();
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_iron_ring_guard_impale_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_iron_ring_guard_impale_AuraScript();
+ }
+};
+
+class condition_thorim_arena_leap : public ConditionScript
+{
+ public:
+ condition_thorim_arena_leap() : ConditionScript("condition_thorim_arena_leap"), _check(false) { }
+
+ bool OnConditionCheck(Condition const* condition, ConditionSourceInfo& sourceInfo) override
+ {
+ WorldObject* target = sourceInfo.mConditionTargets[condition->ConditionTarget];
+ InstanceScript* instance = target->GetInstanceScript();
+
+ if (!instance)
+ return false;
+
+ return _check(target);
+ }
+
+ private:
+ HeightPositionCheck _check;
+};
+
void AddSC_boss_thorim()
{
new boss_thorim();
+ new npc_thorim_pre_phase();
+ new npc_thorim_arena_phase();
+ new npc_runic_colossus();
+ new npc_ancient_rune_giant();
+ new npc_sif();
+ new spell_thorim_blizzard_effect();
+ new spell_thorim_frostbolt_volley();
+ new spell_thorim_charge_orb();
+ new spell_thorim_lightning_charge();
+ new spell_thorim_stormhammer();
+ new spell_thorim_stormhammer_sif();
+ new spell_thorim_stormhammer_boomerang();
+ new spell_thorim_arena_leap();
+ new spell_thorim_runic_smash();
+ new spell_thorim_activate_lightning_orb_periodic();
+ new spell_iron_ring_guard_impale();
+ new condition_thorim_arena_leap();
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
index 2eb507db98c..be43dc8c6cb 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -774,7 +774,7 @@ class boss_sara : public CreatureScript
{
me->RemoveAllAuras();
me->SetReactState(REACT_PASSIVE);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
_events.Reset();
_events.SetPhase(PHASE_ONE);
}
@@ -817,7 +817,7 @@ class boss_sara : public CreatureScript
case EVENT_TRANSFORM_3:
Talk(SAY_SARA_TRANSFORM_4);
DoCast(me, SPELL_FULL_HEAL);
- me->SetFaction(16);
+ me->SetFaction(FACTION_MONSTER_2);
if (Creature* voice = _instance->GetCreature(DATA_VOICE_OF_YOGG_SARON))
voice->AI()->DoAction(ACTION_PHASE_TWO);
if (Creature* mimiron = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_MIMIRON_YS)))
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index d34a7ac516c..a90efe7bfd8 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -38,9 +38,9 @@ static BossBoundaryData const boundaries =
{ BOSS_XT002, new RectangleBoundary(755.0f, 940.0f, -125.0f, 95.0f) },
{ BOSS_ASSEMBLY_OF_IRON, new CircleBoundary(Position(1587.2f, 121.0f), 90.0) },
{ BOSS_ALGALON, new CircleBoundary(Position(1632.668f, -307.7656f), 45.0) },
- { BOSS_ALGALON, new ZRangeBoundary(410.0f, 440.0f) },
+ { BOSS_ALGALON, new ZRangeBoundary(410.0f, 470.0f) },
{ BOSS_HODIR, new EllipseBoundary(Position(2001.5f, -240.0f), 50.0, 75.0) },
- { BOSS_THORIM, new CircleBoundary(Position(2134.73f, -263.2f), 50.0) },
+ // Thorim sets boundaries dynamically
{ BOSS_FREYA, new RectangleBoundary(2094.6f, 2520.0f, -250.0f, 200.0f) },
{ BOSS_MIMIRON, new CircleBoundary(Position(2744.0f, 2569.0f), 70.0) },
{ BOSS_VEZAX, new RectangleBoundary(1740.0f, 1930.0f, 31.0f, 228.0f) },
@@ -59,6 +59,11 @@ static DoorData const doorData[] =
{ GO_MIMIRON_DOOR_1, BOSS_MIMIRON, DOOR_TYPE_ROOM },
{ GO_MIMIRON_DOOR_2, BOSS_MIMIRON, DOOR_TYPE_ROOM },
{ GO_MIMIRON_DOOR_3, BOSS_MIMIRON, DOOR_TYPE_ROOM },
+ { GO_THORIM_ENCOUNTER_DOOR, BOSS_THORIM, DOOR_TYPE_ROOM },
+ { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_HODIR, DOOR_TYPE_PASSAGE },
+ { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_MIMIRON, DOOR_TYPE_PASSAGE },
+ { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_THORIM, DOOR_TYPE_PASSAGE },
+ { GO_ANCIENT_GATE_OF_THE_KEEPERS, BOSS_FREYA, DOOR_TYPE_PASSAGE },
{ GO_VEZAX_DOOR, BOSS_VEZAX, DOOR_TYPE_PASSAGE },
{ GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM },
{ GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM },
@@ -95,6 +100,10 @@ ObjectData const creatureData[] =
{ NPC_EXPEDITION_COMMANDER, DATA_EXPEDITION_COMMANDER },
{ NPC_RAZORSCALE_CONTROLLER, DATA_RAZORSCALE_CONTROL },
+ { NPC_SIF, DATA_SIF },
+ { NPC_RUNIC_COLOSSUS, DATA_RUNIC_COLOSSUS },
+ { NPC_RUNE_GIANT, DATA_RUNE_GIANT },
+ { NPC_THORIM_CONTROLLER, DATA_THORIM_CONTROLLER },
{ NPC_COMPUTER, DATA_COMPUTER },
{ NPC_WORLD_TRIGGER_MIMIRON, DATA_MIMIRON_WORLD_TRIGGER },
{ NPC_VOICE_OF_YOGG_SARON, DATA_VOICE_OF_YOGG_SARON },
@@ -118,6 +127,9 @@ ObjectData const objectData[] =
{ GO_RAZOR_HARPOON_2, GO_RAZOR_HARPOON_2 },
{ GO_RAZOR_HARPOON_3, GO_RAZOR_HARPOON_3 },
{ GO_RAZOR_HARPOON_4, GO_RAZOR_HARPOON_4 },
+ { GO_THORIM_LEVER, DATA_THORIM_LEVER },
+ { GO_THORIM_STONE_DOOR, DATA_STONE_DOOR },
+ { GO_THORIM_RUNIC_DOOR, DATA_RUNIC_DOOR },
{ 0, 0 }
};
@@ -173,7 +185,9 @@ class instance_ulduar : public InstanceMapScript
ObjectGuid LeviathanGateGUID;
ObjectGuid KologarnChestGUID;
ObjectGuid KologarnBridgeGUID;
- ObjectGuid ThorimChestGUID;
+ ObjectGuid ThorimDarkIronPortcullisGUID;
+ ObjectGuid CacheOfStormsGUID;
+ ObjectGuid CacheOfStormsHardmodeGUID;
ObjectGuid HodirRareCacheGUID;
ObjectGuid HodirChestGUID;
ObjectGuid MimironTramGUID;
@@ -330,6 +344,16 @@ class instance_ulduar : public InstanceMapScript
creature->UpdateEntry(NPC_BATTLE_PRIEST_GINA);
break;
+ // Thorim
+ case NPC_MERCENARY_CAPTAIN_H:
+ if (TeamInInstance == HORDE)
+ creature->UpdateEntry(NPC_MERCENARY_CAPTAIN_A);
+ break;
+ case NPC_MERCENARY_SOLDIER_H:
+ if (TeamInInstance == HORDE)
+ creature->UpdateEntry(NPC_MERCENARY_SOLDIER_A);
+ break;
+
// Freya
case NPC_IRONBRANCH:
ElderGUIDs[0] = creature->GetGUID();
@@ -447,9 +471,16 @@ class instance_ulduar : public InstanceMapScript
if (GetBossState(BOSS_KOLOGARN) == DONE)
HandleGameObject(ObjectGuid::Empty, false, gameObject);
break;
- case GO_THORIM_CHEST_HERO:
- case GO_THORIM_CHEST:
- ThorimChestGUID = gameObject->GetGUID();
+ case GO_THORIM_DARK_IRON_PORTCULLIS:
+ ThorimDarkIronPortcullisGUID = gameObject->GetGUID();
+ break;
+ case GO_CACHE_OF_STORMS_10:
+ case GO_CACHE_OF_STORMS_25:
+ CacheOfStormsGUID = gameObject->GetGUID();
+ break;
+ case GO_CACHE_OF_STORMS_HARDMODE_10:
+ case GO_CACHE_OF_STORMS_HARDMODE_25:
+ CacheOfStormsHardmodeGUID = gameObject->GetGUID();
break;
case GO_HODIR_RARE_CACHE_OF_WINTER_HERO:
case GO_HODIR_RARE_CACHE_OF_WINTER:
@@ -656,11 +687,25 @@ class instance_ulduar : public InstanceMapScript
case BOSS_THORIM:
if (state == DONE)
{
- if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID))
- gameObject->SetRespawnTime(gameObject->GetRespawnDelay());
+ if (Creature* thorim = GetCreature(BOSS_THORIM))
+ {
+ if (GameObject* cache = instance->GetGameObject(thorim->AI()->GetData(DATA_THORIM_HARDMODE) ? CacheOfStormsHardmodeGUID : CacheOfStormsGUID))
+ {
+ cache->SetLootRecipient(thorim->GetLootRecipient());
+ cache->SetRespawnTime(cache->GetRespawnDelay());
+ cache->RemoveFlag(GO_FLAG_LOCKED);
+ cache->RemoveFlag(GO_FLAG_NOT_SELECTABLE);
+ cache->RemoveFlag(GO_FLAG_NODESPAWN);
+ }
+ }
instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]);
}
+ else
+ {
+ DoCloseDoorOrButton(GetGuidData(DATA_THORIM_LEVER));
+ DoCloseDoorOrButton(ThorimDarkIronPortcullisGUID);
+ }
break;
case BOSS_ALGALON:
if (state == DONE)
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index a26b699b396..885686e6fc6 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -157,6 +157,31 @@ enum UlduarNPCs
// Freya Achievement Trigger
NPC_FREYA_ACHIEVE_TRIGGER = 33406,
+ // Thorim
+ NPC_THORIM_INVISIBLE_STALKER = 32780,
+ NPC_JORMUNGAR_BEHEMOTH = 32882,
+ NPC_MERCENARY_CAPTAIN_A = 32908,
+ NPC_MERCENARY_CAPTAIN_H = 32907,
+ NPC_MERCENARY_SOLDIER_A = 32885,
+ NPC_MERCENARY_SOLDIER_H = 32883,
+ NPC_DARK_RUNE_ACOLYTE_PRE = 32886,
+ NPC_RUNIC_COLOSSUS = 32872,
+ NPC_RUNE_GIANT = 32873,
+ NPC_IRON_RING_GUARD = 32874,
+ NPC_IRON_HONOR_GUARD = 32875,
+ NPC_DARK_RUNE_CHAMPION = 32876,
+ NPC_DARK_RUNE_WARBRINGER = 32877,
+ NPC_DARK_RUNE_EVOKER = 32878,
+ NPC_DARK_RUNE_COMMONER = 32904,
+ NPC_DARK_RUNE_ACOLYTE = 33110,
+ NPC_THORIM_EVENT_BUNNY = 32892,
+ NPC_LIGHTNING_ORB = 33138,
+ NPC_GOLEM_RIGHT_HAND_BUNNY = 33140,
+ NPC_GOLEM_LEFT_HAND_BUNNY = 33141,
+ NPC_SIF = 33196,
+ NPC_THUNDER_ORB = 33378,
+ NPC_THORIM_CONTROLLER = 32879,
+
// Yogg-Saron
NPC_SARA = 33134,
NPC_GUARDIAN_OF_YOGG_SARON = 33136,
@@ -231,6 +256,8 @@ enum UlduarGameObjects
GO_KOLOGARN_BRIDGE = 194232,
GO_KOLOGARN_DOOR = 194553,
+ GO_ANCIENT_GATE_OF_THE_KEEPERS = 194255,
+
// Hodir
GO_HODIR_ENTRANCE = 194442,
GO_HODIR_DOOR = 194634,
@@ -241,8 +268,15 @@ enum UlduarGameObjects
GO_HODIR_CHEST = 194307,
// Thorim
- GO_THORIM_CHEST_HERO = 194315,
- GO_THORIM_CHEST = 194314,
+ GO_CACHE_OF_STORMS_10 = 194312,
+ GO_CACHE_OF_STORMS_HARDMODE_10 = 194313,
+ GO_CACHE_OF_STORMS_25 = 194315,
+ GO_CACHE_OF_STORMS_HARDMODE_25 = 194314,
+ GO_THORIM_RUNIC_DOOR = 194557,
+ GO_THORIM_STONE_DOOR = 194558,
+ GO_THORIM_ENCOUNTER_DOOR = 194559,
+ GO_THORIM_LEVER = 194264,
+ GO_THORIM_DARK_IRON_PORTCULLIS = 194560,
// Mimiron
GO_MIMIRON_TRAM = 194675,
@@ -407,6 +441,16 @@ enum UlduarData
DATA_ALGALON_TRAPDOOR,
DATA_BRANN_BRONZEBEARD_ALG,
+ // Thorim
+ DATA_SIF,
+ DATA_THORIM_LEVER,
+ DATA_RUNIC_COLOSSUS,
+ DATA_RUNE_GIANT,
+ DATA_RUNIC_DOOR,
+ DATA_STONE_DOOR,
+ DATA_THORIM_HARDMODE,
+ DATA_THORIM_CONTROLLER,
+
// Misc
DATA_BRANN_BRONZEBEARD_INTRO,
DATA_LORE_KEEPER_OF_NORGANNON,
@@ -423,10 +467,15 @@ enum UlduarWorldStates
enum UlduarAchievementData
{
// FL Achievement boolean
- DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs,
+ DATA_UNBROKEN = 29052906, // 2905, 2906 are achievement IDs,
MAX_HERALD_ARMOR_ITEMLEVEL = 226,
- MAX_HERALD_WEAPON_ITEMLEVEL = 232,
- SPELL_LUMBERJACKED_CREDIT = 65296
+ MAX_HERALD_WEAPON_ITEMLEVEL = 232
+};
+
+enum UlduarSharedSpells
+{
+ SPELL_LUMBERJACKED_CREDIT = 65296,
+ SPELL_TELEPORT_KEEPER_VISUAL = 62940 // used by keepers
};
enum UlduarEvents
@@ -445,6 +494,23 @@ enum YoggSaronIllusions
STORMWIND_ILLUSION = 2,
};
+class KeeperDespawnEvent : public BasicEvent
+{
+public:
+ KeeperDespawnEvent(Creature* owner, uint32 despawnTimerOffset = 500) : _owner(owner), _despawnTimer(despawnTimerOffset) { }
+
+ bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
+ {
+ _owner->CastSpell(_owner, SPELL_TELEPORT_KEEPER_VISUAL);
+ _owner->DespawnOrUnsummon(1000 + _despawnTimer);
+ return true;
+ }
+
+private:
+ Creature* _owner;
+ uint32 _despawnTimer;
+};
+
template<typename AI, typename T>
inline AI* GetUlduarAI(T* obj)
{
diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp
index 5b9ab19fb86..ae9d06e9e5d 100644
--- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp
+++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp
@@ -277,7 +277,7 @@ class npc_frozen_orb_stalker : public CreatureScript
{
Position pos;
me->GetNearPoint(toravon, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 10.0f, 0.0f);
- me->SetPosition(pos);
+ me->UpdatePosition(pos);
DoCast(me, SPELL_FROZEN_ORB_SUMMON);
}
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
index 042b8dad906..8d7231d2ea3 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
@@ -243,7 +243,7 @@ class npc_ichor_globule : public CreatureScript
struct npc_ichor_globuleAI : public ScriptedAI
{
- npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature)
+ npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature), _splashTriggered(false)
{
_instance = creature->GetInstanceScript();
creature->SetReactState(REACT_PASSIVE);
@@ -275,14 +275,21 @@ class npc_ichor_globule : public CreatureScript
// this feature should be still implemented
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
+ if (_splashTriggered)
+ return;
+
if (damage >= me->GetHealth())
+ {
+ _splashTriggered = true;
DoCastAOE(SPELL_SPLASH);
+ }
}
void UpdateAI(uint32 /*diff*/) override { }
private:
InstanceScript* _instance;
+ bool _splashTriggered;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Northrend/northrend_script_loader.cpp b/src/server/scripts/Northrend/northrend_script_loader.cpp
index 934d29e61b6..57bd641591c 100644
--- a/src/server/scripts/Northrend/northrend_script_loader.cpp
+++ b/src/server/scripts/Northrend/northrend_script_loader.cpp
@@ -110,6 +110,7 @@ void AddSC_boss_general_vezax();
void AddSC_boss_mimiron();
void AddSC_boss_hodir();
void AddSC_boss_freya();
+void AddSC_boss_thorim();
void AddSC_boss_yogg_saron();
void AddSC_boss_algalon_the_observer();
void AddSC_instance_ulduar();
@@ -291,6 +292,7 @@ void AddNorthrendScripts()
AddSC_boss_mimiron();
AddSC_boss_hodir();
AddSC_boss_freya();
+ AddSC_boss_thorim();
AddSC_boss_yogg_saron();
AddSC_boss_algalon_the_observer();
AddSC_instance_ulduar();
diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp
index b14038431ad..b487d7fc6e1 100644
--- a/src/server/scripts/Northrend/zone_borean_tundra.cpp
+++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp
@@ -119,7 +119,7 @@ public:
DoCast(me, SPELL_EXPLODE_CART, true);
DoCast(me, SPELL_SUMMON_CART, true);
if (GameObject* cart = me->FindNearestGameObject(GO_EXPLOSIVES_CART, 3.0f))
- cart->SetFaction(14);
+ cart->SetFaction(FACTION_MONSTER);
phaseTimer = 3000;
phase = 2;
break;
@@ -557,9 +557,6 @@ enum Lurgglbr
GO_CAGE = 187369,
- FACTION_ESCORTEE_A = 774,
- FACTION_ESCORTEE_H = 775,
-
SAY_START_1 = 0,
SAY_START_2 = 1,
SAY_END_1 = 2,
@@ -681,11 +678,11 @@ public:
switch (player->GetTeam())
{
case ALLIANCE:
- me->SetFaction(FACTION_ESCORTEE_A);
+ me->SetFaction(FACTION_ESCORTEE_A_PASSIVE);
break;
default:
case HORDE:
- me->SetFaction(FACTION_ESCORTEE_H);
+ me->SetFaction(FACTION_ESCORTEE_H_PASSIVE);
break;
}
}
@@ -1690,10 +1687,10 @@ public:
switch (player->GetTeam())
{
case ALLIANCE:
- me->SetFaction(FACTION_ESCORTEE_A);
+ me->SetFaction(FACTION_ESCORTEE_A_PASSIVE);
break;
case HORDE:
- me->SetFaction(FACTION_ESCORTEE_H);
+ me->SetFaction(FACTION_ESCORTEE_H_PASSIVE);
break;
}
me->SetStandState(UNIT_STAND_STATE_STAND);
diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp
index 5c7df86b6a4..9c3f455bc41 100644
--- a/src/server/scripts/Northrend/zone_dragonblight.cpp
+++ b/src/server/scripts/Northrend/zone_dragonblight.cpp
@@ -379,9 +379,7 @@ enum StrengthenAncientsMisc
SPELL_CREATE_ITEM_BARK = 47550,
SPELL_CONFUSED = 47044,
- NPC_LOTHALOR = 26321,
-
- FACTION_WALKER_ENEMY = 14,
+ NPC_LOTHALOR = 26321
};
class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker
@@ -414,7 +412,7 @@ public:
else if (roll == 0) // enemy version
{
tree->AI()->Talk(SAY_WALKER_ENEMY, player);
- tree->SetFaction(FACTION_WALKER_ENEMY);
+ tree->SetFaction(FACTION_MONSTER);
tree->Attack(player, true);
}
}
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index d5c06855cff..bfb90373474 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -103,7 +103,7 @@ public:
Talk(SAY_WORGRAGGRO3);
if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX()+10, me->GetPositionY()+8, me->GetPositionZ()+2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000))
{
- RWORG->SetFaction(35);
+ RWORG->SetFaction(FACTION_FRIENDLY);
_RavenousworgGUID = RWORG->GetGUID();
}
break;
@@ -136,7 +136,7 @@ public:
{
RWORG->Kill(Mrfloppy);
Mrfloppy->ExitVehicle();
- RWORG->SetFaction(14);
+ RWORG->SetFaction(FACTION_MONSTER);
RWORG->GetMotionMaster()->MovePoint(0, RWORG->GetPositionX()+10, RWORG->GetPositionY()+80, RWORG->GetPositionZ());
Talk(SAY_VICTORY2);
}
diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp
index cab2d03b29c..1989b424679 100644
--- a/src/server/scripts/Northrend/zone_howling_fjord.cpp
+++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp
@@ -43,7 +43,6 @@ EndContentData */
enum Entries
{
NPC_APOTHECARY_HANES = 23784,
- FACTION_ESCORTEE_H = 775,
QUEST_TRAIL_OF_FIRE = 11241,
SPELL_HEALING_POTION = 17534,
@@ -155,7 +154,7 @@ public:
break;
case EVENT_START_ESCORT:
events.Reset();
- me->SetFaction(FACTION_ESCORTEE_H);
+ me->SetFaction(FACTION_ESCORTEE_H_PASSIVE);
me->SetReactState(REACT_AGGRESSIVE);
ENSURE_AI(npc_escortAI, (me->AI()))->Start(true, true, _player);
break;
diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp
index 8adbd37d884..bf4caf3128f 100644
--- a/src/server/scripts/Northrend/zone_icecrown.cpp
+++ b/src/server/scripts/Northrend/zone_icecrown.cpp
@@ -47,7 +47,7 @@ public:
{
Initialize();
creature->GetMotionMaster()->MovePoint(0, 8599.258f, 963.951f, 547.553f);
- creature->SetFaction(35); //wrong faction in db?
+ creature->SetFaction(FACTION_FRIENDLY); //wrong faction in db?
}
void Initialize()
@@ -69,7 +69,7 @@ public:
if (uiType != POINT_MOTION_TYPE)
return;
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
}
void DamageTaken(Unit* pDoneBy, uint32& uiDamage) override
@@ -78,7 +78,7 @@ public:
{
uiDamage = 0;
pDoneBy->CastSpell(pDoneBy, SPELL_KILL_CREDIT, true);
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->DespawnOrUnsummon(5000);
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
EnterEvadeMode();
diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
index 01285e18a61..5ace31b5cdd 100644
--- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
@@ -340,7 +340,7 @@ public:
if (quest->GetQuestId() == QUEST_DISASTER)
{
me->GetMotionMaster()->MoveJumpTo(0, 0.4f, 0.4f);
- me->SetFaction(113);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
Start(false, false, player->GetGUID());
Talk(SAY_WP_1);
diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp
index 8fbf23d4a44..5a0e6c5aa99 100644
--- a/src/server/scripts/Northrend/zone_storm_peaks.cpp
+++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp
@@ -93,7 +93,7 @@ public:
if (menuId == GOSSIP_ID && gossipListId == GOSSIP_OPTION_ID)
{
CloseGossipMenuFor(player);
- me->SetFaction(113);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
Start(true, true, player->GetGUID());
}
return false;
diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp
index 48dc7a1d7e4..4e1079eccc7 100644
--- a/src/server/scripts/Northrend/zone_zuldrak.cpp
+++ b/src/server/scripts/Northrend/zone_zuldrak.cpp
@@ -139,7 +139,7 @@ public:
void Reset() override
{
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P
}
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
index 56b21a7465f..416eec05c45 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
@@ -192,7 +192,7 @@ class boss_grandmaster_vorpil : public CreatureScript
if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH))
i_pl->TeleportTo(me->GetMapId(), VorpilPosition.GetPositionX(), VorpilPosition.GetPositionY(), VorpilPosition.GetPositionZ(), VorpilPosition.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT);
- me->SetPosition(VorpilPosition);
+ me->UpdatePosition(VorpilPosition);
DoCast(me, SPELL_DRAW_SHADOWS, true);
DoCast(me, SPELL_RAIN_OF_FIRE);
events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000);
diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.h b/src/server/scripts/Outland/BlackTemple/black_temple.h
index 2213c65373d..42a6c0457d8 100644
--- a/src/server/scripts/Outland/BlackTemple/black_temple.h
+++ b/src/server/scripts/Outland/BlackTemple/black_temple.h
@@ -133,7 +133,6 @@ enum BTGameObjectIds
enum BlackTempleMisc
{
- ASHTONGUE_FACTION_FRIEND = 1820,
AKAMA_FACTION_COMBAT = 1868,
AKAMA_INTRO = 1,
AKAMA_FIGHT = 2,
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 44f9f9069ee..1080e6c1ca9 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -439,7 +439,7 @@ public:
bool operator()(Unit* unit) const
{
- return _me->GetDistance2d(unit) > 25.0f;
+ return unit->GetTypeId() == TYPEID_PLAYER && _me->GetDistance2d(unit) > 25.0f;
}
private:
@@ -2074,7 +2074,8 @@ class spell_illidan_flame_blast : public SpellScriptLoader
void HandleBlaze(SpellEffIndex /*effIndex*/)
{
Unit* target = GetHitUnit();
- target->CastSpell(target, SPELL_BLAZE_SUMMON, true);
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ target->CastSpell(target, SPELL_BLAZE_SUMMON, true);
}
void Register() override
diff --git a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
index 279749dfd9f..3d5b3c3f4a4 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
@@ -384,7 +384,7 @@ public:
void Reset() override
{
Initialize();
- me->SetFaction(ASHTONGUE_FACTION_FRIEND);
+ me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
DoCastSelf(SPELL_STEALTH);
if (_instance->GetBossState(DATA_SHADE_OF_AKAMA) != DONE)
@@ -430,7 +430,7 @@ public:
{
_isInCombat = false;
me->CombatStop(true);
- me->SetFaction(ASHTONGUE_FACTION_FRIEND);
+ me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
me->SetWalk(true);
_events.Reset();
me->GetMotionMaster()->MovePoint(AKAMA_INTRO_WAYPOINT, AkamaWP[1]);
@@ -484,7 +484,7 @@ public:
case EVENT_SHADE_CHANNEL:
me->SetFacingTo(FACE_THE_PLATFORM);
DoCastSelf(SPELL_AKAMA_SOUL_CHANNEL);
- me->SetFaction(AKAMA_FACTION_COMBAT);
+ me->SetFaction(FACTION_MONSTER_SPAR_BUDDY);
_events.ScheduleEvent(EVENT_FIXATE, Seconds(5));
break;
case EVENT_FIXATE:
@@ -532,7 +532,7 @@ public:
}
}
- if (me->GetFaction() == AKAMA_FACTION_COMBAT)
+ if (me->GetFaction() == FACTION_MONSTER_SPAR_BUDDY)
{
if (!UpdateVictim())
return;
@@ -1171,7 +1171,7 @@ public:
Talk(SAY_BROKEN_SPECIAL);
break;
case ACTION_BROKEN_HAIL:
- me->SetFaction(ASHTONGUE_FACTION_FRIEND);
+ me->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
Talk(SAY_BROKEN_HAIL);
break;
case ACTION_BROKEN_EMOTE:
diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
index 21197f01c81..bc2c071f7c3 100644
--- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
+++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp
@@ -128,7 +128,7 @@ class instance_black_temple : public InstanceMapScript
case NPC_STORM_FURY:
AshtongueGUIDs.emplace_back(creature->GetGUID());
if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE)
- creature->SetFaction(ASHTONGUE_FACTION_FRIEND);
+ creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
break;
default:
break;
@@ -175,8 +175,8 @@ class instance_black_temple : public InstanceMapScript
if (state == DONE)
for (ObjectGuid ashtongueGuid : AshtongueGUIDs)
if (Creature* ashtongue = instance->GetCreature(ashtongueGuid))
- ashtongue->SetFaction(ASHTONGUE_FACTION_FRIEND);
- /* fallthrough */
+ ashtongue->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
+ // no break
case DATA_TERON_GOREFIEND:
case DATA_GURTOGG_BLOODBOIL:
case DATA_RELIQUARY_OF_SOULS:
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
index a454599bbf7..ba563eb252f 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
@@ -753,7 +753,7 @@ public:
void Reset() override
{
me->SetDisableGravity(true);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
Initialize();
}
@@ -788,7 +788,7 @@ public:
{
if (Creature* trig = me->SummonCreature(TOXIC_SPORES_TRIGGER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000))
{
- trig->SetFaction(14);
+ trig->SetFaction(FACTION_MONSTER);
trig->CastSpell(trig, SPELL_TOXIC_SPORES, true);
}
}
@@ -804,7 +804,7 @@ public:
if (!Vashj || !Vashj->IsAlive() || ENSURE_AI(boss_lady_vashj::boss_lady_vashjAI, Vashj->ToCreature()->AI())->Phase != 3)
{
// remove
- me->SetFaction(35);
+ me->SetFaction(FACTION_FRIENDLY);
me->DespawnOrUnsummon();
return;
}
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
index eca80aec5e6..8d2d134d80c 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp
@@ -321,7 +321,7 @@ public:
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
}
void EnterCombat(Unit* /*who*/) override { }
diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
index 2379950f294..00a911cc53b 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
@@ -662,7 +662,7 @@ public:
InstanceScript* instance;
- bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/)
+ bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
{
ClearGossipMenuFor(player);
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
index 765a7d5a7de..7a04ba358ac 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp
@@ -207,7 +207,7 @@ class boss_grand_warlock_nethekurse : public CreatureScript
void JustSummoned(Creature* summoned) override
{
- summoned->SetFaction(16);
+ summoned->SetFaction(FACTION_MONSTER_2);
summoned->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
summoned->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index 6fba85f3580..59e48cb078b 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -289,7 +289,7 @@ class boss_alar : public CreatureScript
if (me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f))
dist = 5.0f;
WaitTimer = 1000 + uint32(floor(dist / 80 * 1000.0f));
- me->SetPosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f);
+ me->UpdatePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f);
me->StopMoving();
WaitEvent = WE_LAND;
return;
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
index ee7c9396764..f1a4e6e2d8f 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
@@ -291,7 +291,7 @@ class boss_high_astromancer_solarian : public CreatureScript
Phase1_Timer = 50000;
//After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
me->GetMotionMaster()->Clear();
- me->SetPosition(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O);
+ me->UpdatePosition(CENTER_X, CENTER_Y, CENTER_Z, CENTER_O);
for (uint8 i=0; i <= 2; ++i)
{
if (!i)
@@ -357,7 +357,7 @@ class boss_high_astromancer_solarian : public CreatureScript
//15 seconds later Solarian reappears out of one of the 3 portals. Simultaneously, 2 healers appear in the two other portals.
int i = rand32() % 3;
me->GetMotionMaster()->Clear();
- me->SetPosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
+ me->UpdatePosition(Portals[i][0], Portals[i][1], Portals[i][2], CENTER_O);
for (int j=0; j <= 2; j++)
if (j != i)
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
index ee44f0c0f46..ab5480e8b5f 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
@@ -1278,7 +1278,7 @@ class npc_kael_flamestrike : public CreatureScript
Initialize();
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- me->SetFaction(14);
+ me->SetFaction(FACTION_MONSTER);
}
void MoveInLineOfSight(Unit* /*who*/) override { }
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
index 70b1da72d93..3b4f22bc23c 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
@@ -539,7 +539,7 @@ class npc_zerekethvoidzone : public CreatureScript
void Reset() override
{
me->SetNpcFlags(UNIT_NPC_FLAG_NONE);
- me->SetFaction(16);
+ me->SetFaction(FACTION_MONSTER_2);
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
DoCast(me, SPELL_VOID_ZONE_DAMAGE);
diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
index 72001b3a07e..ab8b16468ae 100644
--- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
+++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
@@ -46,8 +46,6 @@ enum Aeranas
{
SAY_SUMMON = 0,
SAY_FREE = 1,
- FACTION_HOSTILE = 16,
- FACTION_FRIENDLY = 35,
SPELL_ENVELOPING_WINDS = 15535,
SPELL_SHOCK = 12553
};
@@ -87,7 +85,7 @@ public:
{
if (faction_Timer <= diff)
{
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_MONSTER_2);
faction_Timer = 0;
} else faction_Timer -= diff;
}
@@ -252,7 +250,7 @@ enum WoundedBloodElf
QUEST_ROAD_TO_FALCON_WATCH = 9375,
NPC_HAALESHI_WINDWALKER = 16966,
NPC_HAALESHI_TALONGUARD = 16967,
- FACTION_FALCON_WATCH_QUEST = 775
+
};
class npc_wounded_blood_elf : public CreatureScript
@@ -281,7 +279,7 @@ public:
{
if (quest->GetQuestId() == QUEST_ROAD_TO_FALCON_WATCH)
{
- me->SetFaction(FACTION_FALCON_WATCH_QUEST);
+ me->SetFaction(FACTION_ESCORTEE_H_PASSIVE);
npc_escortAI::Start(true, false, player->GetGUID());
}
}
@@ -997,7 +995,7 @@ public:
break;
case EVENT_ATTACK:
me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_MONSTER_2);
if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID))
me->CombatStart(player);
_events.ScheduleEvent(EVENT_FIREBALL, 1);
diff --git a/src/server/scripts/Outland/zone_nagrand.cpp b/src/server/scripts/Outland/zone_nagrand.cpp
index c51dfa286ad..55e129504e6 100644
--- a/src/server/scripts/Outland/zone_nagrand.cpp
+++ b/src/server/scripts/Outland/zone_nagrand.cpp
@@ -200,7 +200,7 @@ public:
if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_H)
{
me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetFaction(232);
+ me->SetFaction(FACTION_ESCORTEE_H_NEUTRAL_ACTIVE);
Start(true, false, player->GetGUID(), quest);
Talk(SAY_MAG_START);
@@ -575,7 +575,7 @@ public:
if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_A)
{
me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetFaction(231);
+ me->SetFaction(FACTION_ESCORTEE_A_NEUTRAL_ACTIVE);
Start(true, false, player->GetGUID(), quest);
Talk(SAY_KUR_START);
diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp
index c4560a9d633..9ef66707d03 100644
--- a/src/server/scripts/Outland/zone_netherstorm.cpp
+++ b/src/server/scripts/Outland/zone_netherstorm.cpp
@@ -548,7 +548,7 @@ public:
{
if (quest->GetQuestId() == Q_ALMABTRIEB)
{
- me->SetFaction(113);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
Start(true, false, player->GetGUID());
}
@@ -656,7 +656,7 @@ public:
{
if (quest->GetQuestId() == QUEST_MARK_V_IS_ALIVE)
{
- me->SetFaction(113);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
Start(false, false, player->GetGUID());
}
}
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 19b79b6ee4c..a44dedb56ca 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -341,10 +341,6 @@ public:
enum EnshlavedNetherwingDrake
{
- // Factions
- FACTION_DEFAULT = 62,
- FACTION_FRIENDLY = 1840, // Not sure if this is correct, it was taken off of Mordenai.
-
// Spells
SPELL_HIT_FORCE_OF_NELTHARAKU = 38762,
SPELL_FORCE_OF_NELTHARAKU = 38775,
@@ -380,7 +376,7 @@ public:
void Reset() override
{
if (!Tapped)
- me->SetFaction(FACTION_DEFAULT);
+ me->SetFaction(FACTION_ORC_DRAGONMAW);
FlyTimer = 10000;
me->SetDisableGravity(false);
@@ -396,7 +392,7 @@ public:
Tapped = true;
PlayerGUID = caster->GetGUID();
- me->SetFaction(FACTION_FRIENDLY);
+ me->SetFaction(FACTION_FLAYER_HUNTER);
DoCast(caster, SPELL_FORCE_OF_NELTHARAKU, true);
Unit* Dragonmaw = me->FindNearestCreature(NPC_DRAGONMAW_SUBJUGATOR, 50);
@@ -589,8 +585,7 @@ enum Earthmender
SPELL_HEALING_WAVE = 12491,
QUEST_ESCAPE_COILSCAR = 10451,
- NPC_COILSKAR_ASSASSIN = 21044,
- FACTION_EARTHEN = 1726 //guessed
+ NPC_COILSKAR_ASSASSIN = 21044
};
class npc_earthmender_wilda : public CreatureScript
@@ -733,7 +728,7 @@ public:
if (quest->GetQuestId() == QUEST_ESCAPE_COILSCAR)
{
Talk(SAY_WIL_START, player);
- me->SetFaction(FACTION_EARTHEN);
+ me->SetFaction(FACTION_EARTHEN_RING);
Start(false, false, player->GetGUID(), quest);
}
@@ -1415,11 +1410,7 @@ enum Enraged_Dpirits
NPC_CREDIT_EARTH = 21092,
// Captured Spell / Buff
- SPELL_SOUL_CAPTURED = 36115,
-
- // Factions
- FACTION_ENRAGED_SOUL_FRIENDLY = 35,
- FACTION_ENRAGED_SOUL_HOSTILE = 14
+ SPELL_SOUL_CAPTURED = 36115
};
class npc_enraged_spirit : public CreatureScript
@@ -1487,7 +1478,7 @@ public:
totemOspirits = me->FindNearestCreature(ENTRY_TOTEM_OF_SPIRITS, RADIUS_TOTEM_OF_SPIRITS);
if (totemOspirits)
{
- Summoned->SetFaction(FACTION_ENRAGED_SOUL_FRIENDLY);
+ Summoned->SetFaction(FACTION_FRIENDLY);
Summoned->GetMotionMaster()->MovePoint(0, totemOspirits->GetPositionX(), totemOspirits->GetPositionY(), Summoned->GetPositionZ());
if (Unit* owner = totemOspirits->GetOwner())
diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp
index 5334f567a89..60037276c25 100644
--- a/src/server/scripts/Outland/zone_shattrath_city.cpp
+++ b/src/server/scripts/Outland/zone_shattrath_city.cpp
@@ -44,7 +44,6 @@ enum RaliqTheDrunk
{
SAY_RALIQ_ATTACK = 0,
OPTION_ID_COLLECT_A_DEBT = 0,
- FACTION_OGRE_HOSTILE = 45,
MENU_ID_COLLECT_A_DEBT = 7729,
NPC_TEXT_WUT_YOU_WANT = 9440,
CRACKIN_SOME_SKULLS = 10009,
@@ -97,7 +96,7 @@ public:
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
CloseGossipMenuFor(player);
- me->SetFaction(FACTION_OGRE_HOSTILE);
+ me->SetFaction(FACTION_OGRE);
Talk(SAY_RALIQ_ATTACK, player);
AttackStart(player);
}
@@ -134,8 +133,6 @@ enum Salsalabim
{
SAY_DEMONIC_AGGRO = 0,
OPTION_ID_ALTRUIS_SENT_ME = 0,
- FACTION_FRIENDLY = 35,
- FACTION_DEMON_HOSTILE = 90,
MENU_ID_ALTRUIS_SENT_ME = 7725,
NPC_TEXT_SAL_GROWLS_AT_YOU = 9435,
PATIENCE_AND_UNDERSTANDING = 10004,
@@ -198,7 +195,7 @@ public:
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
CloseGossipMenuFor(player);
- me->SetFaction(FACTION_DEMON_HOSTILE);
+ me->SetFaction(FACTION_DEMON);
Talk(SAY_DEMONIC_AGGRO, player);
AttackStart(player);
}
diff --git a/src/server/scripts/Outland/zone_terokkar_forest.cpp b/src/server/scripts/Outland/zone_terokkar_forest.cpp
index 50ee9cf0039..7d519c434a4 100644
--- a/src/server/scripts/Outland/zone_terokkar_forest.cpp
+++ b/src/server/scripts/Outland/zone_terokkar_forest.cpp
@@ -48,8 +48,6 @@ enum UnkorTheRuthless
{
SAY_SUBMIT = 0,
REQUIRED_KILL_COUNT = 10,
- FACTION_FRIENDLY = 35,
- FACTION_HOSTILE = 45,
SPELL_PULVERIZE = 2676,
QUEST_DONTKILLTHEFATONE = 9889,
NPC_BOULDERFIST_INVADER = 18260
@@ -87,7 +85,7 @@ public:
{
Initialize();
me->SetStandState(UNIT_STAND_STATE_STAND);
- me->SetFaction(FACTION_HOSTILE);
+ me->SetFaction(FACTION_OGRE);
}
void EnterCombat(Unit* /*who*/) override { }
@@ -310,7 +308,6 @@ enum Floon
SAY_FLOON_ATTACK = 0,
OPTION_ID_PAY_UP_OR_DIE = 0,
OPTION_ID_COLLECT_A_DEBT = 0,
- FACTION_HOSTILE_FLOON = 1738,
MENU_ID_PAY_UP_OR_DIE = 7731,
MENU_ID_COLLECT_A_DEBT = 7732,
GOSSIP_FLOON_STRANGE_SOUNDS = 9442,
@@ -395,7 +392,7 @@ public:
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
CloseGossipMenuFor(player);
- me->SetFaction(FACTION_HOSTILE_FLOON);
+ me->SetFaction(FACTION_ARAKKOA);
Talk(SAY_FLOON_ATTACK, player);
AttackStart(player);
}
@@ -428,7 +425,6 @@ enum IslaStarmaneData
SAY_PROGRESS_3 = 2,
SAY_PROGRESS_4 = 3,
GO_DISTANCE = 10,
- FACTION_ESCORTEE = 113,
ESCAPE_FROM_FIREWING_POINT_A = 10051,
ESCAPE_FROM_FIREWING_POINT_H = 10052,
SPELL_TRAVEL_FORM_CAT = 32447,
@@ -504,7 +500,7 @@ public:
if (quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_H || quest->GetQuestId() == ESCAPE_FROM_FIREWING_POINT_A)
{
Start(true, false, player->GetGUID());
- me->SetFaction(FACTION_ESCORTEE);
+ me->SetFaction(FACTION_ESCORTEE_N_NEUTRAL_PASSIVE);
}
}
};
@@ -694,9 +690,9 @@ public:
Start(false, false, player->GetGUID());
if (player->GetTeamId() == TEAM_ALLIANCE)
- me->SetFaction(FACTION_ESCORT_A_NEUTRAL_PASSIVE);
+ me->SetFaction(FACTION_ESCORTEE_A_NEUTRAL_PASSIVE);
else
- me->SetFaction(FACTION_ESCORT_H_NEUTRAL_PASSIVE);
+ me->SetFaction(FACTION_ESCORTEE_H_NEUTRAL_PASSIVE);
}
}
};
diff --git a/src/server/scripts/Outland/zone_zangarmarsh.cpp b/src/server/scripts/Outland/zone_zangarmarsh.cpp
index ced7d46107f..3ff618f4b2d 100644
--- a/src/server/scripts/Outland/zone_zangarmarsh.cpp
+++ b/src/server/scripts/Outland/zone_zangarmarsh.cpp
@@ -162,8 +162,7 @@ public:
enum Cooshhooosh
{
SPELL_LIGHTNING_BOLT = 9532,
- QUEST_CRACK_SKULLS = 10009,
- FACTION_HOSTILE_CO = 45
+ QUEST_CRACK_SKULLS = 10009
};
class npc_cooshcoosh : public CreatureScript
@@ -226,7 +225,7 @@ public:
if (action == GOSSIP_ACTION_INFO_DEF)
{
CloseGossipMenuFor(player);
- me->SetFaction(FACTION_HOSTILE_CO);
+ me->SetFaction(FACTION_OGRE);
AttackStart(player);
}
return true;
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 48d63353a34..b0e52234c13 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -66,6 +66,7 @@ enum DruidSpells
SPELL_DRUID_REJUVENATION_T10_PROC = 70691,
SPELL_DRUID_BALANCE_T10_BONUS = 70718,
SPELL_DRUID_BALANCE_T10_BONUS_PROC = 70721,
+ SPELL_DRUID_RESTORATION_T10_2P_BONUS = 70658,
SPELL_DRUID_SUNFIRE_DAMAGE = 164815,
SPELL_DRUID_SURVIVAL_INSTINCTS = 50322
};
@@ -1434,14 +1435,52 @@ public:
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_wild_growth_SpellScript::SetTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);
}
- private:
std::list<WorldObject*> _targets;
};
+ class spell_dru_wild_growth_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_wild_growth_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_DRUID_RESTORATION_T10_2P_BONUS });
+ }
+
+ void HandleTickUpdate(AuraEffect* aurEff)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ // calculate from base damage, not from aurEff->GetAmount() (already modified)
+ float damage = caster->CalculateSpellDamage(GetUnitOwner(), GetSpellInfo(), aurEff->GetEffIndex());
+
+ // Wild Growth = first tick gains a 6% bonus, reduced by 2% each tick
+ float reduction = 2.f;
+ if (AuraEffect* bonus = caster->GetAuraEffect(SPELL_DRUID_RESTORATION_T10_2P_BONUS, EFFECT_0))
+ reduction -= CalculatePct(reduction, bonus->GetAmount());
+ reduction *= (aurEff->GetTickNumber() - 1);
+
+ AddPct(damage, 6.f - reduction);
+ aurEff->SetAmount(int32(damage));
+ }
+
+ void Register() override
+ {
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dru_wild_growth_AuraScript::HandleTickUpdate, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ }
+ };
+
SpellScript* GetSpellScript() const override
{
return new spell_dru_wild_growth_SpellScript();
}
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_dru_wild_growth_AuraScript();
+ }
};
void AddSC_druid_spell_scripts()
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 2824a5e637b..de38535a865 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -3704,7 +3704,7 @@ class spell_gen_gm_freeze : public SpellScriptLoader
if (Player* player = GetTarget()->ToPlayer())
{
// stop combat + make player unattackable + duel stop + stop some spells
- player->SetFaction(35);
+ player->SetFaction(FACTION_FRIENDLY);
player->CombatStop();
if (player->IsNonMeleeSpellCast(true))
player->InterruptNonMeleeSpells(true);
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 095933d4c03..60db94dbf63 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -259,8 +259,6 @@ enum ChickenCluck
EMOTE_CLUCK_TEXT = 2,
QUEST_CLUCK = 3861,
- FACTION_FRIENDLY = 35,
- FACTION_CHICKEN = 31
};
class npc_chicken_cluck : public CreatureScript
@@ -285,7 +283,7 @@ public:
void Reset() override
{
Initialize();
- me->SetFaction(FACTION_CHICKEN);
+ me->SetFaction(FACTION_PREY);
me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
}
diff --git a/src/server/shared/Dynamic/FactoryHolder.h b/src/server/shared/Dynamic/FactoryHolder.h
index ce6622daea4..317d50ea9fc 100644
--- a/src/server/shared/Dynamic/FactoryHolder.h
+++ b/src/server/shared/Dynamic/FactoryHolder.h
@@ -24,23 +24,21 @@
/** FactoryHolder holds a factory object of a specific type
*/
-template<class T, class Key = std::string>
+template<class T, class O, class Key = std::string>
class FactoryHolder
{
public:
- typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
+ typedef ObjectRegistry<FactoryHolder<T, O, Key>, Key> FactoryHolderRegistry;
- FactoryHolder(Key k) : i_key(k) { }
+ explicit FactoryHolder(Key const& k) : _key(k) { }
virtual ~FactoryHolder() { }
- inline Key key() const { return i_key; }
- void RegisterSelf(void) { FactoryHolderRegistry::instance()->InsertItem(this, i_key); }
- void DeregisterSelf(void) { FactoryHolderRegistry::instance()->RemoveItem(this, false); }
+ void RegisterSelf() { FactoryHolderRegistry::instance()->InsertItem(this, _key); }
/// Abstract Factory create method
- virtual T* Create(void *data = NULL) const = 0;
+ virtual T* Create(O* object = nullptr) const = 0;
private:
- Key i_key;
+ Key const _key;
};
/** Permissible is a classic way of letting the object decide
@@ -52,6 +50,6 @@ class Permissible
{
public:
virtual ~Permissible() { }
- virtual int Permit(const T *) const = 0;
+ virtual int32 Permit(T const*) const = 0;
};
#endif
diff --git a/src/server/shared/Dynamic/ObjectRegistry.h b/src/server/shared/Dynamic/ObjectRegistry.h
index 45380d699d3..973c34fda24 100644
--- a/src/server/shared/Dynamic/ObjectRegistry.h
+++ b/src/server/shared/Dynamic/ObjectRegistry.h
@@ -23,14 +23,15 @@
#include <string>
#include <map>
#include <vector>
+#include <memory>
/** ObjectRegistry holds all registry item of the same type
*/
template<class T, class Key = std::string>
-class ObjectRegistry
+class ObjectRegistry final
{
public:
- typedef std::map<Key, T*> RegistryMapType;
+ typedef std::map<Key, std::unique_ptr<T>> RegistryMapType;
static ObjectRegistry<T, Key>* instance()
{
@@ -39,71 +40,47 @@ class ObjectRegistry
}
/// Returns a registry item
- const T* GetRegistryItem(Key key) const
+ T const* GetRegistryItem(Key const& key) const
{
- typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
- return( iter == i_registeredObjects.end() ? NULL : iter->second );
+ auto itr = _registeredObjects.find(key);
+ if (itr == _registeredObjects.end())
+ return nullptr;
+ return itr->second.get();
}
/// Inserts a registry item
- bool InsertItem(T *obj, Key key, bool _override = false)
+ bool InsertItem(T* obj, Key const& key, bool force = false)
{
- typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
- if ( iter != i_registeredObjects.end() )
+ auto itr = _registeredObjects.find(key);
+ if (itr != _registeredObjects.end())
{
- if ( !_override )
+ if (!force)
return false;
- delete iter->second;
- i_registeredObjects.erase(iter);
+ _registeredObjects.erase(itr);
}
- i_registeredObjects[key] = obj;
+ _registeredObjects.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(obj));
return true;
}
- /// Removes a registry item
- void RemoveItem(Key key, bool delete_object = true)
- {
- typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
- if ( iter != i_registeredObjects.end() )
- {
- if ( delete_object )
- delete iter->second;
- i_registeredObjects.erase(iter);
- }
- }
-
/// Returns true if registry contains an item
- bool HasItem(Key key) const
+ bool HasItem(Key const& key) const
{
- return (i_registeredObjects.find(key) != i_registeredObjects.end());
- }
-
- /// Inefficiently return a vector of registered items
- unsigned int GetRegisteredItems(std::vector<Key> &l) const
- {
- unsigned int sz = l.size();
- l.resize(sz + i_registeredObjects.size());
- for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
- l[sz++] = iter->first;
- return i_registeredObjects.size();
+ return (_registeredObjects.count(key) > 0);
}
/// Return the map of registered items
- RegistryMapType const &GetRegisteredItems() const
+ RegistryMapType const& GetRegisteredItems() const
{
- return i_registeredObjects;
+ return _registeredObjects;
}
- ObjectRegistry() { }
- ~ObjectRegistry()
- {
- for (typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
- delete iter->second;
- i_registeredObjects.clear();
- }
private:
- RegistryMapType i_registeredObjects;
+ RegistryMapType _registeredObjects;
+
+ // non instanceable, only static
+ ObjectRegistry() { }
+ ~ObjectRegistry() { }
};
#endif