aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2012_02_21_00_world_creature_loot_template.sql78
-rw-r--r--sql/updates/world/2012_02_21_01_world_conditions.sql3592
-rw-r--r--sql/updates/world/2012_02_21_02_world_creature_loot_template.sql11
-rw-r--r--sql/updates/world/2012_02_21_03_world_creature_loot_template.sql26
-rw-r--r--sql/updates/world/2012_02_21_04_world_creature_loot_template.sql16
-rw-r--r--sql/updates/world/2012_02_21_05_world_Gossip_SAI.sql39
-rw-r--r--sql/updates/world/2012_02_21_06_world_Gossip.sql184
-rw-r--r--sql/updates/world/2012_02_22_00_world_SAI.sql39
-rw-r--r--sql/updates/world/2012_02_22_01_world_say_text.sql34
-rw-r--r--sql/updates/world/2012_02_22_02_world_misc.sql57
-rw-r--r--sql/updates/world/2012_02_22_03_world_conditions.sql3
-rw-r--r--sql/updates/world/2012_02_23_00_world_spell_script_names.sql7
-rw-r--r--src/server/collision/Models/GameObjectModel.cpp24
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp14
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp10
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp6
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp14
-rwxr-xr-xsrc/server/game/Battlegrounds/ArenaTeam.cpp4
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAV.cpp15
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp447
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.h30
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp20
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h4
-rwxr-xr-xsrc/server/game/Entities/Creature/CreatureGroups.cpp2
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp12
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h6
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp44
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp79
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h3
-rw-r--r--src/server/game/Grids/GridDefines.h10
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.cpp13
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.h117
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiersImpl.h111
-rwxr-xr-xsrc/server/game/Handlers/AuctionHouseHandler.cpp22
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rwxr-xr-xsrc/server/game/Handlers/NPCHandler.cpp16
-rwxr-xr-xsrc/server/game/Maps/Map.cpp2
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.cpp5
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.h7
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp2
-rwxr-xr-xsrc/server/game/Quests/QuestDef.h2
-rwxr-xr-xsrc/server/game/Scripting/MapScripts.cpp12
-rwxr-xr-xsrc/server/game/Scripting/ScriptLoader.cpp2
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp10
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp2514
-rwxr-xr-xsrc/server/game/Spells/Spell.h192
-rw-r--r--src/server/game/Spells/SpellInfo.cpp414
-rw-r--r--src/server/game/Spells/SpellInfo.h31
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp11
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.h12
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp5
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h1
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp6
-rw-r--r--src/server/scripts/Commands/cs_account.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/CMakeLists.txt1
-rw-r--r--src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp62
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp14
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ghostlands.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/hinterlands.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/redridge_mountains.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/searing_gorge.cpp179
-rw-r--r--src/server/scripts/EasternKingdoms/stormwind_city.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/undercity.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/western_plaguelands.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp4
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp12
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp2
-rw-r--r--src/server/scripts/Kalimdor/ZulFarrak/instance_zulfarrak.cpp2
-rw-r--r--src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp2
-rw-r--r--src/server/scripts/Kalimdor/dustwallow_marsh.cpp2
-rw-r--r--src/server/scripts/Kalimdor/silithus.cpp8
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp4
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp6
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp2
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp4
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp6
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp10
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp20
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp18
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp14
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp4
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp10
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp5
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp6
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp34
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp4
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp14
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp2
-rw-r--r--src/server/scripts/Northrend/VioletHold/violet_hold.cpp2
-rw-r--r--src/server/scripts/Northrend/borean_tundra.cpp12
-rw-r--r--src/server/scripts/Northrend/grizzly_hills.cpp2
-rw-r--r--src/server/scripts/Northrend/howling_fjord.cpp2
-rw-r--r--src/server/scripts/Northrend/zuldrak.cpp2
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp10
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp8
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp4
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp6
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp2
-rw-r--r--src/server/scripts/Outland/nagrand.cpp4
-rw-r--r--src/server/scripts/Outland/shadowmoon_valley.cpp10
-rw-r--r--src/server/scripts/Outland/terokkar_forest.cpp3
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp4
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp4
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp2
-rw-r--r--src/server/scripts/Spells/spell_item.cpp33
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp2
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp37
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp4
-rw-r--r--src/server/scripts/World/boss_emerald_dragons.cpp2
-rw-r--r--src/server/scripts/World/npcs_special.cpp6
-rw-r--r--src/server/worldserver/worldserver.conf.dist4
134 files changed, 6711 insertions, 2341 deletions
diff --git a/sql/updates/world/2012_02_21_00_world_creature_loot_template.sql b/sql/updates/world/2012_02_21_00_world_creature_loot_template.sql
new file mode 100644
index 00000000000..1d05c031868
--- /dev/null
+++ b/sql/updates/world/2012_02_21_00_world_creature_loot_template.sql
@@ -0,0 +1,78 @@
+-- Loot for Hellfire 5-man dungeons Trash (heroic and normal) --
+-- -------------------------------------------------------------
+
+-- Hellfire Citadel: Ramparts
+SET @Lootid := 17259;
+-- set all lootids to same entry (normal and heroic)
+UPDATE `creature_template` SET `lootid`=@Lootid WHERE `entry` IN
+(17259,17264,17269,17270,17271,17280,17281,17309,17455,17478,17517,18048,18049,18050,18051,18052,18053,18054,18055,18057,18058,18059);
+-- populate trashloot table
+DELETE FROM `creature_loot_template` WHERE `entry` IN
+(17259,17264,17269,17270,17271,17280,17281,17309,17455,17478,17517,18048,18049,18050,18051,18052,18053,18054,18055,18057,18058,18059);
+DELETE FROM `creature_loot_template` WHERE `entry`=@Lootid;
+INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+-- rough indication based on wowhead data of ALL mobs in the dungeon
+(@Lootid,14047,40,1,0,1,4), -- Runecloth
+(@Lootid,21877,20,1,0,1,4), -- Netherweave Cloth
+(@Lootid, 8952,10,1,0,1,4), -- Roasted Quail
+(@Lootid, 8766, 5,1,0,1,3), -- Morning Glory Dew
+-- references for worldgreys
+(@Lootid,1,5,1,0,-24000,1), -- Outland Grey Item Reference1
+(@Lootid,2,5,1,0,-24002,1), -- Outland Grey Item Reference2
+(@Lootid,3,5,1,0,-24003,1), -- Outland Grey Item Reference3
+(@Lootid,4,5,1,0,-24011,1), -- Outland Grey Item Reference4
+(@Lootid,5,5,1,0,-24022,1), -- Outland Grey Item Reference5
+(@Lootid,6,5,1,0,-24023,1), -- Outland Grey Item Reference6
+-- specifics
+(@Lootid,5759,0.25,1,0,1,1), -- Thorium Lockbox
+(@Lootid,5760,0.30,1,0,1,1), -- Eternium Lockbox
+-- Scrolls
+(@Lootid,7,5,1,0,-24724,1); -- Scroll of <stat> IV
+
+-- -----------------------------------------
+-- -- Hellfire Citadel: The Blood Furnace --
+-- -----------------------------------------
+SET @Lootid := 17370;
+UPDATE `creature_template` SET `lootid`=@Lootid WHERE `entry` IN (17256,17370,17371,17395,17397,17398,17399,17414,17429,17477,17491,17624,17626,17653,18894,19016,18608,18619,18617,18615,18612,18614,18618,18603,18606,18610,18611,18609,18620,21645,21646);
+
+DELETE FROM `creature_loot_template` WHERE `entry` IN (17370,17371,17395,17397,17398,17414,17429,17491,17624,17626,18894);
+INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+(@Lootid,23894,-100,1,0,1,1), -- Fel Orc Blood (quest)
+-- most common items
+(@Lootid,14047,40,1,0,1,4), -- Runecloth
+(@Lootid,21877,20,1,0,1,4), -- Netherweave Cloth
+(@Lootid, 8952,10,1,0,1,4), -- Roasted Quail
+(@Lootid, 8766, 5,1,0,1,3), -- Morning Glory Dew
+-- references for worldgreys
+(@Lootid,1,5,1,0,-24000,1), -- Outland Grey Item Reference1
+(@Lootid,2,5,1,0,-24002,1), -- Outland Grey Item Reference2
+(@Lootid,3,5,1,0,-24003,1), -- Outland Grey Item Reference3
+(@Lootid,4,5,1,0,-24011,1), -- Outland Grey Item Reference4
+(@Lootid,5,5,1,0,-24022,1), -- Outland Grey Item Reference5
+(@Lootid,6,5,1,0,-24023,1), -- Outland Grey Item Reference6
+-- specifics
+(@Lootid,5759,0.25,1,0,1,1), -- Thorium Lockbox
+(@Lootid,5760,0.30,1,0,1,1), -- Eternium Lockbox
+-- Scrolls
+(@Lootid,7,5,1,0,-24724,1); -- Scroll of <stat> IV
+
+-- -------------------------------------------
+-- -- Hellfire Citadel: The Shattered Halls --
+-- -------------------------------------------
+SET @Lootid := 16507;
+UPDATE `creature_template` SET `lootid`=@Lootid WHERE `entry` IN (17669,16507,17622,17462,17427,17420,17083,16699,16704,17695,17670,16700,16593,16594,17464,17694,17465,17461,17671,20593,20582,20576,20590,20589,20594,20567,20587,20579,20581,20595,20586,20583,20578,20574,20588,20584,20577,20580);
+
+DELETE FROM `creature_loot_template` WHERE `entry` IN (16507,16593,16594,16699,16700,16704,17083,17420,17427,17461,17462,17464,17465,17669,17670,17671,17694,17695,17669,16594,17694,17427,17695,17461,16593,17465,17671,17464,17420,17670,16700,16699,16507,16704,17462);
+INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+(@Lootid,21877,40,1,0,2,3), -- Netherweave Cloth
+(@Lootid,27854,20,1,0,1,1), -- Smoked Talbuk Venison
+(@Lootid,27860,20,1,0,1,1), -- Purified Draenic Water
+(@Lootid,31952,2.5,1,0,1,1), -- Khorium Lockbox
+-- references
+(@Lootid,1,5,1,1,-24002,1), -- Outland Grey Item Reference1
+(@Lootid,2,2,1,1,-24009,1), -- Outland Green Reference1
+(@Lootid,3,5,1,1,-24011,1), -- Outland Grey Item Reference2
+(@Lootid,4,1,1,1,-24012,1), -- Outland Blue Reference1
+(@Lootid,5,5,1,1,-24093,1), -- Outland Plans & patterns
+-- Scrolls
+(@Lootid,6,5,1,0,-24724,1); -- Scroll of <stat> IV
diff --git a/sql/updates/world/2012_02_21_01_world_conditions.sql b/sql/updates/world/2012_02_21_01_world_conditions.sql
new file mode 100644
index 00000000000..54685868186
--- /dev/null
+++ b/sql/updates/world/2012_02_21_01_world_conditions.sql
@@ -0,0 +1,3592 @@
+CREATE TABLE `temp_convert_spells`
+(
+ `id` INT(11),
+ `effMask` INT(11),
+ `onlyPlayers` TINYINT(3),
+ PRIMARY KEY (`id`)
+);
+
+INSERT INTO `temp_convert_spells` VALUES
+(46174,1,0),
+(78002,1,1),
+(78001,1,1),
+(78000,1,1),
+(77999,1,1),
+(77984,1,1),
+(76379,1,0),
+(76098,1,0),
+(76092,1,0),
+(75920,1,1),
+(75767,1,1),
+(75765,1,1),
+(75396,1,0),
+(75389,1,1),
+(75364,1,0),
+(75319,1,0),
+(75313,1,0),
+(75244,1,0),
+(75197,1,0),
+(75195,1,0),
+(75181,1,0),
+(75107,1,0),
+(75100,1,0),
+(75078,1,0),
+(75053,1,0),
+(75018,1,0),
+(74977,1,0),
+(74903,1,0),
+(74801,1,1),
+(74758,1,0),
+(74735,1,0),
+(74549,1,0),
+(74548,1,0),
+(74486,1,0),
+(74455,1,0),
+(74444,1,0),
+(74313,1,0),
+(74285,1,0),
+(74219,1,0),
+(74182,1,0),
+(74148,1,0),
+(74098,1,0),
+(74090,1,1),
+(74086,1,1),
+(74074,1,0),
+(74033,1,0),
+(73980,1,0),
+(73955,1,0),
+(73953,1,0),
+(73886,1,0),
+(73846,1,1),
+(73845,1,1),
+(73844,1,1),
+(73843,1,1),
+(73837,1,0),
+(73836,1,0),
+(73835,1,0),
+(73787,1,0),
+(73786,1,0),
+(73785,1,0),
+(73725,1,0),
+(73659,1,0),
+(73650,1,1),
+(73582,1,0),
+(73556,1,0),
+(73555,1,0),
+(73548,1,0),
+(73331,1,1),
+(73288,1,0),
+(73165,1,0),
+(73164,1,1),
+(73159,1,1),
+(73129,1,0),
+(73128,1,0),
+(73082,1,0),
+(73071,1,0),
+(73035,1,0),
+(72959,1,1),
+(72934,1,1),
+(72928,1,1),
+(72900,1,1),
+(72830,1,1),
+(72748,1,0),
+(72747,1,0),
+(72746,1,0),
+(72745,1,0),
+(72728,1,0),
+(72706,1,1),
+(72618,1,0),
+(72595,1,1),
+(72527,1,0),
+(72479,1,1),
+(72431,1,1),
+(72429,1,1),
+(72401,1,0),
+(72347,1,0),
+(72346,1,1),
+(72280,1,0),
+(72279,1,0),
+(72278,1,0),
+(72262,1,0),
+(72260,1,0),
+(72257,1,1),
+(72209,1,0),
+(72202,1,0),
+(72099,1,0),
+(72033,1,0),
+(72032,1,0),
+(72031,1,0),
+(71952,1,0),
+(71949,1,1),
+(71948,1,0),
+(71946,1,0),
+(71848,1,0),
+(71811,1,0),
+(71809,1,0),
+(71753,1,1),
+(71693,1,0),
+(71620,1,0),
+(71617,1,0),
+(71599,1,0),
+(71538,1,1),
+(71536,1,1),
+(71520,1,0),
+(71440,1,0),
+(71415,1,0),
+(71412,1,0),
+(71365,1,0),
+(71352,1,1),
+(71322,1,0),
+(71310,1,0),
+(71308,1,0),
+(71306,1,0),
+(71281,1,0),
+(71272,1,0),
+(71189,1,0),
+(71082,1,0),
+(71081,1,0),
+(71080,1,0),
+(71079,1,0),
+(71078,1,0),
+(71075,1,0),
+(71070,1,0),
+(71032,1,0),
+(71024,1,0),
+(70995,1,0),
+(70983,1,0),
+(70966,1,1),
+(70939,1,0),
+(70936,1,0),
+(70933,1,0),
+(70931,1,0),
+(70921,1,0),
+(70881,1,0),
+(70861,1,0),
+(70860,1,0),
+(70859,1,0),
+(70858,1,0),
+(70857,1,0),
+(70856,1,0),
+(70792,1,0),
+(70790,1,0),
+(70784,1,0),
+(70781,1,0),
+(70743,1,0),
+(70713,1,1),
+(70643,1,0),
+(70639,1,0),
+(70638,1,1),
+(70636,1,1),
+(70635,1,0),
+(70623,1,1),
+(70614,1,0),
+(70611,1,0),
+(70602,1,0),
+(70595,1,0),
+(70588,1,0),
+(70586,1,0),
+(70572,1,0),
+(70569,1,0),
+(70527,1,1),
+(70525,1,0),
+(70488,1,0),
+(70485,1,0),
+(70471,1,0),
+(70466,1,0),
+(70464,1,0),
+(70444,1,0),
+(70443,1,1),
+(70403,1,0),
+(70397,1,0),
+(70383,1,0),
+(70374,1,0),
+(70366,1,0),
+(70360,1,0),
+(70338,1,0),
+(70331,1,1),
+(70299,1,0),
+(70293,1,0),
+(70290,1,0),
+(70267,1,0),
+(70266,1,0),
+(70265,1,0),
+(70246,1,0),
+(70225,1,0),
+(70224,1,0),
+(70143,1,0),
+(70130,1,0),
+(70104,1,0),
+(70100,1,0),
+(70098,1,0),
+(70079,1,0),
+(70078,1,0),
+(70053,1,0),
+(70041,1,0),
+(70040,1,0),
+(70021,1,0),
+(69960,1,0),
+(69959,1,0),
+(69922,1,0),
+(69907,1,0),
+(69886,1,0),
+(69857,1,0),
+(69843,1,0),
+(69801,1,0),
+(69798,1,0),
+(69796,1,0),
+(69784,1,0),
+(69782,1,0),
+(69768,1,0),
+(69753,1,0),
+(69705,1,0),
+(69682,1,0),
+(69614,1,0),
+(69610,1,0),
+(69601,1,0),
+(69600,1,0),
+(69593,1,0),
+(69553,1,0),
+(69538,1,0),
+(69508,1,0),
+(69431,1,0),
+(69372,1,0),
+(69347,1,0),
+(69298,1,1),
+(69171,1,0),
+(69125,1,0),
+(69101,1,0),
+(69098,1,0),
+(69097,1,0),
+(69048,1,1),
+(69039,1,0),
+(69016,1,0),
+(68957,1,0),
+(68922,1,0),
+(68919,1,0),
+(68901,1,0),
+(68881,1,0),
+(68880,1,0),
+(68861,1,0),
+(68847,1,0),
+(68842,1,0),
+(68798,1,0),
+(68663,1,0),
+(68644,1,0),
+(68617,1,0),
+(68616,1,0),
+(68614,1,0),
+(68515,1,1),
+(68471,1,1),
+(68470,1,1),
+(68401,1,0),
+(68400,1,0),
+(68360,1,0),
+(68359,1,0),
+(68358,1,0),
+(68206,1,1),
+(68198,1,1),
+(68197,1,1),
+(68193,1,1),
+(68186,1,1),
+(67888,1,0),
+(67864,1,0),
+(67857,1,0),
+(67856,1,0),
+(67855,1,0),
+(67804,1,0),
+(67757,1,0),
+(67756,1,0),
+(67755,1,0),
+(67748,1,0),
+(67732,1,0),
+(67715,1,0),
+(67705,1,0),
+(67551,1,1),
+(67547,1,0),
+(67482,1,0),
+(67400,1,0),
+(67397,1,0),
+(67369,1,0),
+(67335,1,0),
+(67328,1,0),
+(67163,1,0),
+(67162,1,0),
+(67161,1,0),
+(67160,1,0),
+(67159,1,0),
+(67158,1,0),
+(66986,1,1),
+(66810,1,1),
+(66798,1,0),
+(66785,1,0),
+(66774,1,0),
+(66718,1,1),
+(66665,1,0),
+(66637,1,0),
+(66636,1,0),
+(66630,1,0),
+(66551,1,0),
+(66550,1,0),
+(66513,1,0),
+(66512,1,0),
+(66508,1,0),
+(66401,1,0),
+(66391,1,0),
+(66390,1,0),
+(66387,1,0),
+(66386,1,0),
+(66385,1,0),
+(66384,1,0),
+(66383,1,0),
+(66382,1,0),
+(66379,1,0),
+(66357,1,0),
+(66356,1,0),
+(66355,1,0),
+(66354,1,0),
+(66353,1,0),
+(66352,1,0),
+(66350,1,0),
+(66349,1,0),
+(66348,1,0),
+(66345,1,0),
+(66339,1,0),
+(66332,1,0),
+(66314,1,1),
+(66312,1,1),
+(66287,1,0),
+(66256,1,0),
+(66193,1,0),
+(66181,1,0),
+(66153,1,0),
+(66152,1,0),
+(66141,1,0),
+(66140,1,0),
+(66135,1,1),
+(66133,1,0),
+(66132,1,0),
+(65872,1,0),
+(65861,1,0),
+(65719,1,0),
+(65718,1,0),
+(65699,1,0),
+(65685,1,0),
+(65652,1,0),
+(65614,1,0),
+(65613,1,0),
+(65611,1,0),
+(65594,1,1),
+(65589,1,0),
+(65588,1,0),
+(65587,1,0),
+(65509,1,0),
+(65357,1,0),
+(65354,1,0),
+(65350,1,0),
+(65349,1,0),
+(65346,1,1),
+(65312,1,1),
+(65311,1,1),
+(65265,1,0),
+(65258,1,0),
+(65238,1,0),
+(65224,1,0),
+(65206,1,0),
+(65200,1,0),
+(65192,1,0),
+(65184,1,1),
+(65140,1,0),
+(65109,1,0),
+(65061,1,0),
+(65042,1,0),
+(65040,1,1),
+(65034,1,0),
+(65016,1,0),
+(65015,1,0),
+(64996,1,0),
+(64995,1,0),
+(64898,1,0),
+(64887,1,0),
+(64886,1,0),
+(64880,1,0),
+(64828,1,0),
+(64799,1,0),
+(64767,1,0),
+(64623,1,0),
+(64620,1,0),
+(64619,1,0),
+(64618,1,0),
+(64597,1,0),
+(64543,1,0),
+(64539,1,0),
+(64503,1,0),
+(64499,1,0),
+(64480,1,0),
+(64475,1,0),
+(64474,1,0),
+(64466,1,0),
+(64465,1,0),
+(64463,1,0),
+(64449,1,0),
+(64444,1,0),
+(64425,1,0),
+(64414,1,0),
+(64402,1,0),
+(64397,1,0),
+(64320,1,0),
+(64229,1,0),
+(64225,1,0),
+(64224,1,0),
+(64201,1,0),
+(64185,1,0),
+(64184,1,0),
+(64183,1,0),
+(64173,1,0),
+(64172,1,0),
+(64098,1,0),
+(64069,1,0),
+(64063,1,0),
+(64061,1,0),
+(64059,1,1),
+(64032,1,0),
+(64031,1,0),
+(64030,1,0),
+(64029,1,0),
+(64028,1,0),
+(64027,1,0),
+(64026,1,0),
+(64025,1,0),
+(64024,1,0),
+(64014,1,0),
+(63984,1,0),
+(63979,1,0),
+(63947,1,0),
+(63886,1,0),
+(63882,1,0),
+(63820,1,0),
+(63813,1,0),
+(63812,1,0),
+(63764,1,0),
+(63763,1,0),
+(63762,1,0),
+(63761,1,0),
+(63749,1,0),
+(63747,1,1),
+(63745,1,1),
+(63744,1,0),
+(63702,1,0),
+(63676,1,0),
+(63659,1,0),
+(63658,1,0),
+(63657,1,0),
+(63629,1,0),
+(63628,1,0),
+(63576,1,0),
+(63524,1,0),
+(63499,1,0),
+(63446,1,0),
+(63445,1,0),
+(63444,1,0),
+(63443,1,0),
+(63442,1,0),
+(63441,1,0),
+(63440,1,0),
+(63439,1,0),
+(63438,1,0),
+(63352,1,0),
+(63348,1,0),
+(63322,1,1),
+(63274,1,0),
+(63255,1,0),
+(63238,1,0),
+(63109,1,0),
+(63037,1,0),
+(63013,1,0),
+(63001,1,0),
+(62990,1,0),
+(62978,1,0),
+(62976,1,0),
+(62943,1,0),
+(62911,1,0),
+(62909,1,0),
+(62906,1,0),
+(62888,1,0),
+(62883,1,0),
+(62882,1,0),
+(62834,1,0),
+(62809,1,0),
+(62797,1,1),
+(62778,1,0),
+(62731,1,0),
+(62727,1,0),
+(62711,1,0),
+(62708,1,0),
+(62706,1,0),
+(62701,1,0),
+(62669,1,0),
+(62646,1,0),
+(62603,1,0),
+(62584,1,0),
+(62577,1,0),
+(62567,1,0),
+(62533,1,0),
+(62525,1,0),
+(62524,1,0),
+(62521,1,0),
+(62509,1,0),
+(62505,1,0),
+(62496,1,0),
+(62488,1,0),
+(62485,1,0),
+(62484,1,0),
+(62483,1,0),
+(62480,1,0),
+(62464,1,0),
+(62378,1,0),
+(124,1,0),
+(2222,1,0),
+(3730,1,0),
+(4020,1,0),
+(4338,1,0),
+(5249,1,0),
+(5251,1,0),
+(5432,1,0),
+(5555,1,0),
+(6636,1,0),
+(6672,1,0),
+(6755,1,0),
+(6955,1,0),
+(6967,1,0),
+(7022,1,0),
+(7035,1,0),
+(7036,1,0),
+(7277,1,0),
+(7393,1,0),
+(7670,1,0),
+(7769,1,0),
+(8283,1,0),
+(8593,1,0),
+(8596,1,0),
+(9002,1,0),
+(9003,1,0),
+(9004,1,0),
+(9012,1,0),
+(9082,1,0),
+(9095,1,0),
+(9455,1,0),
+(9457,1,0),
+(9712,1,0),
+(9976,1,0),
+(10113,1,0),
+(10137,1,0),
+(10252,1,0),
+(10258,1,0),
+(10259,1,0),
+(10260,1,0),
+(10345,1,0),
+(10604,1,0),
+(10727,1,0),
+(10747,1,0),
+(11195,1,0),
+(11402,1,0),
+(11440,1,0),
+(11513,1,0),
+(11637,1,0),
+(11757,1,0),
+(11893,1,0),
+(12134,1,0),
+(12158,1,0),
+(12159,1,0),
+(12347,1,0),
+(12512,1,0),
+(12564,1,0),
+(12613,1,0),
+(12623,1,0),
+(12699,1,0),
+(12709,1,0),
+(12774,1,0),
+(12938,1,0),
+(13461,1,0),
+(13727,1,0),
+(13821,1,0),
+(13951,1,0),
+(13982,1,0),
+(14250,1,0),
+(14292,1,0),
+(14806,1,0),
+(14813,1,0),
+(14928,1,0),
+(15252,1,0),
+(15281,1,0),
+(15591,1,0),
+(15658,1,0),
+(15746,1,0),
+(15958,1,0),
+(16007,1,0),
+(16032,1,0),
+(16037,1,0),
+(16053,1,0),
+(16068,1,0),
+(16069,1,0),
+(16070,1,0),
+(16074,1,0),
+(16378,1,0),
+(16381,1,0),
+(16404,1,0),
+(16556,1,0),
+(16558,1,0),
+(16637,1,0),
+(16786,1,0),
+(16807,1,0),
+(17048,1,0),
+(17166,1,0),
+(17190,1,0),
+(17202,1,0),
+(17272,1,0),
+(17278,1,0),
+(17279,1,0),
+(17471,1,0),
+(17536,1,0),
+(17616,1,0),
+(17618,1,0),
+(17652,1,0),
+(17671,1,0),
+(17675,1,0),
+(17676,1,0),
+(17677,1,0),
+(17678,1,0),
+(17698,1,0),
+(17748,1,0),
+(18110,1,0),
+(18655,1,0),
+(18666,1,0),
+(18811,1,0),
+(18969,1,0),
+(19032,1,0),
+(19096,1,0),
+(19571,1,0),
+(19593,1,0),
+(19721,1,0),
+(19749,1,0),
+(19770,1,0),
+(19773,1,0),
+(19952,1,0),
+(20358,1,0),
+(20465,1,0),
+(20619,1,0),
+(21052,1,0),
+(21075,1,0),
+(21076,1,0),
+(21391,1,0),
+(21556,1,0),
+(21566,1,0),
+(21885,1,0),
+(21950,1,0),
+(22096,1,0),
+(22203,1,0),
+(22205,1,0),
+(22393,1,0),
+(22458,1,0),
+(22860,1,0),
+(22906,1,0),
+(22966,1,0),
+(23014,1,0),
+(23016,1,0),
+(23018,1,0),
+(23019,1,0),
+(23168,1,0),
+(23328,1,0),
+(23360,1,0),
+(23389,1,0),
+(23394,1,0),
+(23415,1,0),
+(23642,1,0),
+(23951,1,0),
+(23974,1,0),
+(24062,1,0),
+(24083,1,0),
+(24172,1,0),
+(24207,1,0),
+(24217,1,0),
+(24311,1,0),
+(24322,1,0),
+(24323,1,0),
+(24391,1,0),
+(24734,1,0),
+(24744,1,0),
+(24756,1,0),
+(24758,1,0),
+(24760,1,0),
+(24763,1,0),
+(24765,1,0),
+(24768,1,0),
+(24770,1,0),
+(24772,1,0),
+(24784,1,0),
+(24786,1,0),
+(24788,1,0),
+(24789,1,0),
+(24790,1,0),
+(24804,1,0),
+(24933,1,0),
+(25030,1,0),
+(25031,1,0),
+(25032,1,0),
+(25099,1,0),
+(25145,1,0),
+(25149,1,0),
+(25150,1,0),
+(25158,1,0),
+(25201,1,0),
+(25715,1,0),
+(25727,1,0),
+(25745,1,0),
+(25822,1,0),
+(25823,1,0),
+(25896,1,0),
+(26235,1,0),
+(26344,1,0),
+(26345,1,0),
+(26346,1,0),
+(26347,1,0),
+(26348,1,0),
+(26349,1,0),
+(26351,1,0),
+(26352,1,0),
+(26353,1,0),
+(26354,1,0),
+(26355,1,0),
+(26356,1,0),
+(26462,1,0),
+(26522,1,1),
+(26608,1,0),
+(26687,1,1),
+(26879,1,0),
+(27583,1,0),
+(27651,1,0),
+(27663,1,0),
+(27745,1,0),
+(27885,1,0),
+(27886,1,0),
+(27892,1,0),
+(27893,1,0),
+(27894,1,0),
+(27928,1,0),
+(27929,1,0),
+(27935,1,0),
+(27936,1,0),
+(28018,1,0),
+(28032,1,0),
+(28056,1,0),
+(28078,1,0),
+(28087,1,0),
+(28096,1,0),
+(28111,1,0),
+(28159,1,0),
+(28278,1,0),
+(28281,1,0),
+(28309,1,0),
+(28326,1,0),
+(28338,1,0),
+(28339,1,0),
+(28365,1,0),
+(28366,1,0),
+(28367,1,0),
+(28374,1,0),
+(28392,1,0),
+(28404,1,0),
+(28441,1,0),
+(28605,1,0),
+(28697,1,0),
+(28731,1,0),
+(28732,1,0),
+(28861,1,0),
+(29070,1,0),
+(29072,1,0),
+(29120,1,0),
+(29121,1,0),
+(29122,1,0),
+(29172,1,0),
+(29173,1,0),
+(29176,1,0),
+(29328,1,1),
+(29339,1,0),
+(29340,1,0),
+(29428,1,0),
+(29437,1,0),
+(29456,1,0),
+(29457,1,0),
+(29458,1,0),
+(29459,1,0),
+(29461,1,0),
+(29531,1,0),
+(29534,1,0),
+(29612,1,0),
+(29705,1,0),
+(29726,1,0),
+(29727,1,0),
+(29769,1,0),
+(29770,1,0),
+(29846,1,1),
+(29962,1,0),
+(29966,1,0),
+(29967,1,0),
+(29969,1,0),
+(29970,1,0),
+(29972,1,0),
+(29989,1,0),
+(30012,1,0),
+(30065,1,0),
+(30107,1,0),
+(30166,1,0),
+(30207,1,0),
+(30221,1,0),
+(30232,1,0),
+(30273,1,0),
+(30410,1,0),
+(30417,1,0),
+(30418,1,0),
+(30425,1,0),
+(30427,1,0),
+(30460,1,0),
+(30462,1,0),
+(30469,1,0),
+(30477,1,0),
+(30541,1,0),
+(30544,1,0),
+(30571,1,1),
+(30572,1,0),
+(30625,1,0),
+(30631,1,1),
+(30656,1,0),
+(30662,1,0),
+(30676,1,0),
+(30690,1,0),
+(30735,1,0),
+(30738,1,0),
+(30745,1,0),
+(30751,1,0),
+(30762,1,0),
+(30763,1,0),
+(30764,1,0),
+(30765,1,0),
+(30766,1,0),
+(30834,1,0),
+(30835,1,0),
+(30875,1,0),
+(30876,1,0),
+(30951,1,0),
+(30952,1,0),
+(30964,1,0),
+(30968,1,0),
+(30970,1,0),
+(30974,1,0),
+(30985,1,0),
+(30988,1,0),
+(31115,1,0),
+(31225,1,0),
+(31315,1,0),
+(31324,1,0),
+(31326,1,0),
+(31329,1,0),
+(31336,1,0),
+(31346,1,0),
+(31411,1,0),
+(31412,1,0),
+(31413,1,0),
+(31414,1,0),
+(31474,1,0),
+(31515,1,0),
+(31532,1,0),
+(31537,1,0),
+(31550,1,0),
+(31611,1,0),
+(31628,1,0),
+(31630,1,0),
+(31631,1,0),
+(31702,1,0),
+(31727,1,0),
+(31736,1,0),
+(31749,1,0),
+(31781,1,0),
+(31793,1,0),
+(31799,1,0),
+(31806,1,0),
+(31889,1,0),
+(31902,1,0),
+(31936,1,0),
+(31979,1,0),
+(31993,1,0),
+(32040,1,0),
+(32042,1,0),
+(32045,1,0),
+(32051,1,0),
+(32052,1,0),
+(32087,1,0),
+(32111,1,0),
+(32127,1,0),
+(32146,1,0),
+(32163,1,0),
+(32164,1,0),
+(32227,1,0),
+(32228,1,0),
+(32251,1,0),
+(32260,1,0),
+(32286,1,0),
+(32301,1,0),
+(32303,1,0),
+(32312,1,0),
+(32373,1,0),
+(32396,1,0),
+(32560,1,0),
+(32573,1,0),
+(32589,1,0),
+(32622,1,0),
+(32623,1,0),
+(32638,1,0),
+(32668,1,0),
+(32708,1,1),
+(32760,1,0),
+(32838,1,0),
+(32890,1,0),
+(32928,1,0),
+(32929,1,0),
+(32930,1,0),
+(32953,1,0),
+(32958,1,0),
+(32974,1,0),
+(32976,1,0),
+(32979,1,0),
+(33067,1,0),
+(33270,1,1),
+(33329,1,0),
+(33332,1,0),
+(33336,1,0),
+(33337,1,0),
+(33423,1,0),
+(33424,1,0),
+(33425,1,0),
+(33531,1,0),
+(33532,1,0),
+(33618,1,0),
+(33644,1,0),
+(33655,1,0),
+(33669,1,0),
+(33710,1,0),
+(33716,1,1),
+(33742,1,0),
+(33744,1,0),
+(33796,1,0),
+(33805,1,0),
+(33806,1,0),
+(33809,1,0),
+(33822,1,0),
+(33831,1,0),
+(33838,1,0),
+(33861,1,0),
+(33862,1,0),
+(33918,1,0),
+(33924,1,0),
+(33937,1,0),
+(33981,1,0),
+(34011,1,0),
+(34013,1,0),
+(34016,1,0),
+(34019,1,0),
+(34023,1,0),
+(34024,1,0),
+(34062,1,0),
+(34063,1,0),
+(34076,1,0),
+(34119,1,0),
+(34154,1,0),
+(34156,1,0),
+(34209,1,0),
+(34211,1,0),
+(34212,1,0),
+(34221,1,0),
+(34239,1,0),
+(34254,1,0),
+(34330,1,0),
+(34332,1,0),
+(34367,1,0),
+(34378,1,0),
+(34393,1,0),
+(34397,1,0),
+(34430,1,0),
+(34516,1,0),
+(34526,1,0),
+(34536,1,0),
+(34581,1,0),
+(34583,1,0),
+(34613,1,0),
+(34627,1,0),
+(34646,1,0),
+(34662,1,0),
+(34742,1,0),
+(34806,1,0),
+(34874,1,0),
+(34893,1,0),
+(34946,1,0),
+(35016,1,0),
+(35040,1,0),
+(35063,1,0),
+(35097,1,0),
+(35113,1,0),
+(35137,1,0),
+(35140,1,0),
+(35141,1,0),
+(35155,1,0),
+(35160,1,0),
+(35162,1,0),
+(35170,1,0),
+(35176,1,0),
+(35190,1,0),
+(35245,1,0),
+(35262,1,0),
+(35282,1,0),
+(35301,1,0),
+(35372,1,0),
+(35413,1,0),
+(35427,1,0),
+(35515,1,0),
+(35516,1,0),
+(35598,1,0),
+(35600,1,0),
+(35673,1,0),
+(35682,1,0),
+(35724,1,0),
+(35746,1,0),
+(35756,1,0),
+(35770,1,0),
+(35771,1,0),
+(35772,1,0),
+(35782,1,0),
+(35930,1,0),
+(35941,1,1),
+(35956,1,1),
+(35960,1,0),
+(35961,1,0),
+(35962,1,0),
+(36000,1,0),
+(36035,1,0),
+(36089,1,0),
+(36090,1,0),
+(36103,1,0),
+(36167,1,0),
+(36174,1,0),
+(36196,1,0),
+(36197,1,0),
+(36198,1,0),
+(36201,1,0),
+(36220,1,0),
+(36239,1,0),
+(36241,1,0),
+(36243,1,0),
+(36290,1,0),
+(36291,1,0),
+(36293,1,0),
+(36327,1,0),
+(36330,1,0),
+(36378,1,0),
+(36384,1,0),
+(36431,1,0),
+(36452,1,0),
+(36455,1,1),
+(36456,1,0),
+(36514,1,0),
+(36544,1,0),
+(36639,1,0),
+(36651,1,0),
+(36652,1,0),
+(36692,1,0),
+(36709,1,0),
+(36717,1,1),
+(36779,1,0),
+(36795,1,0),
+(36802,1,0),
+(36803,1,0),
+(36804,1,0),
+(36823,1,0),
+(36852,1,0),
+(36854,1,0),
+(36856,1,0),
+(36857,1,0),
+(36858,1,0),
+(36859,1,0),
+(36871,1,0),
+(36878,1,0),
+(36884,1,0),
+(36896,1,0),
+(36951,1,0),
+(36953,1,0),
+(36969,1,0),
+(36995,1,0),
+(37013,1,0),
+(37017,1,0),
+(37032,1,0),
+(37033,1,0),
+(37034,1,0),
+(37035,1,0),
+(37051,1,0),
+(37052,1,0),
+(37053,1,0),
+(37055,1,0),
+(37056,1,0),
+(37071,1,0),
+(37072,1,0),
+(37103,1,0),
+(37142,1,0),
+(37143,1,0),
+(37144,1,0),
+(37146,1,0),
+(37147,1,0),
+(37148,1,0),
+(37149,1,0),
+(37150,1,0),
+(37151,1,0),
+(37152,1,0),
+(37153,1,0),
+(37199,1,0),
+(37220,1,0),
+(37226,1,0),
+(37229,1,0),
+(37235,1,0),
+(37281,1,0),
+(37285,1,0),
+(37337,1,0),
+(37339,1,0),
+(37345,1,0),
+(37348,1,0),
+(37388,1,0),
+(37406,1,0),
+(37408,1,1),
+(37413,1,0),
+(37422,1,0),
+(37427,1,0),
+(37428,1,0),
+(37448,1,1),
+(37449,1,1),
+(37453,1,0),
+(37454,1,0),
+(37459,1,0),
+(37461,1,0),
+(37465,1,0),
+(37469,1,0),
+(37471,1,0),
+(37472,1,0),
+(37474,1,0),
+(37476,1,0),
+(37498,1,0),
+(37502,1,0),
+(37573,1,0),
+(37626,1,0),
+(37645,1,0),
+(37689,1,0),
+(37697,1,0),
+(37712,1,0),
+(37720,1,0),
+(37748,1,0),
+(37755,1,0),
+(37775,1,0),
+(37784,1,0),
+(37824,1,0),
+(37842,1,0),
+(37843,1,0),
+(37848,1,0),
+(37849,1,1),
+(37853,1,0),
+(37868,1,0),
+(37893,1,0),
+(37895,1,0),
+(37918,1,0),
+(37934,1,0),
+(37936,1,0),
+(37964,1,0),
+(37984,1,0),
+(38003,1,0),
+(38014,1,0),
+(38015,1,0),
+(38017,1,0),
+(38020,1,0),
+(38053,1,0),
+(38054,1,0),
+(38072,1,0),
+(38073,1,0),
+(38112,1,0),
+(38121,1,0),
+(38123,1,0),
+(38126,1,0),
+(38128,1,0),
+(38130,1,0),
+(38202,1,0),
+(38250,1,0),
+(38269,1,0),
+(38360,1,0),
+(38444,1,0),
+(38451,1,0),
+(38452,1,0),
+(38455,1,0),
+(38469,1,0),
+(38482,1,0),
+(38508,1,0),
+(38530,1,0),
+(38629,1,0),
+(38632,1,0),
+(38691,1,0),
+(38711,1,0),
+(38722,1,0),
+(38736,1,0),
+(38738,1,0),
+(38762,1,0),
+(38802,1,0),
+(38829,1,1),
+(38966,1,0),
+(38968,1,0),
+(39010,1,0),
+(39011,1,0),
+(39043,1,0),
+(39073,1,0),
+(39094,1,0),
+(39124,1,0),
+(39126,1,0),
+(39140,1,0),
+(39141,1,0),
+(39184,1,0),
+(39185,1,0),
+(39189,1,0),
+(39190,1,0),
+(39206,1,0),
+(39211,1,0),
+(39216,1,0),
+(39219,1,0),
+(39221,1,0),
+(39248,1,0),
+(39334,1,0),
+(39335,1,0),
+(39338,1,0),
+(39341,1,0),
+(39342,1,0),
+(39344,1,0),
+(39350,1,0),
+(39352,1,0),
+(39353,1,0),
+(39354,1,0),
+(39355,1,0),
+(39356,1,0),
+(39357,1,0),
+(39358,1,0),
+(39359,1,0),
+(39360,1,0),
+(39361,1,0),
+(39362,1,0),
+(39395,1,0),
+(39495,1,0),
+(39497,1,1),
+(39552,1,0),
+(39559,1,0),
+(39583,1,0),
+(39601,1,0),
+(39635,1,0),
+(39678,1,0),
+(39687,1,0),
+(39690,1,0),
+(39691,1,0),
+(39692,1,0),
+(39696,1,0),
+(39758,1,0),
+(39834,1,1),
+(39849,1,0),
+(39851,1,1),
+(39852,1,1),
+(39853,1,1),
+(39854,1,1),
+(39873,1,0),
+(39899,1,0),
+(39914,1,0),
+(39915,1,0),
+(39919,1,0),
+(39921,1,0),
+(39923,1,1),
+(39930,1,0),
+(39938,1,0),
+(39939,1,0),
+(39940,1,0),
+(39974,1,0),
+(39977,1,0),
+(39978,1,0),
+(39985,1,0),
+(39989,1,0),
+(39993,1,0),
+(39999,1,0),
+(40085,1,0),
+(40094,1,0),
+(40106,1,0),
+(40110,1,0),
+(40112,1,1),
+(40136,1,0),
+(40147,1,0),
+(40153,1,0),
+(40156,1,0),
+(40160,1,0),
+(40187,1,0),
+(40189,1,0),
+(40190,1,0),
+(40224,1,0),
+(40281,1,0),
+(40287,1,0),
+(40288,1,0),
+(40289,1,0),
+(40309,1,0),
+(40350,1,0),
+(40359,1,0),
+(40382,1,0),
+(40383,1,0),
+(40397,1,0),
+(40437,1,0),
+(40439,1,0),
+(40454,1,0),
+(40490,1,0),
+(40494,1,0),
+(40498,1,0),
+(40499,1,0),
+(40512,1,0),
+(40520,1,0),
+(40521,1,0),
+(40523,1,0),
+(40532,1,0),
+(40547,1,0),
+(40607,1,0),
+(40638,1,0),
+(40693,1,0),
+(40704,1,0),
+(40707,1,0),
+(40708,1,0),
+(40709,1,0),
+(40710,1,0),
+(40711,1,0),
+(40712,1,0),
+(40713,1,0),
+(40715,1,0),
+(40730,1,1),
+(40738,1,0),
+(40750,1,0),
+(40761,1,0),
+(40788,1,0),
+(40821,1,0),
+(40824,1,0),
+(40825,1,0),
+(40828,1,0),
+(40830,1,0),
+(40848,1,1),
+(40874,1,0),
+(40887,1,0),
+(40978,1,0),
+(40985,1,1),
+(40989,1,0),
+(40993,1,1),
+(41007,1,1),
+(41015,1,1),
+(41022,1,1),
+(41073,1,0),
+(41077,1,0),
+(41122,1,0),
+(41124,1,0),
+(41125,1,0),
+(41128,1,0),
+(41129,1,0),
+(41154,1,0),
+(41257,1,0),
+(41268,1,0),
+(41269,1,0),
+(41271,1,0),
+(41285,1,1),
+(41295,1,0),
+(41333,1,0),
+(41342,1,0),
+(41343,1,0),
+(41344,1,0),
+(41362,1,0),
+(41455,1,0),
+(41457,1,0),
+(41477,1,0),
+(41499,1,0),
+(41522,1,0),
+(41525,1,0),
+(41537,1,0),
+(41557,1,0),
+(41560,1,0),
+(41575,1,0),
+(41602,1,0),
+(41614,1,0),
+(41624,1,1),
+(41975,1,0),
+(41976,1,0),
+(41993,1,0),
+(42008,1,0),
+(42014,1,0),
+(42138,1,1),
+(42143,1,0),
+(42151,1,0),
+(42166,1,0),
+(42167,1,0),
+(42168,1,0),
+(42178,1,0),
+(42219,1,0),
+(42222,1,0),
+(42247,1,0),
+(42269,1,0),
+(42271,1,0),
+(42272,1,0),
+(42289,1,0),
+(42317,1,0),
+(42318,1,0),
+(42321,1,0),
+(42339,1,0),
+(42341,1,0),
+(42352,1,0),
+(42356,1,0),
+(42391,1,0),
+(42393,1,0),
+(42405,1,0),
+(42410,1,0),
+(42415,1,0),
+(42428,1,0),
+(42442,1,0),
+(42447,1,0),
+(42454,1,0),
+(42471,1,0),
+(42473,1,0),
+(42482,1,0),
+(42484,1,0),
+(42515,1,0),
+(42517,1,0),
+(42530,1,0),
+(42534,1,0),
+(42536,1,0),
+(42542,1,0),
+(42550,1,0),
+(42564,1,0),
+(42567,1,0),
+(42570,1,0),
+(42577,1,0),
+(42585,1,0),
+(42604,1,0),
+(42605,1,0),
+(42616,1,0),
+(42631,1,0),
+(42638,1,1),
+(42647,1,0),
+(42654,1,0),
+(42655,1,0),
+(42659,1,0),
+(42661,1,0),
+(42664,1,0),
+(42674,1,1),
+(42685,1,0),
+(42695,1,0),
+(42697,1,0),
+(42703,1,0),
+(42707,1,0),
+(42713,1,0),
+(42720,1,0),
+(42734,1,0),
+(42757,1,1),
+(42768,1,0),
+(42793,1,0),
+(42797,1,0),
+(42808,1,0),
+(42809,1,0),
+(42813,1,0),
+(42815,1,0),
+(42816,1,0),
+(42818,1,0),
+(42821,1,0),
+(42839,1,0),
+(42857,1,0),
+(42881,1,0),
+(42882,1,0),
+(42883,1,0),
+(42884,1,0),
+(42888,1,0),
+(42905,1,0),
+(42968,1,0),
+(42982,1,0),
+(43033,1,0),
+(43035,1,0),
+(43057,1,0),
+(43066,1,0),
+(43068,1,0),
+(43069,1,0),
+(43072,1,0),
+(43076,1,0),
+(43078,1,0),
+(43079,1,0),
+(43092,1,0),
+(43101,1,0),
+(43106,1,0),
+(43109,1,0),
+(43144,1,0),
+(43171,1,0),
+(43209,1,0),
+(43210,1,0),
+(43234,1,0),
+(43239,1,0),
+(43244,1,0),
+(43255,1,0),
+(43291,1,0),
+(43306,1,0),
+(43307,1,0),
+(43333,1,0),
+(43371,1,0),
+(43385,1,0),
+(43386,1,0),
+(43403,1,0),
+(43404,1,0),
+(43407,1,0),
+(43450,1,0),
+(43458,1,0),
+(43468,1,0),
+(43486,1,0),
+(43487,1,0),
+(43515,1,0),
+(43520,1,0),
+(43525,1,0),
+(43546,1,0),
+(43559,1,0),
+(43563,1,0),
+(43568,1,0),
+(43615,1,0),
+(43647,1,0),
+(43662,1,0),
+(43685,1,0),
+(43691,1,0),
+(43711,1,0),
+(43734,1,0),
+(43754,1,0),
+(43770,1,0),
+(43791,1,0),
+(43805,1,0),
+(43863,1,0),
+(43865,1,0),
+(43867,1,0),
+(43871,1,0),
+(43872,1,0),
+(43878,1,0),
+(43882,1,0),
+(43892,1,0),
+(43942,1,0),
+(43943,1,0),
+(43949,1,0),
+(43962,1,0),
+(43990,1,0),
+(43994,1,0),
+(44014,1,0),
+(44022,1,0),
+(44023,1,0),
+(44024,1,0),
+(44026,1,0),
+(44027,1,0),
+(44028,1,0),
+(44037,1,0),
+(44145,1,0),
+(44161,1,0),
+(44193,1,0),
+(44214,1,0),
+(44224,1,1),
+(44229,1,0),
+(44232,1,1),
+(44250,1,0),
+(44255,1,0),
+(44260,1,0),
+(44266,1,0),
+(44270,1,0),
+(44283,1,0),
+(44284,1,0),
+(44309,1,0),
+(44313,1,0),
+(44329,1,0),
+(44330,1,0),
+(44355,1,0),
+(44362,1,0),
+(44365,1,0),
+(44367,1,0),
+(44374,1,0),
+(44392,1,0),
+(44411,1,0),
+(44420,1,0),
+(44422,1,0),
+(44458,1,0),
+(44550,1,0),
+(44562,1,0),
+(44574,1,0),
+(44609,1,0),
+(44610,1,0),
+(44653,1,0),
+(44681,1,0),
+(44682,1,1),
+(44749,1,0),
+(44804,1,0),
+(44807,1,0),
+(44826,1,0),
+(44837,1,0),
+(44838,1,0),
+(44839,1,0),
+(44840,1,0),
+(44841,1,0),
+(44842,1,0),
+(44845,1,0),
+(44846,1,0),
+(44849,1,1),
+(44864,1,0),
+(44865,1,0),
+(44872,1,0),
+(44877,1,0),
+(44883,1,0),
+(44886,1,0),
+(44938,1,0),
+(44939,1,0),
+(44941,1,0),
+(44946,1,0),
+(44948,1,0),
+(44963,1,0),
+(44965,1,0),
+(44981,1,0),
+(45005,1,0),
+(45008,1,0),
+(45012,1,0),
+(45013,1,0),
+(45076,1,0),
+(45086,1,0),
+(45103,1,0),
+(45109,1,0),
+(45114,1,0),
+(45115,1,0),
+(45119,1,0),
+(45172,1,0),
+(45188,1,0),
+(45191,1,0),
+(45219,1,0),
+(45223,1,0),
+(45224,1,0),
+(45229,1,0),
+(45233,1,0),
+(45259,1,0),
+(45260,1,1),
+(45264,1,0),
+(45267,1,0),
+(45277,1,0),
+(45279,1,0),
+(45307,1,0),
+(45323,1,0),
+(45339,1,0),
+(45340,1,0),
+(45351,1,0),
+(45368,1,0),
+(45371,1,0),
+(45388,1,0),
+(45389,1,0),
+(45405,1,0),
+(45407,1,0),
+(45414,1,0),
+(45437,1,0),
+(45446,1,0),
+(45448,1,0),
+(45449,1,0),
+(45465,1,0),
+(45474,1,0),
+(45536,1,0),
+(45581,1,0),
+(45583,1,0),
+(45586,1,0),
+(45594,1,0),
+(45595,1,0),
+(45596,1,0),
+(45597,1,0),
+(45602,1,0),
+(45605,1,0),
+(45606,1,0),
+(45607,1,0),
+(45608,1,0),
+(45609,1,0),
+(45622,1,0),
+(45623,1,0),
+(45630,1,0),
+(45634,1,0),
+(45644,1,1),
+(45651,1,0),
+(45655,1,0),
+(45656,1,0),
+(45666,1,0),
+(45667,1,0),
+(45671,1,1),
+(45680,1,1),
+(45692,1,0),
+(45700,1,0),
+(45714,1,0),
+(45732,1,0),
+(45735,1,0),
+(45761,1,0),
+(45774,1,0),
+(45780,1,0),
+(45788,1,0),
+(45805,1,0),
+(45808,1,0),
+(45834,1,0),
+(45835,1,0),
+(45841,1,0),
+(45853,1,0),
+(45859,1,0),
+(45863,1,0),
+(45864,1,0),
+(45867,1,0),
+(45872,1,0),
+(45888,1,0),
+(45907,1,0),
+(45911,1,0),
+(45912,1,0),
+(45914,1,0),
+(45918,1,1),
+(45923,1,0),
+(45929,1,0),
+(45930,1,0),
+(45941,1,0),
+(45949,1,0),
+(45961,1,0),
+(45968,1,0),
+(45969,1,0),
+(45970,1,0),
+(45976,1,0),
+(45979,1,0),
+(45990,1,0),
+(45993,1,0),
+(46013,1,0),
+(46018,1,1),
+(46022,1,0),
+(46034,1,0),
+(46054,1,0),
+(46058,1,0),
+(46063,1,0),
+(46066,1,0),
+(46068,1,0),
+(46085,1,0),
+(46143,1,0),
+(46171,1,0),
+(46173,1,0),
+(62377,1,0),
+(46175,1,0),
+(46176,1,0),
+(46177,1,0),
+(46178,1,0),
+(46201,1,0),
+(46208,1,0),
+(46219,1,0),
+(46222,1,0),
+(46236,1,0),
+(46237,1,0),
+(46245,1,0),
+(46246,1,0),
+(46281,1,0),
+(46307,1,1),
+(46318,1,0),
+(46319,1,0),
+(46320,1,1),
+(46330,1,0),
+(46363,1,0),
+(46372,1,1),
+(46374,1,0),
+(46376,1,0),
+(46382,1,0),
+(46385,1,0),
+(46396,1,1),
+(46398,1,0),
+(46399,1,0),
+(46400,1,0),
+(46474,1,0),
+(46475,1,0),
+(46477,1,0),
+(46482,1,0),
+(46488,1,0),
+(46521,1,0),
+(46588,1,1),
+(46592,1,0),
+(46593,1,0),
+(46603,1,0),
+(46609,1,0),
+(46610,1,0),
+(46623,1,0),
+(46631,1,0),
+(46637,1,0),
+(46650,1,0),
+(46652,1,0),
+(46656,1,0),
+(46685,1,0),
+(46692,1,0),
+(46694,1,0),
+(46704,1,0),
+(46707,1,0),
+(46732,1,1),
+(46733,1,0),
+(46735,1,0),
+(46747,1,0),
+(46793,1,0),
+(46797,1,0),
+(46809,1,0),
+(46815,1,0),
+(46818,1,0),
+(46820,1,0),
+(46843,1,0),
+(46886,1,0),
+(46895,1,0),
+(46900,1,0),
+(46902,1,0),
+(46903,1,0),
+(46904,1,0),
+(46936,1,0),
+(46937,1,0),
+(46963,1,0),
+(46964,1,0),
+(46965,1,1),
+(46974,1,0),
+(47016,1,0),
+(47026,1,0),
+(47035,1,0),
+(47060,1,0),
+(47065,1,0),
+(47104,1,0),
+(47110,1,0),
+(47137,1,0),
+(47170,1,0),
+(47176,1,0),
+(47184,1,0),
+(47214,1,0),
+(47253,1,0),
+(47254,1,0),
+(47336,1,0),
+(47344,1,0),
+(47370,1,1),
+(47374,1,0),
+(47378,1,0),
+(47421,1,0),
+(47452,1,0),
+(47460,1,0),
+(47463,1,0),
+(47469,1,0),
+(47542,1,0),
+(47547,1,0),
+(47563,1,0),
+(47574,1,0),
+(47593,1,0),
+(47594,1,0),
+(47596,1,0),
+(47597,1,0),
+(47598,1,0),
+(47599,1,0),
+(47616,1,0),
+(47617,1,0),
+(47618,1,0),
+(47619,1,0),
+(47634,1,0),
+(47669,1,0),
+(47670,1,0),
+(47681,1,0),
+(47682,1,0),
+(47683,1,0),
+(47684,1,0),
+(47685,1,0),
+(47691,1,1),
+(47711,1,0),
+(47712,1,0),
+(47713,1,0),
+(47747,1,0),
+(47771,1,0),
+(47787,1,0),
+(47799,1,0),
+(47911,1,0),
+(47913,1,0),
+(47916,1,0),
+(47933,1,0),
+(47935,1,0),
+(47939,1,0),
+(47959,1,0),
+(48009,1,0),
+(48021,1,0),
+(48028,1,1),
+(48035,1,0),
+(48115,1,0),
+(48117,1,0),
+(48183,1,0),
+(48185,1,0),
+(48188,1,0),
+(48194,1,1),
+(48199,1,0),
+(48201,1,0),
+(48202,1,0),
+(48213,1,0),
+(48218,1,0),
+(48222,1,0),
+(48223,1,0),
+(48227,1,0),
+(48246,1,1),
+(48252,1,0),
+(48293,1,0),
+(48306,1,0),
+(48315,1,0),
+(48329,1,0),
+(48344,1,0),
+(48345,1,0),
+(48362,1,0),
+(48363,1,0),
+(48375,1,0),
+(48385,1,0),
+(48398,1,0),
+(48399,1,0),
+(48425,1,0),
+(48426,1,0),
+(48455,1,0),
+(48490,1,0),
+(48497,1,0),
+(48508,1,0),
+(48530,1,0),
+(48551,1,0),
+(48597,1,0),
+(48600,1,0),
+(48605,1,0),
+(48620,1,0),
+(48623,1,0),
+(48627,1,0),
+(48641,1,0),
+(48642,1,0),
+(48646,1,0),
+(48649,1,0),
+(48685,1,0),
+(48724,1,0),
+(48726,1,0),
+(48728,1,0),
+(48730,1,0),
+(48732,1,0),
+(48748,1,0),
+(48764,1,0),
+(48771,1,0),
+(48773,1,0),
+(48790,1,0),
+(48793,1,0),
+(48799,1,0),
+(48808,1,0),
+(48811,1,0),
+(48896,1,0),
+(48901,1,0),
+(48904,1,0),
+(48929,1,0),
+(48974,1,0),
+(48975,1,0),
+(49022,1,0),
+(49030,1,0),
+(49058,1,0),
+(49062,1,0),
+(49075,1,0),
+(49080,1,0),
+(49083,1,0),
+(49118,1,0),
+(49125,1,0),
+(49128,1,0),
+(49129,1,0),
+(49131,1,0),
+(49134,1,0),
+(49135,1,0),
+(49159,1,0),
+(49166,1,0),
+(49210,1,0),
+(49211,1,0),
+(49262,1,0),
+(49291,1,0),
+(49292,1,0),
+(49313,1,0),
+(49319,1,0),
+(49325,1,0),
+(49330,1,0),
+(49332,1,0),
+(49333,1,0),
+(49334,1,0),
+(49367,1,0),
+(49370,1,0),
+(49404,1,0),
+(49405,1,0),
+(49428,1,0),
+(49434,1,0),
+(49515,1,0),
+(49517,1,0),
+(49519,1,0),
+(49524,1,0),
+(49525,1,0),
+(49552,1,0),
+(49554,1,0),
+(49555,1,0),
+(49557,1,0),
+(49590,1,0),
+(49625,1,0),
+(49634,1,0),
+(49679,1,0),
+(49682,1,0),
+(49683,1,0),
+(49684,1,0),
+(49731,1,0),
+(49751,1,0),
+(49762,1,0),
+(49825,1,0),
+(49826,1,0),
+(49829,1,0),
+(49858,1,0),
+(49862,1,0),
+(49870,1,0),
+(49899,1,0),
+(49947,1,0),
+(50036,1,0),
+(50087,1,0),
+(50133,1,0),
+(50173,1,0),
+(50174,1,0),
+(50176,1,0),
+(50177,1,0),
+(50178,1,0),
+(50179,1,0),
+(50312,1,0),
+(50315,1,1),
+(50331,1,0),
+(50350,1,0),
+(50382,1,0),
+(50383,1,0),
+(50398,1,1),
+(50430,1,0),
+(50440,1,0),
+(50492,1,0),
+(50515,1,0),
+(50524,1,0),
+(50546,1,0),
+(50547,1,0),
+(50548,1,0),
+(50554,1,0),
+(50556,1,0),
+(50562,1,0),
+(50563,1,0),
+(50568,1,0),
+(50569,1,0),
+(50592,1,0),
+(50628,1,0),
+(50669,1,0),
+(50674,1,0),
+(50682,1,1),
+(50742,1,0),
+(50775,1,0),
+(50793,1,0),
+(50794,1,0),
+(50817,1,0),
+(50835,1,0),
+(50878,1,0),
+(50883,1,1),
+(50892,1,0),
+(51001,1,0),
+(51022,1,0),
+(51023,1,0),
+(51024,1,0),
+(51025,1,0),
+(51039,1,0),
+(51049,1,0),
+(51122,1,0),
+(51136,1,0),
+(51139,1,0),
+(51152,1,0),
+(51171,1,0),
+(51172,1,0),
+(51202,1,0),
+(51213,1,0),
+(51215,1,0),
+(51234,1,0),
+(51239,1,0),
+(51247,1,0),
+(51256,1,0),
+(51276,1,0),
+(51288,1,0),
+(51318,1,0),
+(51331,1,0),
+(51332,1,0),
+(51333,1,0),
+(51343,1,0),
+(51366,1,0),
+(51368,1,0),
+(51381,1,0),
+(51384,1,0),
+(51393,1,0),
+(51396,1,0),
+(51403,1,0),
+(51420,1,0),
+(51448,1,1),
+(51516,1,0),
+(51518,1,0),
+(51577,1,0),
+(51579,1,0),
+(51590,1,0),
+(51603,1,0),
+(51606,1,0),
+(51607,1,0),
+(51616,1,0),
+(51639,1,0),
+(51641,1,0),
+(51642,1,0),
+(51643,1,0),
+(51644,1,0),
+(51645,1,0),
+(51649,1,0),
+(51650,1,0),
+(51651,1,0),
+(51652,1,0),
+(51670,1,0),
+(51694,1,0),
+(51697,1,0),
+(51727,1,0),
+(51737,1,0),
+(51739,1,0),
+(51743,1,0),
+(51754,1,0),
+(51767,1,0),
+(51769,1,0),
+(51773,1,0),
+(51774,1,0),
+(51791,1,0),
+(51794,1,0),
+(51825,1,0),
+(51840,1,0),
+(51843,1,0),
+(51858,1,0),
+(51859,1,0),
+(51861,1,0),
+(51866,1,0),
+(51870,1,0),
+(51902,1,0),
+(51904,1,0),
+(51907,1,0),
+(51910,1,0),
+(51925,1,0),
+(51927,1,0),
+(51931,1,0),
+(51932,1,0),
+(51933,1,0),
+(51942,1,0),
+(51959,1,0),
+(51964,1,0),
+(51965,1,0),
+(52011,1,0),
+(52037,1,0),
+(52059,1,0),
+(52064,1,0),
+(52089,1,0),
+(52106,1,0),
+(52122,1,0),
+(52124,1,0),
+(52140,1,0),
+(52151,1,0),
+(52164,1,0),
+(52170,1,0),
+(52173,1,0),
+(52185,1,0),
+(52227,1,0),
+(52229,1,0),
+(52238,1,0),
+(52239,1,0),
+(52242,1,0),
+(52247,1,0),
+(52254,1,0),
+(52257,1,0),
+(52259,1,0),
+(52264,1,0),
+(52294,1,0),
+(52313,1,0),
+(52322,1,0),
+(52335,1,0),
+(52336,1,0),
+(52337,1,1),
+(52340,1,0),
+(52343,1,0),
+(52349,1,0),
+(52365,1,1),
+(52369,1,0),
+(52371,1,0),
+(52381,1,0),
+(52387,1,0),
+(52388,1,0),
+(52407,1,0),
+(52412,1,0),
+(52414,1,0),
+(52427,1,0),
+(52438,1,0),
+(52446,1,0),
+(52449,1,0),
+(52452,1,0),
+(52453,1,0),
+(52454,1,0),
+(52457,1,0),
+(52458,1,0),
+(52512,1,0),
+(52514,1,0),
+(52528,1,0),
+(52576,1,0),
+(52577,1,0),
+(52585,1,0),
+(52607,1,0),
+(52632,1,0),
+(52638,1,0),
+(52654,1,0),
+(52661,1,0),
+(52676,1,0),
+(52681,1,0),
+(52686,1,0),
+(52687,1,0),
+(52688,1,0),
+(52725,1,0),
+(52726,1,0),
+(52727,1,0),
+(52728,1,0),
+(52729,1,0),
+(52730,1,0),
+(52731,1,0),
+(52732,1,0),
+(52774,1,0),
+(52791,1,0),
+(52793,1,0),
+(52805,1,0),
+(52811,1,0),
+(52816,1,0),
+(52833,1,0),
+(52834,1,0),
+(52837,1,0),
+(52838,1,0),
+(52844,1,0),
+(52850,1,0),
+(52884,1,0),
+(52908,1,0),
+(52920,1,0),
+(52930,1,0),
+(52934,1,0),
+(52935,1,0),
+(52936,1,0),
+(52937,1,0),
+(52953,1,0),
+(52955,1,0),
+(52956,1,0),
+(52981,1,0),
+(52989,1,0),
+(52990,1,0),
+(53010,1,0),
+(53020,1,0),
+(53024,1,0),
+(53029,1,0),
+(53038,1,0),
+(53083,1,0),
+(53093,1,0),
+(53096,1,0),
+(53106,1,0),
+(53110,1,0),
+(53163,1,0),
+(53170,1,0),
+(53177,1,0),
+(53185,1,0),
+(53206,1,0),
+(53210,1,0),
+(53242,1,1),
+(53272,1,0),
+(53441,1,0),
+(53464,1,0),
+(53465,1,0),
+(53466,1,0),
+(53570,1,0),
+(53609,1,0),
+(53613,1,0),
+(53626,1,0),
+(53644,1,0),
+(53680,1,0),
+(53683,1,0),
+(53684,1,0),
+(53685,1,0),
+(53701,1,0),
+(53714,1,1),
+(53717,1,0),
+(53730,1,0),
+(53745,1,0),
+(53757,1,1),
+(53778,1,0),
+(53798,1,0),
+(53826,1,0),
+(53827,1,0),
+(53828,1,0),
+(53829,1,0),
+(54040,1,0),
+(54047,1,0),
+(54089,1,0),
+(54090,1,0),
+(54097,1,0),
+(54108,1,0),
+(54112,1,0),
+(54128,1,0),
+(54142,1,0),
+(54209,1,0),
+(54236,1,0),
+(54245,1,0),
+(54250,1,0),
+(54258,1,0),
+(54264,1,0),
+(54265,1,0),
+(54266,1,0),
+(54267,1,0),
+(54269,1,0),
+(54323,1,0),
+(54325,1,0),
+(54327,1,0),
+(54328,1,0),
+(54377,1,0),
+(54423,1,0),
+(54426,1,0),
+(54430,1,0),
+(54464,1,0),
+(54510,1,0),
+(54522,1,0),
+(54539,1,0),
+(54548,1,0),
+(54643,1,0),
+(54656,1,0),
+(54664,1,0),
+(54685,1,0),
+(54699,1,1),
+(54725,1,1),
+(54728,1,0),
+(54744,1,1),
+(54746,1,1),
+(54773,1,0),
+(54796,1,0),
+(54798,1,0),
+(54806,1,0),
+(54878,1,0),
+(54899,1,0),
+(54984,1,0),
+(54985,1,0),
+(54988,1,0),
+(54991,1,0),
+(55063,1,0),
+(55089,1,0),
+(55127,1,0),
+(55134,1,0),
+(55137,1,0),
+(55138,1,0),
+(55141,1,0),
+(55145,1,0),
+(55161,1,0),
+(55223,1,0),
+(55227,1,0),
+(55229,1,0),
+(55231,1,0),
+(55244,1,0),
+(55257,1,0),
+(55287,1,0),
+(55288,1,0),
+(55290,1,0),
+(55406,1,0),
+(55418,1,0),
+(55419,1,0),
+(55423,1,1),
+(55432,1,0),
+(55465,1,0),
+(55468,1,0),
+(55510,1,0),
+(55516,1,0),
+(55519,1,0),
+(55524,1,0),
+(55526,1,0),
+(55527,1,0),
+(55571,1,0),
+(55578,1,0),
+(55616,1,1),
+(55647,1,0),
+(55660,1,0),
+(55661,1,0),
+(55662,1,0),
+(55693,1,0),
+(55720,1,0),
+(55721,1,0),
+(55722,1,0),
+(55723,1,0),
+(55724,1,0),
+(55725,1,0),
+(55726,1,0),
+(55727,1,0),
+(55785,1,0),
+(55796,1,0),
+(55801,1,0),
+(55803,1,0),
+(55805,1,0),
+(55811,1,0),
+(55844,1,0),
+(55853,1,0),
+(55868,1,0),
+(55872,1,0),
+(55875,1,0),
+(55878,1,1),
+(55881,1,1),
+(55882,1,0),
+(55885,1,1),
+(55886,1,0),
+(55887,1,1),
+(55888,1,0),
+(55954,1,0),
+(56047,1,0),
+(56066,1,0),
+(56099,1,0),
+(56103,1,0),
+(56114,1,0),
+(56117,1,0),
+(56150,1,0),
+(56152,1,0),
+(56189,1,0),
+(56227,1,0),
+(56253,1,0),
+(56263,1,0),
+(56264,1,0),
+(56265,1,0),
+(56266,1,0),
+(56275,1,0),
+(56312,1,0),
+(56387,1,0),
+(56388,1,0),
+(56393,1,0),
+(56429,1,0),
+(56458,1,0),
+(56505,1,0),
+(56523,1,0),
+(56560,1,0),
+(56563,1,0),
+(56567,1,0),
+(56575,1,0),
+(56621,1,0),
+(56622,1,0),
+(56652,1,0),
+(56661,1,0),
+(56663,1,0),
+(56665,1,0),
+(56667,1,0),
+(56669,1,0),
+(56673,1,0),
+(56677,1,0),
+(56680,1,0),
+(56683,1,0),
+(56688,1,0),
+(56691,1,0),
+(56693,1,0),
+(56695,1,0),
+(56696,1,0),
+(56711,1,0),
+(56713,1,0),
+(56722,1,0),
+(56723,1,0),
+(56724,1,0),
+(56725,1,0),
+(56738,1,0),
+(56763,1,0),
+(56764,1,0),
+(56865,1,0),
+(56905,1,0),
+(56917,1,0),
+(56941,1,1),
+(57042,1,0),
+(57068,1,0),
+(57071,1,0),
+(57072,1,0),
+(57410,1,0),
+(57417,1,0),
+(57420,1,0),
+(57422,1,0),
+(57469,1,0),
+(57471,1,0),
+(57495,1,0),
+(57523,1,0),
+(57534,1,0),
+(57632,1,0),
+(57637,1,0),
+(57638,1,0),
+(57639,1,0),
+(57642,1,0),
+(57650,1,0),
+(57659,1,0),
+(57666,1,0),
+(57667,1,0),
+(57682,1,0),
+(57732,1,0),
+(57734,1,0),
+(57735,1,0),
+(57736,1,0),
+(57737,1,0),
+(57738,1,0),
+(57797,1,0),
+(57806,1,0),
+(57809,1,0),
+(57828,1,0),
+(57852,1,0),
+(57853,1,0),
+(57885,1,0),
+(57891,1,0),
+(57912,1,0),
+(57930,1,0),
+(57962,1,0),
+(57963,1,0),
+(57980,1,0),
+(57983,1,0),
+(58036,1,0),
+(58040,1,0),
+(58064,1,0),
+(58084,1,0),
+(58103,1,0),
+(58108,1,0),
+(58109,1,0),
+(58112,1,0),
+(58114,1,0),
+(58121,1,0),
+(58123,1,0),
+(58124,1,0),
+(58131,1,0),
+(58152,1,0),
+(58178,1,0),
+(58195,1,1),
+(58196,1,1),
+(58197,1,1),
+(58198,1,1),
+(58225,1,0),
+(58350,1,0),
+(58416,1,0),
+(58493,1,1),
+(58515,1,0),
+(58533,1,0),
+(58542,1,0),
+(58552,1,0),
+(58593,1,0),
+(58641,1,0),
+(58658,1,0),
+(58672,1,0),
+(58685,1,0),
+(58793,1,0),
+(58836,1,0),
+(58838,1,0),
+(58846,1,1),
+(58858,1,0),
+(58873,1,0),
+(58916,1,0),
+(58917,1,0),
+(58945,1,0),
+(58949,1,0),
+(59078,1,0),
+(59091,1,0),
+(59098,1,0),
+(59115,1,0),
+(59125,1,0),
+(59189,1,0),
+(59190,1,0),
+(59284,1,0),
+(59335,1,0),
+(59363,1,0),
+(59375,1,0),
+(59383,1,0),
+(59386,1,0),
+(59396,1,0),
+(59449,1,0),
+(59456,1,0),
+(59461,1,1),
+(59528,1,0),
+(59534,1,0),
+(59552,1,0),
+(59554,1,0),
+(59556,1,1),
+(59579,1,0),
+(59595,1,0),
+(59643,1,0),
+(59655,1,0),
+(59668,1,0),
+(59677,1,0),
+(59678,1,0),
+(59704,1,0),
+(59729,1,0),
+(59730,1,0),
+(59764,1,0),
+(59780,1,0),
+(59781,1,0),
+(59807,1,0),
+(59847,1,0),
+(59867,1,0),
+(59871,1,0),
+(59897,1,0),
+(59925,1,0),
+(59930,1,0),
+(59951,1,0),
+(59952,1,0),
+(59977,1,0),
+(60038,1,0),
+(60045,1,0),
+(60046,1,0),
+(60088,1,0),
+(60104,1,0),
+(60178,1,1),
+(60207,1,0),
+(60208,1,0),
+(60224,1,0),
+(60243,1,0),
+(60256,1,0),
+(60285,1,0),
+(60288,1,0),
+(60291,1,1),
+(60292,1,1),
+(60293,1,1),
+(60294,1,1),
+(60295,1,1),
+(60296,1,1),
+(60297,1,1),
+(60298,1,0),
+(60310,1,0),
+(60315,1,0),
+(60316,1,0),
+(60342,1,0),
+(60422,1,0),
+(60456,1,0),
+(60476,1,1),
+(60496,1,0),
+(60499,1,1),
+(60507,1,1),
+(60508,1,1),
+(60511,1,0),
+(60516,1,0),
+(60522,1,1),
+(60528,1,0),
+(60535,1,0),
+(60536,1,0),
+(60561,1,0),
+(60612,1,0),
+(60614,1,0),
+(60713,1,0),
+(60810,1,0),
+(60829,1,0),
+(60831,1,0),
+(60834,1,0),
+(60836,1,0),
+(60863,1,0),
+(60909,1,0),
+(60912,1,1),
+(60967,1,0),
+(61007,1,0),
+(61026,1,0),
+(61028,1,0),
+(61071,1,0),
+(61072,1,0),
+(61073,1,0),
+(61074,1,0),
+(61075,1,0),
+(61114,1,0),
+(61121,1,0),
+(61151,1,0),
+(61152,1,0),
+(61180,1,0),
+(61210,1,0),
+(61219,1,0),
+(61245,1,0),
+(61254,1,0),
+(61353,1,0),
+(61355,1,0),
+(61397,1,0),
+(61408,1,0),
+(61416,1,0),
+(61487,1,0),
+(61488,1,0),
+(61492,1,0),
+(61524,1,0),
+(61537,1,0),
+(61588,1,0),
+(61602,1,0),
+(61647,1,0),
+(61652,1,0),
+(61665,1,0),
+(61710,1,0),
+(61738,1,0),
+(61764,1,0),
+(61765,1,0),
+(61766,1,0),
+(61771,1,0),
+(61816,1,1),
+(61863,1,1),
+(61901,1,0),
+(61934,1,0),
+(61942,1,0),
+(61964,1,0),
+(61975,1,0),
+(62002,1,0),
+(62016,1,0),
+(62034,1,0),
+(62037,1,1),
+(62072,1,0),
+(62082,1,0),
+(62083,1,0),
+(62084,1,0),
+(62091,1,0),
+(62102,1,0),
+(62195,1,0),
+(62223,1,0),
+(62266,1,0),
+(62272,1,0),
+(62278,1,0),
+(62284,1,0),
+(62304,1,0),
+(62323,1,0),
+(62343,1,0),
+(47129,2,0),
+(34395,2,0),
+(34387,2,0),
+(32440,2,0),
+(32439,2,0),
+(32205,2,0),
+(31538,2,0),
+(30740,2,0),
+(29831,2,0),
+(28806,2,0),
+(28353,2,0),
+(27517,2,0),
+(27203,2,0),
+(27202,2,0),
+(27201,2,0),
+(27191,2,0),
+(27190,2,0),
+(27184,2,0),
+(26560,2,0),
+(26063,2,0),
+(25005,2,0),
+(24934,2,0),
+(24871,2,0),
+(24721,2,0),
+(24390,2,0),
+(23208,2,0),
+(21127,2,0),
+(18431,2,0),
+(17731,2,0),
+(17016,2,0),
+(16613,2,0),
+(16447,2,0),
+(13489,2,0),
+(12139,2,0),
+(11792,2,0),
+(9224,2,0),
+(9223,2,0),
+(9222,2,0),
+(9221,2,0),
+(8674,2,0),
+(7729,2,0),
+(7728,2,0),
+(3921,2,0),
+(35683,2,0),
+(36066,2,0),
+(36546,2,0),
+(36851,2,0),
+(37754,2,0),
+(38439,2,0),
+(38782,2,0),
+(39050,2,0),
+(40055,2,0),
+(40165,2,0),
+(40166,2,0),
+(40167,2,0),
+(40328,2,0),
+(40447,2,0),
+(40468,2,0),
+(40632,2,0),
+(40640,2,0),
+(40642,2,0),
+(40644,2,0),
+(40675,2,0),
+(40774,2,0),
+(40785,2,0),
+(40964,2,0),
+(40965,2,0),
+(40968,2,0),
+(40970,2,0),
+(41004,2,0),
+(41145,2,0),
+(41146,2,0),
+(42020,2,0),
+(42022,2,0),
+(42323,2,0),
+(42788,2,0),
+(43418,2,0),
+(43552,2,0),
+(43723,2,0),
+(43753,2,0),
+(43768,2,0),
+(43950,2,0),
+(44307,2,0),
+(44498,2,0),
+(44499,2,0),
+(44611,2,0),
+(44686,2,0),
+(44874,2,0),
+(44885,2,0),
+(45149,2,0),
+(45222,2,0),
+(45226,2,0),
+(45795,2,0),
+(45877,2,0),
+(45971,2,0),
+(46072,2,0),
+(46350,2,0),
+(46360,2,1),
+(46584,2,0),
+(76006,2,0),
+(74179,2,0),
+(72869,2,0),
+(72868,2,0),
+(72608,2,0),
+(72456,2,0),
+(72405,2,0),
+(72340,2,1),
+(71284,2,1),
+(70598,2,1),
+(70446,2,1),
+(70346,2,0),
+(70227,2,0),
+(70199,2,0),
+(70175,2,0),
+(70173,2,0),
+(69402,2,0),
+(69400,2,0),
+(69294,2,0),
+(69157,2,0),
+(67815,2,0),
+(67814,2,0),
+(67813,2,0),
+(67812,2,0),
+(67798,2,0),
+(67459,2,0),
+(67458,2,0),
+(67448,2,0),
+(67439,2,0),
+(67436,2,0),
+(66676,2,0),
+(66672,2,0),
+(66655,2,0),
+(66531,2,0),
+(66289,2,0),
+(65209,2,0),
+(64871,2,0),
+(64570,2,0),
+(64436,2,0),
+(63618,2,0),
+(63381,2,0),
+(62776,2,0),
+(62714,2,0),
+(62635,2,0),
+(62397,2,0),
+(62363,2,0),
+(62357,2,0),
+(62355,2,0),
+(62307,2,0),
+(62086,2,0),
+(61999,2,1),
+(60289,2,0),
+(60101,2,0),
+(59790,2,0),
+(59732,2,0),
+(59576,2,0),
+(58596,2,0),
+(58231,2,0),
+(57945,2,0),
+(57619,2,0),
+(57610,2,0),
+(57607,2,0),
+(57583,2,0),
+(57575,2,0),
+(57544,2,0),
+(57517,2,0),
+(57415,2,0),
+(56790,2,0),
+(56570,2,0),
+(56385,2,0),
+(56350,2,0),
+(55934,2,0),
+(55820,2,0),
+(55367,2,0),
+(55197,2,0),
+(54712,2,0),
+(54666,2,0),
+(54530,2,0),
+(52510,2,0),
+(52408,2,0),
+(52339,2,0),
+(52277,2,0),
+(52274,2,0),
+(52115,2,0),
+(51383,2,0),
+(51328,2,0),
+(51327,2,0),
+(51326,2,0),
+(51325,2,0),
+(51241,2,0),
+(50999,2,0),
+(50319,2,0),
+(50026,2,0),
+(50003,2,0),
+(49867,2,0),
+(49860,2,0),
+(49765,2,0),
+(49728,2,0),
+(49693,2,0),
+(49689,2,0),
+(49158,2,0),
+(49123,2,0),
+(49109,2,0),
+(48794,2,0),
+(48738,2,0),
+(48347,2,0),
+(47978,2,0),
+(35246,2,0),
+(42576,3,0),
+(42492,3,0),
+(42475,3,0),
+(42433,3,0),
+(42350,3,0),
+(42348,3,0),
+(42242,3,1),
+(42228,3,0),
+(42220,3,0),
+(42114,3,0),
+(41221,3,0),
+(40961,3,0),
+(40960,3,0),
+(40959,3,0),
+(40957,3,0),
+(40885,3,0),
+(40603,3,0),
+(40495,3,0),
+(40401,3,0),
+(40380,3,0),
+(40341,3,0),
+(40307,3,0),
+(40286,3,0),
+(40285,3,0),
+(40284,3,0),
+(40283,3,0),
+(40268,3,0),
+(40247,3,0),
+(40246,3,0),
+(40245,3,0),
+(40244,3,0),
+(40240,3,0),
+(40222,3,0),
+(40179,3,0),
+(40178,3,0),
+(40177,3,0),
+(40176,3,0),
+(40105,3,0),
+(40076,3,0),
+(39932,3,0),
+(39887,3,0),
+(39844,3,0),
+(39832,3,1),
+(39831,3,0),
+(39558,3,0),
+(39401,3,0),
+(39399,3,0),
+(39398,3,0),
+(39393,3,0),
+(39384,3,0),
+(39364,3,0),
+(38866,3,0),
+(38680,3,0),
+(38173,3,0),
+(38046,3,0),
+(38044,3,0),
+(37970,3,0),
+(37954,3,0),
+(37942,3,0),
+(37919,3,0),
+(37913,3,0),
+(37793,3,1),
+(37789,3,0),
+(37750,3,1),
+(37504,3,0),
+(37489,3,0),
+(37473,3,1),
+(37366,3,0),
+(37134,3,0),
+(36821,3,0),
+(36811,3,0),
+(36450,3,0),
+(36449,3,1),
+(36325,3,0),
+(35958,3,0),
+(35776,3,0),
+(35734,3,0),
+(35599,3,0),
+(35596,3,0),
+(34303,3,0),
+(34200,3,0),
+(34186,3,0),
+(42578,3,0),
+(33814,3,0),
+(33783,3,0),
+(33670,3,0),
+(33664,3,0),
+(33365,3,0),
+(33240,3,0),
+(33111,3,0),
+(32785,3,0),
+(32314,3,0),
+(32307,3,0),
+(32241,3,0),
+(32148,3,0),
+(32067,3,0),
+(31927,3,0),
+(31543,3,0),
+(31364,3,0),
+(31363,3,0),
+(31333,3,0),
+(30758,3,0),
+(30741,3,0),
+(30284,3,0),
+(29945,3,0),
+(29866,3,0),
+(29820,3,1),
+(29460,3,0),
+(28373,3,0),
+(28250,3,0),
+(28054,3,0),
+(26521,3,0),
+(26519,3,0),
+(26518,3,0),
+(26517,3,0),
+(26516,3,0),
+(26490,3,0),
+(26488,3,0),
+(26393,3,1),
+(26373,3,0),
+(26338,3,0),
+(26337,3,0),
+(26336,3,0),
+(26335,3,0),
+(26334,3,0),
+(26333,3,0),
+(26329,3,0),
+(26328,3,0),
+(26327,3,0),
+(26326,3,0),
+(26325,3,0),
+(26304,3,0),
+(26295,3,0),
+(26294,3,0),
+(26293,3,0),
+(26292,3,0),
+(26291,3,0),
+(26286,3,0),
+(25687,3,0),
+(25183,3,0),
+(25181,3,0),
+(25180,3,0),
+(25178,3,0),
+(25177,3,0),
+(24973,3,0),
+(24731,3,0),
+(23024,3,0),
+(21086,3,0),
+(21014,3,0),
+(20038,3,0),
+(20037,3,0),
+(19873,3,0),
+(17179,3,0),
+(16629,3,0),
+(16452,3,0),
+(16337,3,0),
+(15998,3,0),
+(13488,3,0),
+(12151,3,0),
+(10860,3,0),
+(10836,3,0),
+(10835,3,0),
+(10834,3,0),
+(10805,3,0),
+(9257,3,0),
+(9232,3,0),
+(42868,3,0),
+(43233,3,0),
+(43539,3,0),
+(43664,3,0),
+(43898,3,0),
+(43954,3,0),
+(43963,3,0),
+(43986,3,0),
+(44013,3,0),
+(44132,3,0),
+(44213,3,0),
+(44249,3,0),
+(44320,3,0),
+(44321,3,0),
+(44375,3,0),
+(44465,3,0),
+(44554,3,0),
+(44565,3,0),
+(44603,3,0),
+(44678,3,0),
+(44844,3,0),
+(44884,3,0),
+(45030,3,0),
+(45050,3,1),
+(45201,3,0),
+(45203,3,0),
+(45404,3,0),
+(45502,3,0),
+(45585,3,0),
+(45633,3,0),
+(45635,3,0),
+(45653,3,0),
+(45839,3,0),
+(45885,3,1),
+(46417,3,0),
+(46574,3,0),
+(46638,3,1),
+(46852,3,0),
+(46896,3,0),
+(47030,3,1),
+(47328,3,0),
+(47510,3,0),
+(47628,3,0),
+(47745,3,0),
+(47775,3,1),
+(47800,3,0),
+(48198,3,0),
+(48212,3,0),
+(48331,3,0),
+(48431,3,0),
+(48882,3,0),
+(48972,3,0),
+(49197,3,0),
+(49300,3,0),
+(49308,3,0),
+(49453,3,0),
+(49735,3,0),
+(50313,3,1),
+(50348,3,0),
+(50443,3,0),
+(50501,3,0),
+(50626,3,0),
+(50639,3,0),
+(50640,3,0),
+(50716,3,0),
+(50790,3,0),
+(50791,3,0),
+(50802,3,0),
+(50803,3,0),
+(50825,3,0),
+(50826,3,0),
+(51212,3,0),
+(51246,3,0),
+(51395,3,0),
+(51511,3,0),
+(51742,3,0),
+(51748,3,0),
+(51805,3,0),
+(51846,3,0),
+(52067,3,1),
+(52271,3,0),
+(52305,3,0),
+(52479,3,0),
+(52480,3,0),
+(52497,3,0),
+(52603,3,0),
+(52683,3,0),
+(52685,3,0),
+(52812,3,0),
+(53677,3,0),
+(53679,3,0),
+(53694,3,0),
+(53705,3,0),
+(53706,3,0),
+(54272,3,0),
+(54517,3,0),
+(54914,3,0),
+(54961,3,0),
+(54990,3,0),
+(55037,3,0),
+(55083,3,0),
+(55365,3,0),
+(55479,3,0),
+(55715,3,0),
+(55800,3,0),
+(55889,3,1),
+(56095,3,0),
+(56140,3,0),
+(56386,3,0),
+(56389,3,0),
+(56578,3,0),
+(56747,3,0),
+(56765,3,0),
+(57586,3,0),
+(57800,3,0),
+(57824,3,0),
+(57835,3,0),
+(58766,3,0),
+(58825,3,0),
+(59008,3,0),
+(59462,3,0),
+(59464,3,0),
+(59564,3,0),
+(59629,3,0),
+(59694,3,0),
+(60639,3,0),
+(61126,3,0),
+(61224,3,0),
+(61699,3,0),
+(62000,3,0),
+(62056,3,0),
+(62385,3,0),
+(62387,3,0),
+(62399,3,0),
+(62565,3,0),
+(62709,3,0),
+(62973,3,0),
+(62991,3,0),
+(63019,3,0),
+(63122,3,1),
+(63292,3,0),
+(63294,3,0),
+(63295,3,0),
+(63317,3,0),
+(63414,3,0),
+(63528,3,0),
+(63766,3,0),
+(63983,3,0),
+(63985,3,0),
+(64021,3,0),
+(65044,3,0),
+(65045,3,0),
+(65101,3,0),
+(65585,3,0),
+(65586,3,0),
+(65690,3,0),
+(66129,3,0),
+(66170,3,0),
+(66598,3,0),
+(67398,3,0),
+(68378,3,0),
+(68902,3,0),
+(69007,3,0),
+(69095,3,0),
+(69096,3,0),
+(69708,3,0),
+(69783,3,0),
+(69797,3,0),
+(69799,3,0),
+(69802,3,0),
+(69985,3,0),
+(70028,3,0),
+(70037,3,0),
+(70194,3,0),
+(70521,3,0),
+(70564,3,0),
+(70590,3,0),
+(70997,3,0),
+(70998,3,0),
+(70999,3,0),
+(71278,3,1),
+(71621,3,0),
+(71704,3,0),
+(72155,3,1),
+(72162,3,1),
+(72274,3,1),
+(72297,3,1),
+(72460,3,1),
+(72548,3,1),
+(72549,3,1),
+(72550,3,1),
+(72619,3,1),
+(72620,3,1),
+(72679,3,0),
+(72771,3,0),
+(72850,3,0),
+(72851,3,0),
+(72852,3,0),
+(74318,3,0),
+(74319,3,0),
+(74320,3,0),
+(74472,3,0),
+(75509,3,0),
+(75553,3,1),
+(75766,3,1),
+(34012,3,0),
+(74271,4,0),
+(74270,4,0),
+(72096,4,1),
+(72034,4,1),
+(71615,4,0),
+(70827,4,0),
+(69425,4,0),
+(69164,4,0),
+(69162,4,0),
+(68981,4,0),
+(68788,4,1),
+(67816,4,0),
+(67796,4,0),
+(65370,4,0),
+(65333,4,0),
+(64626,4,0),
+(62826,4,0),
+(62489,4,0),
+(62466,4,0),
+(62457,4,0),
+(62345,4,0),
+(62308,4,0),
+(60206,4,0),
+(58185,4,0),
+(55896,4,0),
+(55349,4,0),
+(54109,4,0),
+(54107,4,0),
+(51678,4,0),
+(50652,4,0),
+(49556,4,0),
+(48610,4,0),
+(48277,4,0),
+(48224,4,0),
+(47674,4,0),
+(47109,4,0),
+(45922,4,0),
+(44969,4,0),
+(44737,4,0),
+(44687,4,0),
+(44626,4,0),
+(44233,4,0),
+(40647,4,0),
+(40259,4,0),
+(39246,4,0),
+(36904,4,0),
+(36460,4,0),
+(36374,4,0),
+(30532,4,0),
+(28995,4,0),
+(10451,4,0),
+(9735,4,0),
+(8900,4,0),
+(8899,4,0),
+(8898,4,0),
+(8202,4,0),
+(74272,4,0),
+(69767,5,0),
+(65590,5,0),
+(62386,5,0),
+(55588,5,0),
+(54713,5,0),
+(49464,5,0),
+(49460,5,0),
+(49346,5,0),
+(47310,5,1),
+(45676,5,0),
+(44217,5,0),
+(43977,5,0),
+(41962,5,0),
+(40789,5,0),
+(40503,5,0),
+(38729,5,0),
+(38312,5,0),
+(38106,5,0),
+(38105,5,0),
+(38104,5,0),
+(38103,5,0),
+(38102,5,0),
+(38101,5,0),
+(38100,5,0),
+(38099,5,0),
+(37206,5,0),
+(37205,5,0),
+(37204,5,0),
+(36817,5,0),
+(34630,5,0),
+(21866,5,0),
+(21794,5,0),
+(19832,5,0),
+(19250,5,0),
+(8913,5,0),
+(67308,6,0),
+(67307,6,0),
+(67306,6,0),
+(67305,6,0),
+(67304,6,0),
+(67303,6,0),
+(65876,6,0),
+(65875,6,0),
+(63041,6,0),
+(62560,6,0),
+(59099,6,1),
+(44608,6,0),
+(43702,6,0),
+(43080,6,0),
+(43056,6,0),
+(40902,6,0),
+(40657,6,0),
+(28803,6,1),
+(16054,6,0),
+(8712,6,0),
+(75863,7,1),
+(75448,7,1),
+(74412,7,1),
+(74323,7,0),
+(74322,7,0),
+(74321,7,0),
+(73028,7,0),
+(72622,7,1),
+(72621,7,1),
+(72459,7,1),
+(72273,7,0),
+(72272,7,0),
+(71618,7,0),
+(71614,7,0),
+(71279,7,1),
+(70982,7,0),
+(70981,7,0),
+(70952,7,0),
+(69540,7,0),
+(67751,7,0),
+(66905,7,0),
+(66667,7,0),
+(65126,7,0),
+(64218,7,0),
+(63059,7,0),
+(62942,7,0),
+(62705,7,0),
+(61920,7,0),
+(61715,7,0),
+(61714,7,0),
+(61632,7,0),
+(60532,7,0),
+(60430,7,0),
+(59474,7,0),
+(59465,7,0),
+(57409,7,0),
+(57405,7,0),
+(57056,7,1),
+(56694,7,0),
+(56454,7,0),
+(54160,7,0),
+(53605,7,0),
+(52319,7,0),
+(51719,7,0),
+(50747,7,0),
+(50646,7,0),
+(50645,7,0),
+(50627,7,0),
+(50218,7,0),
+(49889,7,0),
+(48742,7,0),
+(48552,7,0),
+(46158,7,0),
+(42287,7,0),
+(42265,7,1),
+(42079,7,0),
+(42004,7,1),
+(41284,7,0),
+(41113,7,0),
+(41112,7,0),
+(41111,7,0),
+(41110,7,0),
+(41071,7,0),
+(41064,7,1),
+(40931,7,0),
+(40929,7,0),
+(40905,7,0),
+(40900,7,0),
+(40851,7,0),
+(40370,7,0),
+(40172,7,0),
+(40171,7,0),
+(40170,7,0),
+(40169,7,0),
+(40075,7,1),
+(39698,7,0),
+(39686,7,0),
+(39218,7,0),
+(38920,7,0),
+(38774,7,0),
+(38484,7,0),
+(38449,7,0),
+(38371,7,0),
+(37076,7,0),
+(35957,7,1),
+(35754,7,0),
+(35289,7,0),
+(34350,7,0),
+(34187,7,0),
+(31625,7,0),
+(31624,7,0),
+(31617,7,0),
+(30939,7,1),
+(30659,7,0),
+(30657,7,0),
+(30531,7,0),
+(30098,7,0),
+(28681,7,1),
+(25790,7,0),
+(25029,7,0),
+(23015,7,0),
+(22710,7,0),
+(20553,7,0),
+(10732,7,0),
+(10348,7,0),
+(7082,7,0),
+(5628,7,0),
+(804,7,0),
+(802,7,0),
+(54069,1,0),
+(56251,1,0),
+(58630,1,0);
+
+-- remove redundant entries
+DELETE FROM `conditions` WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 1 AND `ConditionValue2` = 0 AND `SourceEntry` IN (SELECT `id` FROM `temp_convert_spells` WHERE onlyPlayers);
+
+-- set source group if available in db
+UPDATE `conditions` SET `SourceGroup` = `ConditionValue3`, `ConditionValue3` = 0 WHERE `ConditionTypeOrReference` = 18;
+
+-- set source group in case of old default (not set) source group
+UPDATE `conditions` SET `SourceGroup` = (SELECT `effMask` FROM `temp_convert_spells` WHERE `id` = `SourceEntry`) WHERE `SourceGroup` = 0 AND `ConditionTypeOrReference` = 18;
+
+CREATE TABLE `temp_cond_vals`
+(
+ `sourceGroup` INT(11),
+ `sourceEntry` INT(11),
+ `conditionValue1` INT(11),
+ `conditionValue2` INT(11),
+ `elseGroup` INT(11) AUTO_INCREMENT,
+ PRIMARY KEY (`sourceGroup`, `sourceEntry`, `elseGroup`)
+) ENGINE=MYISAM;
+
+INSERT INTO `temp_cond_vals` (`sourceGroup`, `sourceEntry`, `conditionValue1`, `conditionValue2`) SELECT `SourceGroup`, `SourceEntry`, `ConditionValue1`, `ConditionValue2` FROM `conditions` WHERE `ConditionTypeOrReference` = 18;
+
+-- set correct else group
+UPDATE `conditions` SET `ElseGroup` = (SELECT `elseGroup` FROM `temp_cond_vals` WHERE `sourceGroup` = `conditions`.`SourceGroup` AND `sourceEntry` = `conditions`.`SourceEntry` AND `conditionValue1` = `conditions`.`ConditionValue1` AND `conditionValue2` = `conditions`.`ConditionValue2`)-1 WHERE `ConditionTypeOrReference` = 18;
+
+-- old condition type 3 (caster's minion)
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`)
+SELECT `SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, 33, 0, 1, 3 FROM `conditions` WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 3;
+
+UPDATE `conditions` SET `ConditionTypeOrReference` = 31 WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 3;
+
+-- old condition type 2 (dead creature)
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `NegativeCondition`)
+SELECT `SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, 36, 0, 0, 0, 1 FROM `conditions` WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 2;
+
+UPDATE `conditions` SET `ConditionTypeOrReference` = 31, `ConditionValue1` = 3 WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 2;
+
+-- old condition type 1 (creature)
+UPDATE `conditions` SET `ConditionTypeOrReference` = 31, `ConditionValue1` = 3 WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 1 AND `ConditionValue2`;
+
+-- old condition type 1 (player)
+UPDATE `conditions` SET `ConditionTypeOrReference` = 32, `ConditionValue1` = 0x90 WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 1 AND NOT `ConditionValue2`;
+
+-- old condition type 0 (gameobject)
+UPDATE `conditions` SET `ConditionTypeOrReference` = 31, `ConditionValue1` = 5 WHERE `ConditionTypeOrReference` = 18 AND `ConditionValue1` = 0;
+
+DROP TABLE `temp_convert_spells`;
+DROP TABLE `temp_cond_vals`; \ No newline at end of file
diff --git a/sql/updates/world/2012_02_21_02_world_creature_loot_template.sql b/sql/updates/world/2012_02_21_02_world_creature_loot_template.sql
new file mode 100644
index 00000000000..6c6af7ed2a3
--- /dev/null
+++ b/sql/updates/world/2012_02_21_02_world_creature_loot_template.sql
@@ -0,0 +1,11 @@
+UPDATE `creature_template` SET `lootid`=`entry` WHERE `entry` IN (38032,37917,38016,38023,37214,38030,38006,37984);
+DELETE FROM `creature_loot_template` WHERE `entry`IN (38032,37917,38016,38023,37214,38030,38006,37984);
+INSERT INTO `creature_loot_template` (`entry`, `item`, `ChanceOrQuestChance`, `lootmode`, `groupid`, `mincountOrRef`, `maxcount`) VALUES
+(38032,1,100,1,0,-45009,1), -- Crown Sprayer
+(37917,1,100,1,0,-45009,1), -- Crown Thug
+(38016,1,100,1,0,-45009,1), -- Crown Agent
+(38023,1,100,1,0,-45009,1), -- Crown Sprinkler
+(37214,1,100,1,0,-45009,1), -- Crown Lackey
+(38030,1,100,1,0,-45009,1), -- Crown Underling
+(38006,1,100,1,0,-45009,1), -- Crown Hoodlum (level 1??)
+(37984,1,100,1,0,-45009,1); -- Crown Duster (level 1??)
diff --git a/sql/updates/world/2012_02_21_03_world_creature_loot_template.sql b/sql/updates/world/2012_02_21_03_world_creature_loot_template.sql
new file mode 100644
index 00000000000..d7d043cbda9
--- /dev/null
+++ b/sql/updates/world/2012_02_21_03_world_creature_loot_template.sql
@@ -0,0 +1,26 @@
+-- Razormane Hunter Warrior's Boots 32% to 3.2%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=3.2996 WHERE `entry`=3265 AND `item`=2967;
+-- Razormane Hunter Hunting Cloak 11% to 1.1%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=1.1855 WHERE `entry`=3265 AND `item`=4689;
+-- Razormane Defender Pioneer Buckler 87% to 0.8%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.8789 WHERE `entry`=3266 AND `item`=7109;
+-- Razormane Defender Spellbinder Belt 77% to 0.7%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.7717 WHERE `entry`=3266 AND `item`=4684;
+-- Razormane Geomancer Simple Shoes 77% to 0.7%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.7791 WHERE `entry`=3269 AND `item`=9743;
+-- Razormane Geomancer Veteran Bracers 73% to 0.7%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.7364 WHERE `entry`=3269 AND `item`=3213;
+-- Venture Co. Supervisor Burnt Leather Belt 85% to 0.8%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.8511 WHERE `entry`=2979 AND `item`=4666;
+-- Venture Co. Supervisor Warrior's Gloves 74% to 0.7%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.7433 WHERE `entry`=2979 AND `item`=2968;
+-- Venture Co. Supervisor Pioneer Bracers 55% to 0.5%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.5593 WHERE `entry`=2979 AND `item`=6519;
+-- Venture Co. Supervisor Journeyman's Gloves 43% to 0.4%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.4348 WHERE `entry`=2979 AND `item`=2960;
+-- Venture Co. Worker Warrior's Bracers 72% to 0.7%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.7226 WHERE `entry`=2978 AND `item`=3214;
+-- Venture Co. Worker Fine Scimitar 64% to 0.6%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.6492 WHERE `entry`=2978 AND `item`=4560;
+-- Venture Co. Worker Warrior's Girdle 24% to 0.2%
+UPDATE `creature_loot_template` SET `ChanceOrQuestChance`=0.2458 WHERE `entry`=2978 AND `item`=4659;
diff --git a/sql/updates/world/2012_02_21_04_world_creature_loot_template.sql b/sql/updates/world/2012_02_21_04_world_creature_loot_template.sql
new file mode 100644
index 00000000000..3deedbf0b0d
--- /dev/null
+++ b/sql/updates/world/2012_02_21_04_world_creature_loot_template.sql
@@ -0,0 +1,16 @@
+SET @ENTRY := 30409; -- Apprentice Osterkilgr
+DELETE FROM `creature_loot_template` WHERE entry=@ENTRY;
+INSERT INTO `creature_loot_template` (`entry`,`item`,`ChanceOrQuestChance`,`lootmode`,`groupid`,`mincountOrRef`,`maxcount`) VALUES
+-- Quest related Items
+(@ENTRY,43089,-100,1,0,1,1), -- Vrykul Bones
+(@ENTRY,42772,-100,1,0,1,1), -- Dr Terrible's "Building a Better Flesh Giant"
+(@ENTRY,42422,-50,1,0,1,1), -- Jotunheim Cage Key
+-- Other random stuff
+(@ENTRY,33470,20,1,0,1,4), -- Frostweave Cloth
+(@ENTRY,43851,20,1,0,1,1), -- Fur Clothing Scraps
+(@ENTRY,43852,20,1,0,1,1), -- Thick Fur Clothing Scraps
+-- References for world drops
+(@ENTRY,1,10,1,0,-35063,1), -- Northrend Grey Items
+(@ENTRY,2,5,1,0,-35066,1), -- Northrend Green Items
+-- hatebook
+(@ENTRY,45912,0.1,1,0,1,1); -- Book Glyph of Mastery (honestly screw that thing)
diff --git a/sql/updates/world/2012_02_21_05_world_Gossip_SAI.sql b/sql/updates/world/2012_02_21_05_world_Gossip_SAI.sql
new file mode 100644
index 00000000000..1bdccae5c39
--- /dev/null
+++ b/sql/updates/world/2012_02_21_05_world_Gossip_SAI.sql
@@ -0,0 +1,39 @@
+-- SAI for Lothos Riftwaker
+SET @ENTRY=14387;
+UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' 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,1,62,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Lothos Riftwaker - On Gossip Option select - close gossip'),
+(@ENTRY,0,1,0,61,0,100,0,5750,0,0,0,62,409,0,0,0,0,0,7,0,0,0,1096,-467,-104.6,3.64,'Lothos Riftwaker - On Gossip Option select - teleport player');
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (5750);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(5750,0,0,'Teleport me to the Molten Core, Lothos.',1,1,0,0,0,0,'');
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (5750);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,5750,0,0,0,8,7848,0,0,0,0,'','Show gossip option if player has quest 7848 completed');
+
+-- SAI for Zamael Lunthistle
+SET @ENTRY=8436;
+UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' 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,1,62,0,100,0,1285,0,0,0,26,3377,0,0,0,0,0,7,0,0,0,0,0,0,0,'Zamael Lunthistle - On Gossip Option select - quest credit'),
+(@ENTRY,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Zamael Lunthistle - On Gossip Option select - close gossip');
+
+DELETE FROM `gossip_menu` WHERE `entry`=1285 AND `text_id`=1920;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1285,1920);
+DELETE FROM `gossip_menu` WHERE `entry`=1286 AND `text_id`=1922;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1286,1922);
+DELETE FROM `gossip_menu` WHERE `entry`=1287 AND `text_id`=1921;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1287,1921);
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (1285,1286,1287);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(1285,0,0,'I wish to hear your tale.',1,1,1287,0,0,0,''),
+(1286,0,0,'Let me think about it, Zamael.',1,1,1285,0,0,0,''),
+(1287,0,0,'Please continue, Zamael.',1,1,1286,0,0,0,'');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (1285);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,1285,0,0,0,9,3377,0,0,0,0,'','Show gossip option if player has quest 3377 but not complete');
diff --git a/sql/updates/world/2012_02_21_06_world_Gossip.sql b/sql/updates/world/2012_02_21_06_world_Gossip.sql
new file mode 100644
index 00000000000..a59d330c6a3
--- /dev/null
+++ b/sql/updates/world/2012_02_21_06_world_Gossip.sql
@@ -0,0 +1,184 @@
+-- Gossip Update from Pitcrawler
+-- Creature Gossip_menu_id Update from sniff
+UPDATE `creature_template` SET `gossip_menu_id`=7692 WHERE `entry`=18424;
+UPDATE `creature_template` SET `gossip_menu_id`=9033 WHERE `entry`=24838;
+UPDATE `creature_template` SET `gossip_menu_id`=9038 WHERE `entry`=24833;
+UPDATE `creature_template` SET `gossip_menu_id`=9066 WHERE `entry`=25011;
+UPDATE `creature_template` SET `gossip_menu_id`=9067 WHERE `entry`=25015;
+UPDATE `creature_template` SET `gossip_menu_id`=9068 WHERE `entry`=25009;
+UPDATE `creature_template` SET `gossip_menu_id`=9069 WHERE `entry`=25017;
+UPDATE `creature_template` SET `gossip_menu_id`=9070 WHERE `entry`=25018;
+UPDATE `creature_template` SET `gossip_menu_id`=9071 WHERE `entry`=25016;
+UPDATE `creature_template` SET `gossip_menu_id`=9072 WHERE `entry` IN (25013,25014);
+UPDATE `creature_template` SET `gossip_menu_id`=9091 WHERE `entry`=25076;
+UPDATE `creature_template` SET `gossip_menu_id`=9107 WHERE `entry`=24929;
+UPDATE `creature_template` SET `gossip_menu_id`=9109 WHERE `entry`=24927;
+UPDATE `creature_template` SET `gossip_menu_id`=9110 WHERE `entry`=24924;
+UPDATE `creature_template` SET `gossip_menu_id`=9116 WHERE `entry`=25105;
+UPDATE `creature_template` SET `gossip_menu_id`=9117 WHERE `entry`=25100;
+UPDATE `creature_template` SET `gossip_menu_id`=9118 WHERE `entry`=25104;
+UPDATE `creature_template` SET `gossip_menu_id`=9120 WHERE `entry`=25107;
+UPDATE `creature_template` SET `gossip_menu_id`=9121 WHERE `entry` IN (25101,25102,25103);
+UPDATE `creature_template` SET `gossip_menu_id`=9122 WHERE `entry`=25106;
+UPDATE `creature_template` SET `gossip_menu_id`=9349 WHERE `entry`=26539;
+UPDATE `creature_template` SET `gossip_menu_id`=10120 WHERE `entry` IN (31704,31705,31706,31720,31723,31724);
+UPDATE `creature_template` SET `gossip_menu_id`=10259 WHERE `entry`=31716;
+
+-- Gossip Menu insert from sniff
+DELETE FROM `gossip_menu` WHERE `entry`=7692 AND `text_id`=9383;
+DELETE FROM `gossip_menu` WHERE `entry`=7696 AND `text_id`=9444;
+DELETE FROM `gossip_menu` WHERE `entry`=7704 AND `text_id`=9425;
+DELETE FROM `gossip_menu` WHERE `entry`=7726 AND `text_id`=9437;
+DELETE FROM `gossip_menu` WHERE `entry`=7727 AND `text_id`=9438;
+DELETE FROM `gossip_menu` WHERE `entry`=7728 AND `text_id`=9439;
+DELETE FROM `gossip_menu` WHERE `entry`=9033 AND `text_id`=12211;
+DELETE FROM `gossip_menu` WHERE `entry`=9038 AND `text_id`=12216;
+DELETE FROM `gossip_menu` WHERE `entry`=9040 AND `text_id`=12217;
+DELETE FROM `gossip_menu` WHERE `entry`=9041 AND `text_id`=12218;
+DELETE FROM `gossip_menu` WHERE `entry`=9042 AND `text_id`=12219;
+DELETE FROM `gossip_menu` WHERE `entry`=9043 AND `text_id`=12220;
+DELETE FROM `gossip_menu` WHERE `entry`=9066 AND `text_id`=12262;
+DELETE FROM `gossip_menu` WHERE `entry`=9067 AND `text_id`=12263;
+DELETE FROM `gossip_menu` WHERE `entry`=9068 AND `text_id`=12264;
+DELETE FROM `gossip_menu` WHERE `entry`=9069 AND `text_id`=12266;
+DELETE FROM `gossip_menu` WHERE `entry`=9070 AND `text_id`=12267;
+DELETE FROM `gossip_menu` WHERE `entry`=9091 AND `text_id`=12292;
+DELETE FROM `gossip_menu` WHERE `entry`=9109 AND `text_id`=12317;
+DELETE FROM `gossip_menu` WHERE `entry`=9110 AND `text_id`=12318;
+DELETE FROM `gossip_menu` WHERE `entry`=9116 AND `text_id`=12327;
+DELETE FROM `gossip_menu` WHERE `entry`=9117 AND `text_id`=12328;
+DELETE FROM `gossip_menu` WHERE `entry`=9118 AND `text_id`=12329;
+DELETE FROM `gossip_menu` WHERE `entry`=9120 AND `text_id`=12331;
+DELETE FROM `gossip_menu` WHERE `entry`=9121 AND `text_id`=12332;
+DELETE FROM `gossip_menu` WHERE `entry`=9122 AND `text_id`=12333;
+DELETE FROM `gossip_menu` WHERE `entry`=9349 AND `text_id`=12649;
+DELETE FROM `gossip_menu` WHERE `entry`=10120 AND `text_id`=14047;
+DELETE FROM `gossip_menu` WHERE `entry`=10259 AND `text_id`=14248;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
+(7692,9383),
+(7696,9444),
+(7704,9425),
+(7726,9437),
+(7727,9438),
+(7728,9439),
+(9033,12211),
+(9038,12216),
+(9040,12217),
+(9041,12218),
+(9042,12219),
+(9043,12220),
+(9066,12262),
+(9067,12263),
+(9068,12264),
+(9069,12266),
+(9070,12267),
+(9091,12292),
+(9109,12317),
+(9110,12318),
+(9116,12327),
+(9117,12328),
+(9118,12329),
+(9120,12331),
+(9121,12332),
+(9122,12333),
+(9349,12649),
+(10120,14047),
+(10259,14248);
+
+-- Insert npc_text from sniff
+DELETE FROM `npc_text` WHERE `ID` IN (9437,9438,9439,12211,12266);
+INSERT INTO `npc_text` (`ID`,`text0_0`,`text0_1`,`lang0`,`prob0`,`em0_0`,`em0_1`,`em0_2`,`em0_3`,`em0_4`,`em0_5`,`text1_0`,`text1_1`,`lang1`,`prob1`,`em1_0`,`em1_1`,`em1_2`,`em1_3`,`em1_4`,`em1_5`,`text2_0`,`text2_1`,`lang2`,`prob2`,`em2_0`,`em2_1`,`em2_2`,`em2_3`,`em2_4`,`em2_5`,`text3_0`,`text3_1`,`lang3`,`prob3`,`em3_0`,`em3_1`,`em3_2`,`em3_3`,`em3_4`,`em3_5`,`text4_0`,`text4_1`,`lang4`,`prob4`,`em4_0`,`em4_1`,`em4_2`,`em4_3`,`em4_4`,`em4_5`,`text5_0`,`text5_1`,`lang5`,`prob5`,`em5_0`,`em5_1`,`em5_2`,`em5_3`,`em5_4`,`em5_5`,`text6_0`,`text6_1`,`lang6`,`prob6`,`em6_0`,`em6_1`,`em6_2`,`em6_3`,`em6_4`,`em6_5`,`text7_0`,`text7_1`,`lang7`,`prob7`,`em7_0`,`em7_1`,`em7_2`,`em7_3`,`em7_4`,`em7_5`,`WDBVerified`) VALUES
+(9437,'<Warden Treelos looks at you funny and then pauses a moment, clearly struggling.>$B$BZangarmarsh... too close to truth.$B$B<His face goes crazy again.>$B$BIs he still watching!?','',0,1,1000,1,1000,6,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,12340),
+(9438,'What''s that? Zangarmarsh? Why would I want to go there?$B$B<Treelos looks thoughtful.>$B$BYes, Zangarmarsh... we... the druids there are getting close to figuring out why the water level is dropping. It''s destroying everything!$B$B<You can see the insanity creep back in behind the warden''s eyes.>$B$BDestroyed us all! Bright light! BOOM!!','',0,1,0,6,1000,1,1000,5,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,12340),
+(9439,'The Firewing blood elves... for some reason they want to stop us.$B$B<Warden Treelos visibly struggles to keep his wits about him for a few more seconds.>$B$BThey... they sent one of the Broken as ... as an emissary.... But he had a bomb!$B$BThey died, they all died! They tried to run away! The lucky ones didn''t even know.$B$BI must have been at the edge of the blast. It was horr...IT''S WATCHING US AGAIN!$B$B<Treelos becomes despondent and looks straight through you as if you''re not there.>','',0,1,0,18,1000,18,1000,5,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,12340),
+(12211,'Fine day fer sailin'', innit?','',7,1,0,1,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,12340),
+(12266,'','I''m almost jealous of our Mr. Wavesinger. Why, he may well be prettier than me!',7,1,0,1,3,11,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,'','',0,0,0,0,0,0,0,0,12340);
+
+-- Creature Gossip_menu_option insert from sniff
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (7692,7726,7727) AND `id`=0;
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (9038,9040,9041,9042,9043) AND `id` IN (0,1,2);
+DELETE FROM `gossip_menu_option` WHERE `menu_id`=9038 AND `id`=3;
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(7692,0,0,'Treelos, I know that the truth is somewhere inside you. Tell me what it is.',1,1,7726,0,0,0,''),
+(7726,0,0,'Keep it together man! What about Zangarmarsh?',1,1,7727,0,0,0,''),
+(7727,0,0,'I don''t have time for this! Warden, what happened?!',1,1,7728,0,0,0,''),
+(9038,0,0,'The Lady Mehley',1,1,9040,0,0,0,''),
+(9038,1,0,'Food & Drink',1,1,9041,0,0,0,''),
+(9038,2,0,'Goods & Gear',1,1,9042,0,0,0,''),
+(9038,3,0,'"Stash?"',1,1,9043,0,0,0,''),
+(9040,0,0,'Food & Drink',1,1,9041,0,0,0,''),
+(9040,1,0,'Goods & Gear',1,1,9042,0,0,0,''),
+(9040,2,0,'"Stash?',1,1,9043,0,0,0,''),
+(9041,0,0,'The Lady Mehley',1,1,9040,0,0,0,''),
+(9041,1,0,'Goods & Gear',1,1,9042,0,0,0,''),
+(9041,2,0,'"Stash?',1,1,9043,0,0,0,''),
+(9042,0,0,'The Lady Mehley',1,1,9040,0,0,0,''),
+(9042,1,0,'Food & Drink',1,1,9041,0,0,0,''),
+(9042,2,0,'"Stash?',1,1,9043,0,0,0,''),
+(9043,0,0,'The Lady Mehley',1,1,9040,0,0,0,''),
+(9043,1,0,'Food & Drink',1,1,9041,0,0,0,''),
+(9043,2,0,'Goods & Gear',1,1,9042,0,0,0,'');
+
+-- Conditions
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=7704 AND `SourceEntry`=9425;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=7696 AND `SourceEntry`=9444;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (7704,7692);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(14,7696,9444,0,0,8,10005,0,0,0,0,'','Show different gossip if player has rewarded quest 10005'),
+(14,7696,9444,0,1,8,10006,0,0,0,0,'','Show different gossip if player has rewarded quest 10006'),
+(14,7704,9425,0,0,8,9978,0,0,0,0,'','Show different gossip if player has rewarded quest 9978'),
+(15,7704,0,0,0,9,9978,0,0,0,0,'','Show gossip option if player has quest 9978 but not complete'),
+(15,7692,0,0,0,8,10006,0,0,0,0,'','Show gossip option if player has rewarded quest 10006'),
+(15,7692,0,0,1,8,10005,0,0,0,0,'','Show gossip option if player has rewarded quest 10005');
+
+-- Gossip Update from Malcrom
+DELETE FROM `gossip_menu` WHERE `entry` IN (1042,1043,1044,1045,1046,1047,1048,1049,1050,1052,1053);
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES
+(1042,1635),(1043,1640),(1044,1644),(1045,1643),(1045,1753),
+(1046,1648),(1047,1754),(1048,1650),(1049,1755),
+(1050,1651),(1050,1756),(1052,1652),(1053,1653);
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (1045,1047,1049,1050);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(1045,0,0,'Acquire Higher Level Access Card',1,1,0,0,0,0,''),
+(1047,0,0,'Acquire Higher Level Access Card',1,1,0,0,0,0,''),
+(1049,0,0,'Acquire Higher Level Access Card',1,1,0,0,0,0,''),
+(1050,0,0,'Acquire high level data card.',1,1,0,0,0,0,'');
+
+DELETE FROM `gossip_menu` WHERE `entry`=1080 AND `text_id`=1693;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1080,1693);
+DELETE FROM `gossip_menu` WHERE `entry`=1100 AND `text_id`=1713;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1100,1713);
+DELETE FROM `gossip_menu` WHERE `entry`=1143 AND `text_id`=1759;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1143,1759);
+DELETE FROM `gossip_menu` WHERE `entry`=1161 AND `text_id`=1793;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1161,1793);
+DELETE FROM `gossip_menu` WHERE `entry`=1162 AND `text_id`=1794;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1162,1794);
+DELETE FROM `gossip_menu` WHERE `entry`=1201 AND `text_id`=1833;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1201,1833);
+DELETE FROM `gossip_menu` WHERE `entry`=1281 AND `text_id`=1916;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1281,1916);
+DELETE FROM `gossip_menu` WHERE `entry`=1282 AND `text_id`=1918;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1282,1918);
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (1282);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(1282,0,0,'Touch the Suntara stone and call forth Lathoric the Black and his guardian, Obsidion.',1,1,0,0,0,0,'');
+
+DELETE FROM `gossip_menu` WHERE `entry`=1301 AND `text_id`=1933;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1301,1933);
+DELETE FROM `gossip_menu` WHERE `entry`=1301 AND `text_id`=1934;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1301,1934);
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (1301);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(1301,0,0,'I wish to browse your wares.',3,128,0,0,0,0,'');
+
+DELETE FROM `gossip_menu` WHERE `entry`=1302 AND `text_id`=1935;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1302,1935);
+DELETE FROM `gossip_menu` WHERE `entry`=1321 AND `text_id`=1955;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1321,1955);
+DELETE FROM `gossip_menu` WHERE `entry`=1322 AND `text_id`=1954;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1322,1954);
+DELETE FROM `gossip_menu` WHERE `entry`=1362 AND `text_id`=1994;
+INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1362,1994);
diff --git a/sql/updates/world/2012_02_22_00_world_SAI.sql b/sql/updates/world/2012_02_22_00_world_SAI.sql
new file mode 100644
index 00000000000..2e392f3a45f
--- /dev/null
+++ b/sql/updates/world/2012_02_22_00_world_SAI.sql
@@ -0,0 +1,39 @@
+-- SAI for Kalaran Windblade
+SET @ENTRY=8479;
+UPDATE `creature_template` SET `AIName`='SmartAI',`ScriptName`='' WHERE `entry`=@ENTRY;
+DELETE FROM `smart_scripts` WHERE (`entryorguid`=@ENTRY AND `source_type`=0);
+DELETE FROM `smart_scripts` WHERE (`entryorguid`=@ENTRY*100 AND `source_type`=9);
+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
+-- AI
+(@ENTRY,0,0,1,62,0,100,0,1321,0,0,0,26,3441,0,0,0,0,0,7,0,0,0,0,0,0,0,'Kalaran Windblade - On Gossip Option select - quest credit'),
+(@ENTRY,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Kalaran Windblade - On Gossip Option select - close gossip'),
+(@ENTRY,0,2,3,62,0,100,0,1323,2,0,0,11,19797,0,0,0,0,0,7,0,0,0,0,0,0,0,'Kalaran Windblade - On Gossip Option select - cast 19797'),
+(@ENTRY,0,3,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Kalaran Windblade - On Gossip Option select - close gossip'),
+(@ENTRY,0,4,0,62,0,100,0,1323,3,0,0,80,@ENTRY*100,0,0,0,0,0,1,0,0,0,0,0,0,0,'Kalaran Windblade - On Gossip Option select - run script'),
+-- Script
+(@ENTRY*100,9,0,0,0,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Kalaran Windblade - script - close gossip'),
+(@ENTRY*100,9,1,0,0,0,100,0,0,0,0,0,83,3,0,0,0,0,0,1,0,0,0,0,0,0,0,'Kalaran Windblade - script - remove npc flags'),
+(@ENTRY*100,9,2,0,0,0,100,0,1000,1000,1000,1000,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Kalaran Windblade - script - say 0'),
+(@ENTRY*100,9,3,0,0,0,100,0,1000,1000,1000,1000,17,69,0,0,0,0,0,1,0,0,0,0,0,0,0,'Kalaran Windblade - script - emotestate usestanding'),
+(@ENTRY*100,9,4,0,0,0,100,0,60000,60000,60000,60000,17,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Kalaran Windblade - script - emotestate none'),
+(@ENTRY*100,9,5,0,0,0,100,0,1000,1000,1000,1000,26,3453,0,0,0,0,0,7,0,0,0,0,0,0,0,'Kalaran Windblade - script - give quest credit'),
+(@ENTRY*100,9,6,0,0,0,100,0,1000,1000,1000,1000,82,3,0,0,0,0,0,1,0,0,0,0,0,0,0,'Kalaran Windblade - script - add npc flags');
+-- npc text
+DELETE FROM `creature_text` WHERE `entry`=@ENTRY;
+INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`) VALUES
+(@ENTRY,0,0,'Please be patient, $N',12,0,100,0,0,0,'Kalaran Windblade');
+-- Gossip options
+DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (1321,1322,1323);
+INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`)VALUES
+(1321,0,0,'Let me confer with my colleagues.',1,1,0,0,0,0,''),
+(1322,0,0,'Continue please.',1,1,1321,0,0,0,''),
+(1323,0,0,'Tell me what drives this vengeance?',1,1,1322,0,0,0,''),
+(1323,2,0,'Kalaran, I have misplaced my torch. I require another.',1,1,0,0,0,0,''),
+(1323,3,0,'Kalaran, please enchant the torch.',1,1,0,0,0,0,'');
+-- Gossip option conditions
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (1323);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(15,1323,0,0,0,9,3441,0,0,0,0,'','Show gossip option if player has quest 3441 but not complete'),
+(15,1323,2,0,0,8,3454,0,0,0,0,'','Show gossip option if player has quest 3441 complete'),
+(15,1323,2,0,0,2,10515,0,1,0,0,'','Show gossip option if player does not have item 10515'),
+(15,1323,3,0,0,9,3453,0,0,0,0,'','Show gossip option if player has quest 3453 but not complete');
diff --git a/sql/updates/world/2012_02_22_01_world_say_text.sql b/sql/updates/world/2012_02_22_01_world_say_text.sql
new file mode 100644
index 00000000000..035962e11c3
--- /dev/null
+++ b/sql/updates/world/2012_02_22_01_world_say_text.sql
@@ -0,0 +1,34 @@
+-- Invisible Stalker text for Wintergrasp from sniff
+DELETE FROM `creature_text` WHERE `entry`=15214;
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
+(15214,0,0, 'Let the battle begin!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,1,0, 'The Broken Temple siege workshop has been attacked by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,2,0, 'The Broken Temple siege workshop has been captured by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,3,0, 'The Broken Temple siege workshop has been attacked by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,4,0, 'The Broken Temple siege workshop has been captured by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,5,0, 'The Sunken Ring siege workshop has been attacked by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,6,0, 'The Sunken Ring siege workshop has been captured by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,7,0, 'The Sunken Ring siege workshop has been attacked by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,8,0, 'The Sunken Ring siege workshop has been captured by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,9,0, 'The Eastspark siege workshop has been attacked by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,10,0, 'The Eastspark siege workshop has been captured by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,11,0, 'The Eastspark siege workshop has been attacked by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,12,0, 'The Eastspark siege workshop has been captured by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,13,0, 'The Westspark siege workshop has been attacked by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,14,0, 'The Westspark siege workshop has been captured by the Horde!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,15,0, 'The Westspark siege workshop has been attacked by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,16,0, 'The Westspark siege workshop has been captured by the Alliance!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,17,0, 'The north-western keep tower has been damaged!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,18,0, 'The north-western keep tower has been destroyed!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,19,0, 'The south-eastern keep tower has been damaged!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,20,0, 'The south-eastern keep tower has been destroyed!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,21,0, 'The western tower has been damaged!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,22,0, 'The western tower has been destroyed!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,23,0, 'The southern tower has been damaged!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,24,0, 'The southern tower has been destroyed!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,25,0, 'The eastern tower has been damaged!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,26,0, 'The eastern tower has been destroyed!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,27,0, 'The Horde has defended Wintergrasp Fortress!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,28,0, 'The Horde has captured Wintergrasp Fortress!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,29,0, 'The Alliance has defended Wintergrasp Fortress!',41,0,100,0,0,0, 'Invisible Stalker'),
+(15214,30,0, 'The Alliance has captured Wintergrasp Fortress!',41,0,100,0,0,0, 'Invisible Stalker'); \ No newline at end of file
diff --git a/sql/updates/world/2012_02_22_02_world_misc.sql b/sql/updates/world/2012_02_22_02_world_misc.sql
new file mode 100644
index 00000000000..33bec2a9b78
--- /dev/null
+++ b/sql/updates/world/2012_02_22_02_world_misc.sql
@@ -0,0 +1,57 @@
+-- Mounting Hodir's Helm (12987)
+
+-- cleanup after Discovered
+-- clean all related to npc Hodir's Helm KC Bunny
+DELETE FROM `smart_scripts` WHERE `entryorguid`=30210 AND `source_type`=0;
+DELETE FROM `creature` WHERE `id`=30210;
+DELETE FROM `creature_text` WHERE `entry`=30210;
+
+SET @HELM := 192080; -- Hodir's Helm
+SET @TEMP := 300230; -- TEMP Northern Ice Spike
+SET @BUNNY_TARGET := 30215; -- Ice Spike Target Bunny
+SET @GUID_GO := 270; -- set by TDB
+SET @GUID_NPC := 40514; -- set by TDB
+SET @SPELL_READ_PRONOUNCEMENT := 56278;
+SET @QUEST := 12987;
+SET @AREA := 4438; -- Dun Niffelem
+SET @SPELL_AREA := 56305; -- See Quest Invisibility 1 (Ice Spike Bunny)
+SET @QUEST := 13006; -- Polishing the Helm
+
+UPDATE `creature_template` SET `unit_flags`=`unit_flags`|33554432|256,`InhabitType`=7,`flags_extra`=`flags_extra`|128 WHERE `entry`=@BUNNY_TARGET;
+
+UPDATE `gameobject_template` SET `flags`=`flags`|32 WHERE `entry`=@HELM;
+UPDATE `gameobject` SET `phaseMask`=4 WHERE `id`=@TEMP;
+
+DELETE FROM `gameobject` WHERE `guid`=@GUID_GO;
+INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES
+(@GUID_GO,@HELM,571,1,4,7390.143,-2725.382,874.2561,-3.089183,0,0,-0.9996567,0.02620165,600,255,1);
+
+DELETE FROM `creature` WHERE `guid` BETWEEN @GUID_NPC+0 AND @GUID_NPC+1;
+INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES
+(@GUID_NPC+0,@BUNNY_TARGET,571,1,4,0,0,7386.51,-2726.489,872.5089,5.88176,300,0,0,4979,0,0,0,0,0),
+(@GUID_NPC+1,@BUNNY_TARGET,571,1,4,0,0,7388.424,-2724.909,869.8643,0.5934119,300,0,0,4979,0,0,0,0,0);
+
+DELETE FROM `creature_template_addon` WHERE `entry`=@BUNNY_TARGET;
+INSERT INTO `creature_template_addon` (`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES
+(@BUNNY_TARGET,0,0,65536,1,0, '61333 56304 61334'); -- Gigantic Helm Sparkle / Hodir's Helm Bunny: Invisibility / Extra Large Helm Sparkle
+
+DELETE FROM `spell_script_names` WHERE `spell_id`=@SPELL_READ_PRONOUNCEMENT;
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(@SPELL_READ_PRONOUNCEMENT, 'spell_q12987_read_pronouncement');
+
+DELETE FROM `spell_area` WHERE `spell`=@SPELL_AREA;
+INSERT INTO `spell_area` (`spell`,`area`,`quest_start`,`quest_start_active`,`quest_end`,`aura_spell`,`racemask`,`gender`,`autocast`) VALUES
+(@SPELL_AREA,@AREA,@QUEST,1,@QUEST,0,0,2,1);
+
+-- relation for the daily quest that should be available after finishing Mounting Hodir's Helm
+
+-- removing flag 4 or else player can't interract with Q giver
+UPDATE `gameobject_template` SET `flags`=`flags`&~4 WHERE `entry`=@HELM;
+
+DELETE FROM `gameobject_questrelation` WHERE `id`=@HELM;
+INSERT INTO `gameobject_questrelation` (`id`,`quest`) VALUES
+(@HELM,@QUEST);
+
+DELETE FROM `gameobject_involvedrelation` WHERE `id`=@HELM;
+INSERT INTO `gameobject_involvedrelation` (`id`,`quest`) VALUES
+(@HELM,@QUEST);
diff --git a/sql/updates/world/2012_02_22_03_world_conditions.sql b/sql/updates/world/2012_02_22_03_world_conditions.sql
new file mode 100644
index 00000000000..9c4d0cdec95
--- /dev/null
+++ b/sql/updates/world/2012_02_22_03_world_conditions.sql
@@ -0,0 +1,3 @@
+UPDATE `conditions` SET `SourceTypeOrReferenceId`=13 WHERE `SourceTypeOrReferenceId`=17 AND `SourceGroup`=1;
+UPDATE `conditions` SET `ConditionValue2`=1 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=1323 AND `SourceEntry`=2 AND `ConditionTypeOrReference`=2;
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=1 AND `SourceGroup`=17465 AND `SourceEntry`=22554 AND `ConditionTypeOrReference`=7;
diff --git a/sql/updates/world/2012_02_23_00_world_spell_script_names.sql b/sql/updates/world/2012_02_23_00_world_spell_script_names.sql
new file mode 100644
index 00000000000..6ea96033091
--- /dev/null
+++ b/sql/updates/world/2012_02_23_00_world_spell_script_names.sql
@@ -0,0 +1,7 @@
+DELETE FROM `spell_script_names` WHERE `spell_id` in (11885,11886,11887,11888,11889);
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(11885,'spell_item_muisek_vessel'),
+(11886,'spell_item_muisek_vessel'),
+(11887,'spell_item_muisek_vessel'),
+(11888,'spell_item_muisek_vessel'),
+(11889,'spell_item_muisek_vessel');
diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp
index 1abbc59a5b0..1c3a0aa639e 100644
--- a/src/server/collision/Models/GameObjectModel.cpp
+++ b/src/server/collision/Models/GameObjectModel.cpp
@@ -33,6 +33,8 @@ using G3D::Vector3;
using G3D::Ray;
using G3D::AABox;
+#ifndef NO_CORE_FUNCS
+
struct GameobjectModelData
{
GameobjectModelData(const std::string& name_, const AABox& box) :
@@ -47,23 +49,30 @@ ModelList model_list;
void LoadGameObjectModelList()
{
+ uint32 oldMSTime = getMSTime();
FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
if (!model_list_file)
+ {
+ sLog->outError("Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS);
return;
+ }
uint32 name_length, displayId;
char buff[500];
- while (!feof(model_list_file))
+ while (true)
{
Vector3 v1, v2;
- if (fread(&displayId, sizeof(uint32), 1, model_list_file) != 1
- || fread(&name_length, sizeof(uint32), 1, model_list_file) != 1
+ if (fread(&displayId, sizeof(uint32), 1, model_list_file) != 1)
+ if (feof(model_list_file)) // EOF flag is only set after failed reading attempt
+ break;
+
+ if (fread(&name_length, sizeof(uint32), 1, model_list_file) != 1
|| name_length >= sizeof(buff)
|| fread(&buff, sizeof(char), name_length, model_list_file) != name_length
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
{
- printf("\nFile '%s' seems to be corrupted", VMAP::GAMEOBJECT_MODELS);
+ sLog->outError("File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
break;
}
@@ -72,7 +81,10 @@ void LoadGameObjectModelList()
ModelList::value_type( displayId, GameobjectModelData(std::string(buff,name_length),AABox(v1,v2)) )
);
}
+
fclose(model_list_file);
+ sLog->outString(">> Loaded %u GameObject models in %u ms", model_list.size(), GetMSTimeDiffToNow(oldMSTime));
+ sLog->outString();
}
GameObjectModel::~GameObjectModel()
@@ -91,7 +103,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
// ignore models with no bounds
if (mdl_box == G3D::AABox::zero())
{
- std::cout << "Model " << it->second.name << " has zero bounds, loading skipped" << std::endl;
+ sLog->outError("GameObject model %s has zero bounds, loading skipped", it->second.name.c_str());
return false;
}
@@ -171,3 +183,5 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
}
return hit;
}
+
+#endif
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 048cc8b3d68..01e13b29f19 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -307,11 +307,7 @@ void npc_escortAI::MovementInform(uint32 moveType, uint32 pointId)
{
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI has returned to original position before combat");
- if (m_bIsRunning && me->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
- else if (!m_bIsRunning && !me->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
-
+ me->SetWalk(!m_bIsRunning);
RemoveEscortState(STATE_ESCORT_RETURNING);
if (!m_uiWPWaitTimer)
@@ -400,14 +396,14 @@ void npc_escortAI::SetRun(bool on)
if (on)
{
if (!m_bIsRunning)
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
else
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI attempt to set run mode, but is already running.");
}
else
{
if (m_bIsRunning)
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
else
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: EscortAI attempt to set walk mode, but is already walking.");
}
@@ -473,9 +469,9 @@ void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false
//Set initial speed
if (m_bIsRunning)
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
else
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
AddEscortState(STATE_ESCORT_ESCORTING);
}
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 7838e6891fe..8776090c86f 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -45,7 +45,7 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c)
mCanRepeatPath = false;
// spawn in run mode
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
mRun = false;
me->GetPosition(&mLastOOCPos);
@@ -720,9 +720,9 @@ uint64 SmartAI::GetGUID(int32 /*id*/)
void SmartAI::SetRun(bool run)
{
if (run)
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
else
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
mRun = run;
}
@@ -731,12 +731,12 @@ void SmartAI::SetFly(bool fly)
{
if (fly)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
}
else
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
}
me->SetFlying(fly);
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 95574e6d21d..67d26ea06dd 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -482,7 +482,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) ? true : false);
else
- sLog->outDebug(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: %u Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*itr)->GetGUID(), (*itr)->GetEntry(), uint32((*itr)->GetTypeId()));
+ sLog->outDebug(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*itr)->GetGUID(), (*itr)->GetEntry(), uint32((*itr)->GetTypeId()));
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_CAST:: Creature %u casts spell %u on target %u with castflags %u",
me->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags);
}
@@ -511,7 +511,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) ? true : false);
else
- sLog->outDebug(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: %u Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*itr)->GetGUID(), (*itr)->GetEntry(), uint32((*itr)->GetTypeId()));
+ sLog->outDebug(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*itr)->GetGUID(), (*itr)->GetEntry(), uint32((*itr)->GetTypeId()));
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %u casts spell %u on target %u with castflags %u",
tempLastInvoker->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags);
@@ -1576,7 +1576,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.cast.spell))
(*itr)->ToUnit()->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) ? true : false);
else
- sLog->outDebug(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: %u Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*it)->GetGUID(), (*it)->GetEntry(), uint32((*it)->GetTypeId()));
+ sLog->outDebug(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*it)->GetGUID(), (*it)->GetEntry(), uint32((*it)->GetTypeId()));
}
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index f99e317454c..4105012ac86 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -62,27 +62,19 @@ void SmartWaypointMgr::LoadFromDB()
y = fields[3].GetFloat();
z = fields[4].GetFloat();
- WayPoint* wp = new WayPoint(id, x, y, z);
-
if (last_entry != entry)
{
- path = new WPPath;
+ waypoint_map[entry] = new WPPath();
last_id = 1;
+ count++;
}
if (last_id != id)
- {
sLog->outErrorDb("SmartWaypointMgr::LoadFromDB: Path entry %u, unexpected point id %u, expected %u.", entry, id, last_id);
- }
last_id++;
- (*path)[id] = wp;
+ (*waypoint_map[entry])[id] = new WayPoint(id, x, y, z);
- if (last_entry != entry)
- {
- count++;
- waypoint_map[entry] = path;
- }
last_entry = entry;
total++;
}
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 02707261d13..a5c34e4b7ee 100755
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -295,8 +295,10 @@ void ArenaTeam::SetCaptain(uint64 guid)
if (newCaptain)
{
newCaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 0);
+ char const* oldCaptainName = oldCaptain ? oldCaptain->GetName() : "";
+ uint32 oldCaptainLowGuid = oldCaptain ? oldCaptain->GetGUIDLow() : 0;
sLog->outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].",
- oldCaptain->GetName(), oldCaptain->GetGUIDLow(), newCaptain->GetName(), newCaptain->GetGUIDLow(), GetId(), GetType());
+ oldCaptainName, oldCaptainLowGuid, newCaptain->GetName(), newCaptain->GetGUIDLow(), GetId(), GetType());
}
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index 801b522feab..5ea9fc67fed 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -1032,17 +1032,18 @@ void BattlegroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
std::vector<uint64> ghost_list = m_ReviveQueue[BgCreatures[node]];
if (!ghost_list.empty())
{
- Player* player;
- WorldSafeLocsEntry const* ClosestGrave = NULL;
+ Player* waitingPlayer; // player waiting at graveyard for resurrection
+ WorldSafeLocsEntry const* closestGrave = NULL;
for (std::vector<uint64>::iterator itr = ghost_list.begin(); itr != ghost_list.end(); ++itr)
{
- player = ObjectAccessor::FindPlayer(*ghost_list.begin());
- if (!player)
+ waitingPlayer = ObjectAccessor::FindPlayer(*ghost_list.begin());
+ if (!waitingPlayer)
continue;
- if (!ClosestGrave)
- ClosestGrave = GetClosestGraveYard(player);
+
+ if (!closestGrave)
+ closestGrave = GetClosestGraveYard(waitingPlayer);
else
- player->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, player->GetOrientation());
+ waitingPlayer->TeleportTo(GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation());
}
m_ReviveQueue[BgCreatures[node]].clear();
}
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 550814ccf3f..7d21f94f372 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -26,6 +26,7 @@
#include "ConditionMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "Spell.h"
// Checks if object meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
@@ -94,14 +95,14 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
}
case CONDITION_CLASS:
{
- if (Player* player = object->ToPlayer())
- condMeets = player->getClassMask() & ConditionValue1;
+ if (Unit* unit = object->ToUnit())
+ condMeets = unit->getClassMask() & ConditionValue1;
break;
}
case CONDITION_RACE:
{
- if (Player* player = object->ToPlayer())
- condMeets = player->getRaceMask() & ConditionValue1;
+ if (Unit* unit = object->ToUnit())
+ condMeets = unit->getRaceMask() & ConditionValue1;
break;
}
case CONDITION_SKILL:
@@ -153,9 +154,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
condMeets = ((InstanceMap*)map)->GetInstanceScript()->GetData(ConditionValue1) == ConditionValue2;
break;
}
- case CONDITION_SPELL_SCRIPT_TARGET:
- condMeets = true;//spell target condition is handled in spellsystem, here it is always true
- break;
case CONDITION_MAPID:
condMeets = object->GetMapId() == ConditionValue1;
break;
@@ -291,12 +289,153 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
return condMeets && script;
}
+uint32 Condition::GetSearcherTypeMaskForCondition()
+{
+ // build mask of types for which condition can return true
+ // this is used for speeding up gridsearches
+ if (NegativeCondition)
+ return (GRID_MAP_TYPE_MASK_ALL);
+ uint32 mask = 0;
+ switch (ConditionType)
+ {
+ case CONDITION_NONE:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_AURA:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_ITEM:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_ITEM_EQUIPPED:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_ZONEID:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_REPUTATION_RANK:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_ACHIEVEMENT:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_TEAM:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_CLASS:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_RACE:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_SKILL:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_QUESTREWARDED:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_QUESTTAKEN:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_QUEST_COMPLETE:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_QUEST_NONE:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_ACTIVE_EVENT:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_INSTANCE_DATA:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_MAPID:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_AREAID:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_SPELL:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_LEVEL:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_DRUNKENSTATE:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_NEAR_CREATURE:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_NEAR_GAMEOBJECT:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_OBJECT_ENTRY:
+ switch (ConditionValue1)
+ {
+ case TYPEID_UNIT:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE;
+ break;
+ case TYPEID_PLAYER:
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case TYPEID_GAMEOBJECT:
+ mask |= GRID_MAP_TYPE_MASK_GAMEOBJECT;
+ break;
+ case TYPEID_CORPSE:
+ mask |= GRID_MAP_TYPE_MASK_CORPSE;
+ break;
+ default:
+ break;
+ }
+ case CONDITION_TYPE_MASK:
+ if (ConditionValue1 & TYPEMASK_UNIT)
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ if (ConditionValue1 & TYPEMASK_PLAYER)
+ mask |= GRID_MAP_TYPE_MASK_PLAYER;
+ if (ConditionValue1 & TYPEMASK_GAMEOBJECT)
+ mask |= GRID_MAP_TYPE_MASK_GAMEOBJECT;
+ if (ConditionValue1 & TYPEMASK_CORPSE)
+ mask |= GRID_MAP_TYPE_MASK_CORPSE;
+ break;
+ case CONDITION_RELATION_TO:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_REACTION_TO:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_DISTANCE_TO:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_ALIVE:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_HP_VAL:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_HP_PCT:
+ mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
+ break;
+ case CONDITION_WORLD_STATE:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ case CONDITION_PHASEMASK:
+ mask |= GRID_MAP_TYPE_MASK_ALL;
+ break;
+ default:
+ ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!");
+ break;
+ }
+ return mask;
+}
+
uint32 Condition::GetMaxAvailableConditionTargets()
{
// returns number of targets which are available for given source type
switch(SourceType)
{
case CONDITION_SOURCE_TYPE_SPELL:
+ case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET:
case CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE:
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
@@ -327,8 +466,49 @@ ConditionList ConditionMgr::GetConditionReferences(uint32 refId)
return conditions;
}
+uint32 ConditionMgr::GetSearcherTypeMaskForConditionList(ConditionList const& conditions)
+{
+ if (conditions.empty())
+ return GRID_MAP_TYPE_MASK_ALL;
+ // groupId, typeMask
+ std::map<uint32, uint32> ElseGroupStore;
+ for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
+ {
+ // no point of having not loaded conditions in list
+ ASSERT((*i)->isLoaded() && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list");
+ std::map<uint32, uint32>::const_iterator itr = ElseGroupStore.find((*i)->ElseGroup);
+ // group not filled yet, fill with widest mask possible
+ if (itr == ElseGroupStore.end())
+ ElseGroupStore[(*i)->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
+ // no point of checking anymore, empty mask
+ else if (!(*itr).second)
+ continue;
+
+ if ((*i)->ReferenceId) // handle reference
+ {
+ ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
+ ASSERT(ref != ConditionReferenceStore.end() && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference");
+ ElseGroupStore[(*i)->ElseGroup] &= GetSearcherTypeMaskForConditionList((*ref).second);
+ }
+ else // handle normal condition
+ {
+ // object will match conditions in one ElseGroupStore only when it matches all of them
+ // so, let's find a smallest possible mask which satisfies all conditions
+ ElseGroupStore[(*i)->ElseGroup] &= (*i)->GetSearcherTypeMaskForCondition();
+ }
+ }
+ // object will match condition when one of the checks in ElseGroupStore is matching
+ // so, let's include all possible masks
+ uint32 mask = 0;
+ for (std::map<uint32, uint32>::const_iterator i = ElseGroupStore.begin(); i != ElseGroupStore.end(); ++i)
+ mask |= i->second;
+
+ return mask;
+}
+
bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
{
+ // groupId, groupCheckPassed
std::map<uint32, bool> ElseGroupStore;
for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
{
@@ -391,6 +571,33 @@ bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, Con
return IsObjectMeetToConditionList(sourceInfo, conditions);
}
+bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
+{
+ return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE ||
+ sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
+ sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION ||
+ sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
+ sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET ||
+ sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
+ sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
+}
+
+bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const
+{
+ return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
+}
+
ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry)
{
ConditionList spellCond;
@@ -487,6 +694,7 @@ void ConditionMgr::LoadConditions(bool isReload)
sLog->outString("Re-Loading `gossip_menu_option` Table for Conditions!");
sObjectMgr->LoadGossipMenuItems();
+ sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
}
QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
@@ -583,16 +791,23 @@ void ConditionMgr::LoadConditions(bool isReload)
}
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
- if (cond->SourceGroup && !isGroupable(cond->SourceType))
+ if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType))
+ {
+ sLog->outErrorDb("Condition type %u has not allowed value of SourceGroup = %u!", uint32(cond->SourceType), cond->SourceGroup);
+ delete cond;
+ continue;
+ }
+ if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType))
{
- sLog->outErrorDb("Condition type %u has not allowed grouping %u!", uint32(cond->SourceType), cond->SourceGroup);
+ sLog->outErrorDb("Condition type %u has not allowed value of SourceId = %u!", uint32(cond->SourceType), cond->SourceId);
delete cond;
continue;
}
- else if (cond->SourceGroup)
+
+ if (cond->SourceGroup)
{
bool valid = false;
- //handle grouped conditions
+ // handle grouped conditions
switch (cond->SourceType)
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE:
@@ -637,6 +852,29 @@ void ConditionMgr::LoadConditions(bool isReload)
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
valid = addToGossipMenuItems(cond);
break;
+ case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
+ {
+ //if no list for npc create one
+ if (SpellClickEventConditionStore.find(cond->SourceGroup) == SpellClickEventConditionStore.end())
+ {
+ ConditionTypeContainer cmap;
+ SpellClickEventConditionStore[cond->SourceGroup] = cmap;
+ }
+ //if no list for spellclick spell create one
+ if (SpellClickEventConditionStore[cond->SourceGroup].find(cond->SourceEntry) == SpellClickEventConditionStore[cond->SourceGroup].end())
+ {
+ ConditionList clist;
+ SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry] = clist;
+ }
+ SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
+ valid = true;
+ ++count;
+ continue; // do not add to m_AllocatedMemory to avoid double deleting
+ break;
+ }
+ case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET:
+ valid = addToSpellImplicitTargetConditions(cond);
+ break;
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
{
//if no list for vehicle create one
@@ -771,6 +1009,78 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond)
return false;
}
+bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
+{
+ uint32 conditionEffMask = cond->SourceGroup;
+ SpellInfo* spellInfo = const_cast<SpellInfo*>(sSpellMgr->GetSpellInfo(cond->SourceEntry));
+ ASSERT(spellInfo);
+ std::list<uint32> sharedMasks;
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ // check if effect is already a part of some shared mask
+ bool found = false;
+ for (std::list<uint32>::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr)
+ {
+ if ((1<<i) & *itr)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ // build new shared mask with found effect
+ uint32 sharedMask = (1<<i);
+ ConditionList* cmp = spellInfo->Effects[i].ImplicitTargetConditions;
+ for (uint8 effIndex = i+1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ {
+ if (spellInfo->Effects[effIndex].ImplicitTargetConditions == cmp)
+ sharedMask |= 1<<effIndex;
+ }
+ sharedMasks.push_back(sharedMask);
+ }
+
+ for (std::list<uint32>::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr)
+ {
+ // some effect indexes should have same data
+ if (uint32 commonMask = *itr & conditionEffMask)
+ {
+ uint8 firstEffIndex = 0;
+ for (; firstEffIndex < MAX_SPELL_EFFECTS; ++firstEffIndex)
+ if ((1<<firstEffIndex) & *itr)
+ break;
+
+ // get shared data
+ ConditionList* sharedList = spellInfo->Effects[firstEffIndex].ImplicitTargetConditions;
+
+ // there's already data entry for that sharedMask
+ if (sharedList)
+ {
+ // we have overlapping masks in db
+ if (conditionEffMask != *itr)
+ {
+ sLog->outErrorDb("SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
+ "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->SourceEntry, cond->SourceGroup);
+ return false;
+ }
+ }
+ // no data for shared mask, we can create new submask
+ else
+ {
+ // add new list, create new shared mask
+ sharedList = new ConditionList();
+ for (uint8 i = firstEffIndex; i < MAX_SPELL_EFFECTS; ++i)
+ if ((1<<i) & commonMask)
+ spellInfo->Effects[i].ImplicitTargetConditions = sharedList;
+ }
+ sharedList->push_back(cond);
+ break;
+ }
+ }
+ return true;
+}
+
bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX)
@@ -985,64 +1295,54 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
}
break;
}
- case CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET:
+ case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET:
{
- if (cond->ConditionType != CONDITION_SPELL_SCRIPT_TARGET)
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry);
+ if (!spellInfo)
{
- sLog->outErrorDb("SourceEntry %u in `condition` table, has ConditionType %u. Only CONDITION_SPELL_SCRIPT_TARGET(18) is valid for CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET(14), ignoring.", cond->SourceEntry, uint32(cond->ConditionType));
+ sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
return false;
}
- SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry);
- if (!spellProto)
+ if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup)
{
- sLog->outErrorDb("SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ sLog->outErrorDb("SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set , ignoring.", cond->SourceEntry, cond->SourceGroup);
return false;
}
- bool targetfound = false;
+ uint32 origGroup = cond->SourceGroup;
+
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (spellProto->Effects[i].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENTRY ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_UNIT_SRC_AREA_ENTRY ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENTRY ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ENTRY ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_UNIT_NEARBY_ENTRY ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_UNIT_NEARBY_ENTRY ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_GAMEOBJECT_NEARBY_ENTRY ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_SRC_AREA ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_GAMEOBJECT_SRC_AREA ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_DEST_AREA ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_GAMEOBJECT_DEST_AREA ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_DEST_NEARBY_ENTRY ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_DEST_NEARBY_ENTRY ||
- spellProto->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CONE_ENTRY ||
- spellProto->Effects[i].TargetB.GetTarget() == TARGET_UNIT_CONE_ENTRY)
+ if (!((1<<i) & cond->SourceGroup))
+ continue;
+
+ switch (spellInfo->Effects[i].TargetA.GetSelectionCategory())
{
- targetfound = true;
- //break;
+ case TARGET_SELECT_CATEGORY_NEARBY:
+ case TARGET_SELECT_CATEGORY_CONE:
+ case TARGET_SELECT_CATEGORY_AREA:
+ continue;
+ default:
+ break;
}
- else if (cond->ConditionValue3 & (1 << i))
+
+ switch (spellInfo->Effects[i].TargetB.GetSelectionCategory())
{
- cond->ConditionValue3 &= ~(1 << i);
- sLog->outErrorDb("SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DEST_NEARBY_ENTRY (46)"
- ", TARGET_UNIT_SRC_AREA_ENTRY(7), TARGET_UNIT_DEST_AREA_ENTRY(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
- "TARGET_GAMEOBJECT_SRC_AREA(51), TARGET_GAMEOBJECT_DEST_AREA(52) in effect %u", cond->SourceEntry, uint32(i));
+ case TARGET_SELECT_CATEGORY_NEARBY:
+ case TARGET_SELECT_CATEGORY_CONE:
+ case TARGET_SELECT_CATEGORY_AREA:
+ continue;
+ default:
+ break;
}
+
+ sLog->outErrorDb("SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i));
+ cond->SourceGroup &= ~(1<<i);
}
- if (!targetfound && !cond->ConditionValue3) // cond->mConditionValue3 already errored up there
- {
- sLog->outErrorDb("SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DEST_NEARBY_ENTRY (46)"
- ", TARGET_UNIT_SRC_AREA_ENTRY(7), TARGET_UNIT_DEST_AREA_ENTRY(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
- "TARGET_GAMEOBJECT_SRC_AREA(51), TARGET_GAMEOBJECT_DEST_AREA(52)", cond->SourceEntry);
+ // all effects were removed, no need to add the condition at all
+ if (!cond->SourceGroup)
return false;
- }
- if ((cond->ConditionValue1 == SPELL_TARGET_TYPE_DEAD) && !spellProto->IsAllowingDeadTarget())
- {
- sLog->outErrorDb("SourceEntry %u in `condition` table does have SPELL_TARGET_TYPE_DEAD specified but spell does not have SPELL_ATTR2_CAN_TARGET_DEAD", cond->SourceEntry);
- return false;
- }
break;
}
case CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE:
@@ -1318,46 +1618,6 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog->outErrorDb("Race condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
- case CONDITION_SPELL_SCRIPT_TARGET:
- {
- if (cond->ConditionValue1 >= MAX_SPELL_TARGET_TYPE)
- {
- sLog->outErrorDb("SpellTarget condition has non existing spell target type (%u), skipped", cond->ConditionValue1);
- return false;
- }
-
- switch (cond->ConditionValue1)
- {
- case SPELL_TARGET_TYPE_GAMEOBJECT:
- {
- if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2))
- {
- sLog->outErrorDb("SpellTarget condition has non existing gameobject (%u) as target, skipped", cond->ConditionValue2);
- return false;
- }
- break;
- }
- case SPELL_TARGET_TYPE_CONTROLLED:
- case SPELL_TARGET_TYPE_CREATURE:
- case SPELL_TARGET_TYPE_DEAD:
- {
- if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2))
- {
- sLog->outErrorDb("SpellTarget condition has non existing creature template entry (%u) as target, skipped", cond->ConditionValue2);
- return false;
- }
-
- const CreatureTemplate* cInfo = sObjectMgr->GetCreatureTemplate(cond->ConditionValue2);
- if (cond->SourceEntry == 30427 && !cInfo->SkinLootId)
- {
- sLog->outErrorDb("SpellTarget condition has creature entry %u as a target of spellid 30427, but this creature has no skinlootid. Gas extraction will not work!, skipped", cond->ConditionValue2);
- return false;
- }
- break;
- }
- }
- break;
- }
case CONDITION_MAPID:
{
MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1);
@@ -1598,6 +1858,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
sLog->outErrorDb("Phasemask condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
+ case CONDITION_UNUSED_18:
+ sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_18 in `conditions` table - ignoring");
+ return false;
case CONDITION_UNUSED_19:
sLog->outErrorDb("Found ConditionTypeOrReference = CONDITION_UNUSED_19 in `conditions` table - ignoring");
return false;
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 9911aa2a98a..5a5e2dd1c2e 100755
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -48,7 +48,7 @@ enum ConditionTypes
CONDITION_CLASS = 15, // class 0 0 true if player's class is equal to class
CONDITION_RACE = 16, // race 0 0 true if player's race is equal to race
CONDITION_ACHIEVEMENT = 17, // achievement_id 0 0 true if achievement is complete
- CONDITION_SPELL_SCRIPT_TARGET = 18, // SpellScriptTargetType, TargetEntry, 0
+ CONDITION_UNUSED_18 = 18, //
CONDITION_UNUSED_19 = 19, //
CONDITION_UNUSED_20 = 20, //
CONDITION_UNUSED_21 = 21, //
@@ -87,7 +87,7 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE = 10,
CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE = 11,
CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE = 12,
- CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET = 13,
+ CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET = 13,
CONDITION_SOURCE_TYPE_GOSSIP_MENU = 14,
CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION = 15,
CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE = 16,
@@ -173,6 +173,7 @@ struct Condition
}
bool Meets(ConditionSourceInfo& sourceInfo);
+ uint32 GetSearcherTypeMaskForCondition();
bool isLoaded() const { return ConditionType > CONDITION_NONE || ReferenceId; }
uint32 GetMaxAvailableConditionTargets();
};
@@ -198,9 +199,12 @@ class ConditionMgr
bool isConditionTypeValid(Condition* cond);
ConditionList GetConditionReferences(uint32 refId);
+ uint32 GetSearcherTypeMaskForConditionList(ConditionList const& conditions);
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions);
bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions);
bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
+ bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const;
+ bool CanHaveSourceIdSet(ConditionSourceType sourceType) const;
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
@@ -211,29 +215,9 @@ class ConditionMgr
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
bool addToGossipMenus(Condition* cond);
bool addToGossipMenuItems(Condition* cond);
+ bool addToSpellImplicitTargetConditions(Condition* cond);
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
- bool isGroupable(ConditionSourceType sourceType) const
- {
- return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE ||
- sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
- sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION ||
- sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
- sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
- sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
- }
-
void Clean(); // free up resources
std::list<Condition*> AllocatedMemoryStore; // some garbage collection :)
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 3dfa1cece61..20bcfc8f41c 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2408,24 +2408,24 @@ bool Creature::IsDungeonBoss() const
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
-void Creature::SetWalk(bool enable)
+bool Creature::SetWalk(bool enable)
{
- if (enable)
- AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ if (!Unit::SetWalk(enable))
+ return false;
+
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, true);
+ return true;
}
-void Creature::SetLevitate(bool enable)
+bool Creature::SetLevitate(bool enable)
{
- if (enable)
- AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ if (!Unit::SetLevitate(enable))
+ return false;
+
WorldPacket data(enable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, true);
+ return true;
}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index bfe186329e1..40477de7c75 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -520,8 +520,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI* AI() const { return (CreatureAI*)i_AI; }
- void SetWalk(bool enable);
- void SetLevitate(bool enable);
+ bool SetWalk(bool enable);
+ bool SetLevitate(bool enable);
uint32 GetShieldBlockValue() const //dunno mob block value
{
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index f440fd497fc..c95d77db358 100755
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -240,7 +240,7 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z)
if (member->IsWithinDist(m_leader, dist + MAX_DESYNC))
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
else
- member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ member->SetWalk(false);
member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
member->SetHomePosition(dx, dy, dz, pathangle);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index aadf9f44b0b..c98364ecb2d 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1085,9 +1085,9 @@ bool Object::PrintIndexError(uint32 index, bool set) const
return false;
}
-bool Position::HasInLine(Unit const* target, float distance, float width) const
+bool Position::HasInLine(WorldObject const* target, float width) const
{
- if (!HasInArc(M_PI, target) || !target->IsWithinDist3d(m_positionX, m_positionY, m_positionZ, distance))
+ if (!HasInArc(M_PI, target))
return false;
width += target->GetObjectSize();
float angle = GetRelativeAngle(target);
@@ -1502,14 +1502,14 @@ bool WorldObject::IsInBetween(const WorldObject* obj1, const WorldObject* obj2,
return (size * size) >= GetExactDist2dSq(obj1->GetPositionX() + cos(angle) * dist, obj1->GetPositionY() + sin(angle) * dist);
}
-bool WorldObject::isInFront(WorldObject const* target, float distance, float arc) const
+bool WorldObject::isInFront(WorldObject const* target, float arc) const
{
- return IsWithinDist(target, distance) && HasInArc(arc, target);
+ return HasInArc(arc, target);
}
-bool WorldObject::isInBack(WorldObject const* target, float distance, float arc) const
+bool WorldObject::isInBack(WorldObject const* target, float arc) const
{
- return IsWithinDist(target, distance) && !HasInArc(2 * M_PI - arc, target);
+ return !HasInArc(2 * M_PI - arc, target);
}
void WorldObject::GetRandomPoint(const Position &pos, float distance, float &rand_x, float &rand_y, float &rand_z) const
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index c14b7599d5f..7b3fcc4a337 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -451,7 +451,7 @@ struct Position
bool IsInDist(const Position* pos, float dist) const
{ return GetExactDistSq(pos) < dist * dist; }
bool HasInArc(float arcangle, const Position* pos) const;
- bool HasInLine(Unit const* target, float distance, float width) const;
+ bool HasInLine(WorldObject const* target, float width) const;
std::string ToString() const;
};
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
@@ -707,8 +707,8 @@ class WorldObject : public Object, public WorldLocation
bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const;
bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const;
- bool isInFront(WorldObject const* target, float distance, float arc = M_PI) const;
- bool isInBack(WorldObject const* target, float distance, float arc = M_PI) const;
+ bool isInFront(WorldObject const* target, float arc = M_PI) const;
+ bool isInBack(WorldObject const* target, float arc = M_PI) const;
bool IsInBetween(const WorldObject* obj1, const WorldObject* obj2, float size = 0) const;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index fde4f4c6959..632453a230f 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -7944,14 +7944,12 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
_ApplyWeaponDamage(slot, proto, ssv, apply);
// Apply feral bonus from ScalingStatValue if set
- if (ssv)
- if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue))
- ApplyFeralAPBonus(feral_bonus, apply);
-
- // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue)
- if (getClass() == CLASS_DRUID)
- if (int32 feral_bonus = proto->getFeralBonus(ssv->getDPSMod(proto->ScalingStatValue)))
+ if (ssv && getClass() == CLASS_DRUID)
+ {
+ int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue) + proto->getFeralBonus(ssv->getDPSMod(proto->ScalingStatValue));
+ if (feral_bonus)
ApplyFeralAPBonus(feral_bonus, apply);
+ }
}
void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply)
@@ -14071,12 +14069,10 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
menuItemBounds = sObjectMgr->GetGossipMenuItemsMapBounds(0);
uint32 npcflags = 0;
- Creature* creature = NULL;
if (source->GetTypeId() == TYPEID_UNIT)
{
- creature = source->ToCreature();
- npcflags = creature->GetUInt32Value(UNIT_NPC_FLAGS);
+ npcflags = source->GetUInt32Value(UNIT_NPC_FLAGS);
if (npcflags & UNIT_NPC_FLAG_QUESTGIVER && showQuests)
PrepareQuestMenu(source->GetGUID());
}
@@ -14091,7 +14087,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
if (!sConditionMgr->IsObjectMeetToConditions(this, source, itr->second.Conditions))
continue;
- if (source->GetTypeId() == TYPEID_UNIT)
+ if (Creature* creature = source->ToCreature())
{
if (!(itr->second.OptionNpcflag & npcflags))
continue;
@@ -14164,10 +14160,8 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
break;
}
}
- else if (source->GetTypeId() == TYPEID_GAMEOBJECT)
+ else if (GameObject* go = source->ToGameObject())
{
- GameObject* go = source->ToGameObject();
-
switch (itr->second.OptionType)
{
case GOSSIP_OPTION_GOSSIP:
@@ -16002,9 +15996,9 @@ void Player::CastedCreatureOrGO(uint32 entry, uint64 guid, uint32 spell_id)
if (reqTarget != entry) // if entry doesn't match, check for killcredits referenced in template
{
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
- for (uint8 j = 0; j < MAX_KILL_CREDIT; ++j)
- if (cinfo->KillCredit[j] == reqTarget)
- entry = cinfo->KillCredit[j];
+ for (uint8 k = 0; k < MAX_KILL_CREDIT; ++k)
+ if (cinfo->KillCredit[k] == reqTarget)
+ entry = cinfo->KillCredit[k];
}
}
}
@@ -17649,7 +17643,7 @@ void Player::_LoadMailedItems(Mail* mail)
{
sLog->outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), itemGuid, itemTemplate, mail->messageID);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
stmt->setUInt32(0, itemGuid);
CharacterDatabase.Execute(stmt);
@@ -17665,10 +17659,8 @@ void Player::_LoadMailedItems(Mail* mail)
{
sLog->outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, itemGuid);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM);
-
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM);
stmt->setUInt32(0, itemGuid);
-
CharacterDatabase.Execute(stmt);
item->FSetState(ITEM_REMOVED);
@@ -19044,20 +19036,22 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
stmt->setUInt32(0, GetGUIDLow());
trans->Append(stmt);
for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
+ {
if (GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS);
stmt->setUInt32(0, GetGUIDLow());
stmt->setUInt32(1, GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx));
stmt->setUInt64(2, uint64(m_lastDailyQuestTime));
trans->Append(stmt);
}
+ }
if (!m_DFQuests.empty())
{
for (DFQuestsDoneList::iterator itr = m_DFQuests.begin(); itr != m_DFQuests.end(); ++itr)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS);
stmt->setUInt32(0, GetGUIDLow());
stmt->setUInt32(1, (*itr));
stmt->setUInt64(2, uint64(m_lastDailyQuestTime));
@@ -19080,7 +19074,7 @@ void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans)
{
uint32 quest_id = *iter;
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS);
stmt->setUInt32(0, GetGUIDLow());
stmt->setUInt32(1, quest_id);
trans->Append(stmt);
@@ -19106,7 +19100,7 @@ void Player::_SaveSeasonalQuestStatus(SQLTransaction& trans)
{
uint32 quest_id = (*itr);
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS);
stmt->setUInt32(0, GetGUIDLow());
stmt->setUInt32(1, quest_id);
stmt->setUInt32(2, event_id);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 47c3c1a9395..f9d287d271a 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -281,7 +281,6 @@ Unit::~Unit()
_DeleteRemovedAuras();
delete m_charmInfo;
- delete m_vehicleKit;
delete movespline;
ASSERT(!m_duringRemoveFromWorld);
@@ -1470,8 +1469,8 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
if (GetTypeId() == TYPEID_PLAYER)
{
float bonusPct = 0;
- AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_ARMOR_PENETRATION_PCT);
- for (AuraEffectList::const_iterator itr = ResIgnoreAuras.begin(); itr != ResIgnoreAuras.end(); ++itr)
+ AuraEffectList const& armorPenAuras = GetAuraEffectsByType(SPELL_AURA_MOD_ARMOR_PENETRATION_PCT);
+ for (AuraEffectList::const_iterator itr = armorPenAuras.begin(); itr != armorPenAuras.end(); ++itr)
{
if ((*itr)->GetSpellInfo()->EquippedItemClass == -1)
{
@@ -9907,7 +9906,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
if (charm->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
{
- charm->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ charm->SetWalk(false);
charm->SendMovementFlagUpdate();
}
@@ -10004,6 +10003,7 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)
&& _IsValidAttackTarget(magnet, spellInfo)
&& IsWithinLOSInMap(magnet))
{
+ // TODO: handle this charge drop by proc in cast phase on explicit target
(*itr)->GetBase()->DropCharge(AURA_REMOVE_BY_EXPIRE);
return magnet;
}
@@ -13682,7 +13682,7 @@ void Unit::RemoveFromWorld()
{
m_duringRemoveFromWorld = true;
if (IsVehicle())
- GetVehicleKit()->Uninstall();
+ RemoveVehicleKit();
RemoveCharmAuras();
RemoveBindSightAuras();
@@ -13691,7 +13691,7 @@ void Unit::RemoveFromWorld()
RemoveAllGameObjects();
RemoveAllDynObjects();
- ExitVehicle();
+ ExitVehicle(); // Remove applied auras with SPELL_AURA_CONTROL_VEHICLE
UnsummonAllTotems();
RemoveAllControlled();
@@ -15459,7 +15459,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
// Inform pets (if any) when player kills target)
// MUST come after victim->setDeathState(JUST_DIED); or pet next target
// selection will get stuck on same target and break pet react state
- if (Player* player = ToPlayer())
+ if (player)
{
Pet* pet = player->GetPet();
if (pet && pet->isAlive() && pet->isControlled())
@@ -15590,9 +15590,6 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
if (Player* killed = victim->ToPlayer())
sScriptMgr->OnPlayerKilledByCreature(killerCre, killed);
}
-
- if (victim->GetVehicle())
- victim->ExitVehicle();
}
void Unit::SetControlled(bool apply, UnitState state)
@@ -16178,26 +16175,6 @@ bool Unit::IsInRaidWith(Unit const* unit) const
return false;
}
-bool Unit::IsTargetMatchingCheck(Unit const* target, SpellTargetSelectionCheckTypes check) const
-{
- switch (check)
- {
- case TARGET_SELECT_CHECK_ENEMY:
- if (IsControlledByPlayer())
- return !IsFriendlyTo(target);
- else
- return IsHostileTo(target);
- case TARGET_SELECT_CHECK_ALLY:
- return IsFriendlyTo(target);
- case TARGET_SELECT_CHECK_PARTY:
- return IsInPartyWith(target);
- case TARGET_SELECT_CHECK_RAID:
- return IsInRaidWith(target);
- default:
- return true;
- }
-}
-
void Unit::GetRaidMember(std::list<Unit*> &nearMembers, float radius)
{
Player* owner = GetCharmerOrOwnerPlayerOrPlayerItself();
@@ -17021,12 +16998,21 @@ void Unit::ChangeSeat(int8 seatId, bool next)
void Unit::ExitVehicle(Position const* exitPosition)
{
- // This function can be called at upper level code to initialize an exit from the passenger's side.
+ //! This function can be called at upper level code to initialize an exit from the passenger's side.
if (!m_vehicle)
return;
GetVehicleBase()->RemoveAurasByType(SPELL_AURA_CONTROL_VEHICLE, GetGUID());
- _ExitVehicle(exitPosition);
+ //! The following call would not even be executed successfully as the
+ //! SPELL_AURA_CONTROL_VEHICLE unapply handler already calls _ExitVehicle without
+ //! specifying an exitposition. The subsequent call below would return on if (!m_vehicle).
+ /*_ExitVehicle(exitPosition);*/
+ //! To do:
+ //! We need to allow SPELL_AURA_CONTROL_VEHICLE unapply handlers in spellscripts
+ //! to specify exit coordinates and either store those per passenger, or we need to
+ //! init spline movement based on those coordinates in unapply handlers, and
+ //! relocate exiting passengers based on Unit::moveSpline data. Either way,
+ //! Coming Soon™
}
void Unit::_ExitVehicle(Position const* exitPosition)
@@ -17112,6 +17098,9 @@ void Unit::BuildMovementPacket(ByteBuffer *data) const
*data << float (GetTransOffsetO());
*data << uint32(GetTransTime());
*data << uint8 (GetTransSeat());
+
+ if (GetExtraUnitMovementFlags() & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
+ *data << uint32(m_movementInfo.t_time2);
}
// 0x02200000
@@ -17466,3 +17455,29 @@ void Unit::SetFacingToObject(WorldObject* pObject)
// TODO: figure out under what conditions creature will move towards object instead of facing it where it currently is.
SetFacingTo(GetAngle(pObject));
}
+
+bool Unit::SetWalk(bool enable)
+{
+ if (enable == IsWalking())
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+
+ return true;
+}
+
+bool Unit::SetLevitate(bool enable)
+{
+ if (enable == IsLevitating())
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+
+ return true;
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 66b0bcbeb54..0fe5f3d8ca3 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1394,7 +1394,6 @@ class Unit : public WorldObject
bool IsNeutralToAll() const;
bool IsInPartyWith(Unit const* unit) const;
bool IsInRaidWith(Unit const* unit) const;
- bool IsTargetMatchingCheck(Unit const* target, SpellTargetSelectionCheckTypes check) const;
void GetPartyMemberInDist(std::list<Unit*> &units, float dist);
void GetPartyMembers(std::list<Unit*> &units);
void GetRaidMember(std::list<Unit*> &units, float dist);
@@ -1628,6 +1627,8 @@ class Unit : public WorldObject
void SendMovementFlagUpdate();
bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_LEVITATING);}
bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);}
+ virtual bool SetWalk(bool enable);
+ virtual bool SetLevitate(bool enable);
void SetInFront(Unit const* target);
void SetFacingTo(float ori);
diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h
index 8651680cb49..d096bb7ab63 100644
--- a/src/server/game/Grids/GridDefines.h
+++ b/src/server/game/Grids/GridDefines.h
@@ -65,6 +65,16 @@ typedef GridRefManager<DynamicObject> DynamicObjectMapType;
typedef GridRefManager<GameObject> GameObjectMapType;
typedef GridRefManager<Player> PlayerMapType;
+enum GridMapTypeMask
+{
+ GRID_MAP_TYPE_MASK_CORPSE = 0x01,
+ GRID_MAP_TYPE_MASK_CREATURE = 0x02,
+ GRID_MAP_TYPE_MASK_DYNAMICOBJECT = 0x04,
+ GRID_MAP_TYPE_MASK_GAMEOBJECT = 0x08,
+ GRID_MAP_TYPE_MASK_PLAYER = 0x10,
+ GRID_MAP_TYPE_MASK_ALL = 0x1F
+};
+
typedef Grid<Player, AllWorldObjectTypes, AllGridObjectTypes> GridType;
typedef NGrid<MAX_NUMBER_OF_CELLS, Player, AllWorldObjectTypes, AllGridObjectTypes> NGridType;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index 2446e9d4276..17d3066e64d 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -343,24 +343,17 @@ bool AnyDeadUnitObjectInRangeCheck::operator()(Creature* u)
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Player* u)
{
- return AnyDeadUnitObjectInRangeCheck::operator()(u)
- && (i_spellInfo->CheckTarget(i_searchObj, u, true) == SPELL_CAST_OK)
- && i_searchObj->IsTargetMatchingCheck(u, i_check);
+ return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
}
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Corpse* u)
{
- Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID());
- return owner && AnyDeadUnitObjectInRangeCheck::operator()(u)
- && (i_spellInfo->CheckTarget(i_searchObj, owner, true) == SPELL_CAST_OK)
- && i_searchObj->IsTargetMatchingCheck(owner, i_check);
+ return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
}
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
{
- return AnyDeadUnitObjectInRangeCheck::operator()(u)
- && (i_spellInfo->CheckTarget(i_searchObj, u, true) == SPELL_CAST_OK)
- && i_searchObj->IsTargetMatchingCheck(u, i_check);
+ return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
}
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType &);
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 12e3fda0484..7ffdf687561 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -30,6 +30,7 @@
#include "Player.h"
#include "Unit.h"
#include "CreatureAI.h"
+#include "Spell.h"
class Player;
//class Map;
@@ -168,12 +169,33 @@ namespace Trinity
template<class Check>
struct WorldObjectSearcher
{
+ uint32 i_mapTypeMask;
uint32 i_phaseMask;
WorldObject* &i_object;
Check &i_check;
- WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check)
- : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {}
+ WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
+ : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {}
+
+ void Visit(GameObjectMapType &m);
+ void Visit(PlayerMapType &m);
+ void Visit(CreatureMapType &m);
+ void Visit(CorpseMapType &m);
+ void Visit(DynamicObjectMapType &m);
+
+ template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
+ };
+
+ template<class Check>
+ struct WorldObjectLastSearcher
+ {
+ uint32 i_mapTypeMask;
+ uint32 i_phaseMask;
+ WorldObject* &i_object;
+ Check &i_check;
+
+ WorldObjectLastSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
+ : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) {}
void Visit(GameObjectMapType &m);
void Visit(PlayerMapType &m);
@@ -187,12 +209,13 @@ namespace Trinity
template<class Check>
struct WorldObjectListSearcher
{
+ uint32 i_mapTypeMask;
uint32 i_phaseMask;
std::list<WorldObject*> &i_objects;
Check& i_check;
- WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check)
- : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
+ WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
+ : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
void Visit(PlayerMapType &m);
void Visit(CreatureMapType &m);
@@ -206,14 +229,17 @@ namespace Trinity
template<class Do>
struct WorldObjectWorker
{
+ uint32 i_mapTypeMask;
uint32 i_phaseMask;
Do const& i_do;
- WorldObjectWorker(WorldObject const* searcher, Do const& _do)
- : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
+ WorldObjectWorker(WorldObject const* searcher, Do const& _do, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
+ : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_do(_do) {}
void Visit(GameObjectMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
+ return;
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
i_do(itr->getSource());
@@ -221,12 +247,16 @@ namespace Trinity
void Visit(PlayerMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
+ return;
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
i_do(itr->getSource());
}
void Visit(CreatureMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
+ return;
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
i_do(itr->getSource());
@@ -234,6 +264,8 @@ namespace Trinity
void Visit(CorpseMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
+ return;
for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
i_do(itr->getSource());
@@ -241,6 +273,8 @@ namespace Trinity
void Visit(DynamicObjectMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
+ return;
for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
i_do(itr->getSource());
@@ -527,73 +561,11 @@ namespace Trinity
// CHECKS && DO classes
// WorldObject check classes
- class RaiseDeadObjectCheck
- {
- public:
- RaiseDeadObjectCheck(Unit* source, float range) : _source(source), _range(range) {}
- bool operator()(Creature* u)
- {
- if (_source->GetTypeId() != TYPEID_PLAYER || !((Player*)_source)->isHonorOrXPTarget(u) ||
- u->getDeathState() != CORPSE ||
- (u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0 ||
- (u->GetDisplayId() != u->GetNativeDisplayId()))
- return false;
-
- return _source->IsWithinDistInMap(u, _range);
- }
- bool operator()(Player* u)
- {
- if (_source == u || _source->GetTypeId() != TYPEID_PLAYER || !((Player*)_source)->isHonorOrXPTarget(u) ||
- u->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) || u->isInFlight() || !u->isDead() ||
- (u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0)
- return false;
- return _source->IsWithinDistInMap(u, _range);
- }
-
- bool operator()(Corpse* u)
- {
- if (_source->GetTypeId() != TYPEID_PLAYER || u->GetType() == CORPSE_BONES)
- return false;
-
- return _source->IsWithinDistInMap(u, _range);
- }
- template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
- private:
- Unit* const _source;
- float _range;
- };
-
- class ExplodeCorpseObjectCheck
- {
- public:
- ExplodeCorpseObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
- bool operator()(Player* u)
- {
- if (u->getDeathState() != CORPSE || u->isInFlight() ||
- u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId()))
- return false;
-
- return i_funit->IsWithinDistInMap(u, i_range);
- }
- bool operator()(Creature* u)
- {
- if (u->getDeathState() != CORPSE || u->isInFlight() ||
- (u->GetDisplayId() != u->GetNativeDisplayId()) ||
- (u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL) != 0)
- return false;
-
- return i_funit->IsWithinDistInMap(u, i_range);
- }
- template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
- private:
- Unit* const i_funit;
- float i_range;
- };
class AnyDeadUnitObjectInRangeCheck
{
public:
- AnyDeadUnitObjectInRangeCheck(Unit const* searchObj, float range) : i_searchObj(searchObj), i_range(range) {}
+ AnyDeadUnitObjectInRangeCheck(Unit* searchObj, float range) : i_searchObj(searchObj), i_range(range) {}
bool operator()(Player* u);
bool operator()(Corpse* u);
bool operator()(Creature* u);
@@ -606,15 +578,16 @@ namespace Trinity
class AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck
{
public:
- AnyDeadUnitSpellTargetInRangeCheck(Unit const* searchObj, float range, SpellInfo const* spellInfo, SpellTargetSelectionCheckTypes check)
- : AnyDeadUnitObjectInRangeCheck(searchObj, range), i_spellInfo(spellInfo), i_check(check) {}
+ AnyDeadUnitSpellTargetInRangeCheck(Unit* searchObj, float range, SpellInfo const* spellInfo, SpellTargetCheckTypes check)
+ : AnyDeadUnitObjectInRangeCheck(searchObj, range), i_spellInfo(spellInfo), i_check(searchObj, searchObj, spellInfo, check, NULL)
+ {}
bool operator()(Player* u);
bool operator()(Corpse* u);
bool operator()(Creature* u);
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
protected:
SpellInfo const* i_spellInfo;
- SpellTargetSelectionCheckTypes i_check;
+ WorldObjectSpellTargetCheck i_check;
};
// WorldObject do classes
diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
index 34fe7757c5f..40b3863679b 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
@@ -51,6 +51,9 @@ inline void Trinity::ObjectUpdater::Visit(CreatureMapType &m)
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
+ return;
+
// already found
if (i_object)
return;
@@ -71,6 +74,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
+ return;
+
// already found
if (i_object)
return;
@@ -91,6 +97,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
+ return;
+
// already found
if (i_object)
return;
@@ -111,6 +120,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
+ return;
+
// already found
if (i_object)
return;
@@ -131,6 +143,9 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
+ return;
+
// already found
if (i_object)
return;
@@ -148,9 +163,93 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
}
}
+
+template<class Check>
+void Trinity::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
+ return;
+
+ for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
+ i_object = itr->getSource();
+ }
+}
+
+template<class Check>
+void Trinity::WorldObjectLastSearcher<Check>::Visit(PlayerMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
+ return;
+
+ for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
+ i_object = itr->getSource();
+ }
+}
+
+template<class Check>
+void Trinity::WorldObjectLastSearcher<Check>::Visit(CreatureMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
+ return;
+
+ for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
+ i_object = itr->getSource();
+ }
+}
+
+template<class Check>
+void Trinity::WorldObjectLastSearcher<Check>::Visit(CorpseMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
+ return;
+
+ for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
+ i_object = itr->getSource();
+ }
+}
+
+template<class Check>
+void Trinity::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
+ return;
+
+ for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->getSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->getSource()))
+ i_object = itr->getSource();
+ }
+}
+
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
+ return;
+
for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
@@ -160,6 +259,9 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
+ return;
+
for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
@@ -169,6 +271,9 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
+ return;
+
for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
@@ -178,6 +283,9 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
+ return;
+
for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
@@ -187,6 +295,9 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
+ return;
+
for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
if (itr->getSource()->InSamePhase(i_phaseMask))
if (i_check(itr->getSource()))
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index f99bfe52df3..45c0f7bed42 100755
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -309,28 +309,28 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
sAuctionMgr->AddAItem(newItem);
auctionHouse->AddAuction(AH);
- for (uint32 i = 0; i < itemsCount; ++i)
+ for (uint32 j = 0; j < itemsCount; ++j)
{
- Item* item = items[i];
+ Item* item2 = items[j];
- if (item->GetCount() == count[i])
+ if (item2->GetCount() == count[j])
{
- _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
+ _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- item->DeleteFromInventoryDB(trans);
- item->SaveToDB(trans);
+ item2->DeleteFromInventoryDB(trans);
+ item2->SaveToDB(trans);
CharacterDatabase.CommitTransaction(trans);
}
else
{
- item->SetCount(item->GetCount() - count[i]);
- item->SetState(ITEM_CHANGED, _player);
- _player->ItemRemovedQuestCheck(item->GetEntry(), count[i]);
- item->SendUpdateToPlayer(_player);
+ item2->SetCount(item2->GetCount() - count[j]);
+ item2->SetState(ITEM_CHANGED, _player);
+ _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
+ item2->SendUpdateToPlayer(_player);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
- item->SaveToDB(trans);
+ item2->SaveToDB(trans);
CharacterDatabase.CommitTransaction(trans);
}
}
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index a48cf70bd54..30119c79d96 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1811,8 +1811,8 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
{
// Reset guild
- if (QueryResult result = CharacterDatabase.PQuery("SELECT guildid FROM `guild_member` WHERE guid ='%u'", lowGuid))
- if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt32()))
+ if (QueryResult result2 = CharacterDatabase.PQuery("SELECT guildid FROM `guild_member` WHERE guid ='%u'", lowGuid))
+ if (Guild* guild = sGuildMgr->GetGuildById((result2->Fetch()[0]).GetUInt32()))
guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER));
}
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 1f286a0af05..6a44c7ae5e2 100755
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -615,7 +615,7 @@ void WorldSession::HandleStablePet(WorldPacket & recv_data)
Pet* pet = _player->GetPet();
// can't place in stable dead pet
- if (!pet||!pet->isAlive()||pet->getPetType() != HUNTER_PET)
+ if (!pet || !pet->isAlive() || pet->getPetType() != HUNTER_PET)
{
SendStableResult(STABLE_ERR_STABLE);
return;
@@ -853,16 +853,22 @@ void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint3
return;
}
- // move alive pet to slot or delete dead pet
Pet* pet = _player->GetPet();
+ // The player's pet could have been removed during the delay of the DB callback
+ if (!pet)
+ {
+ SendStableResult(STABLE_ERR_STABLE);
+ return;
+ }
+ // move alive pet to slot or delete dead pet
_player->RemovePet(pet, pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED);
// summon unstabled pet
- Pet* newpet = new Pet(_player);
- if (!newpet->LoadPetFromDB(_player, petEntry, petId))
+ Pet* newPet = new Pet(_player);
+ if (!newPet->LoadPetFromDB(_player, petEntry, petId))
{
- delete newpet;
+ delete newPet;
SendStableResult(STABLE_ERR_STABLE);
}
else
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index f6189fa556c..cf517ccfbb4 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -1544,7 +1544,7 @@ inline GridMap* Map::GetGrid(float x, float y)
return GridMaps[gx][gy];
}
-float Map::GetWaterOrGroundLevel(float x, float y, float z, float* ground /*= NULL*/, bool swim /*= false*/) const
+float Map::GetWaterOrGroundLevel(float x, float y, float z, float* ground /*= NULL*/, bool /*swim = false*/) const
{
if (const_cast<Map*>(this)->GetGrid(x, y))
{
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 954a193c498..27816753ca7 100755
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -365,10 +365,7 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee
init.SetParabolic(max_height,0);
init.SetVelocity(speedXY);
init.Launch();
- if (_owner->GetTypeId() == TYPEID_PLAYER)
- Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
- else
- Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
}
void MotionMaster::MoveFall(uint32 id/*=0*/)
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 9910f8ad40a..d6144bfcc3a 100755
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -84,7 +84,12 @@ class MotionMaster //: private std::stack<MovementGenerator *>
//typedef std::stack<MovementGenerator *> Impl;
typedef MovementGenerator* _Ty;
- void pop() { Impl[_top] = NULL; --_top; }
+ void pop()
+ {
+ Impl[_top] = NULL;
+ while (!top())
+ --_top;
+ }
void push(_Ty _Val) { ++_top; Impl[_top] = _Val; }
bool needInitTop() const { return _needInit[_top]; }
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index fb2249c508e..a8602153de3 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -79,7 +79,7 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature)
if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance)
{
sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for "UI64FMTD".", i_path->at(i_currentNode)->event_id, i_currentNode, creature.GetGUID());
- creature.GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, &creature, NULL/*, false*/);
+ creature.GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, &creature, NULL);
}
// Inform script
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 21b98ad2cea..7f22b441afe 100755
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -252,7 +252,7 @@ class Quest
uint32 GetFlags() const { return Flags; }
bool IsDaily() const { return Flags & QUEST_FLAGS_DAILY; }
bool IsWeekly() const { return Flags & QUEST_FLAGS_WEEKLY; }
- bool IsSeasonal() const { return (ZoneOrSort == -QUEST_SORT_SEASONAL || ZoneOrSort == -QUEST_SORT_SPECIAL || ZoneOrSort == -QUEST_SORT_LUNAR_FESTIVAL || ZoneOrSort == -QUEST_SORT_MIDSUMMER || ZoneOrSort == -QUEST_SORT_BREWFEST || ZoneOrSort == -QUEST_SORT_LOVE_IS_IN_THE_AIR || ZoneOrSort == -QUEST_SORT_NOBLEGARDEN); }
+ bool IsSeasonal() const { return (ZoneOrSort == -QUEST_SORT_SEASONAL || ZoneOrSort == -QUEST_SORT_SPECIAL || ZoneOrSort == -QUEST_SORT_LUNAR_FESTIVAL || ZoneOrSort == -QUEST_SORT_MIDSUMMER || ZoneOrSort == -QUEST_SORT_BREWFEST || ZoneOrSort == -QUEST_SORT_LOVE_IS_IN_THE_AIR || ZoneOrSort == -QUEST_SORT_NOBLEGARDEN) && !IsRepeatable(); }
bool IsDailyOrWeekly() const { return Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
bool IsRaidQuest() const { return Type == QUEST_TYPE_RAID || Type == QUEST_TYPE_RAID_10 || Type == QUEST_TYPE_RAID_25; }
bool IsAllowedInRaid() const;
diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp
index 7757e1a1a35..fb2590ebbfe 100755
--- a/src/server/game/Scripting/MapScripts.cpp
+++ b/src/server/game/Scripting/MapScripts.cpp
@@ -39,9 +39,9 @@ void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, O
return;
// prepare static data
- uint64 sourceGUID = source ? source->GetGUID() : (uint64)0; //some script commands doesn't have source
- uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
- uint64 ownerGUID = (source->GetTypeId() == TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
+ uint64 sourceGUID = source ? source->GetGUID() : uint64(0); //some script commands doesn't have source
+ uint64 targetGUID = target ? target->GetGUID() : uint64(0);
+ uint64 ownerGUID = (source && source->GetTypeId() == TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : uint64(0);
///- Schedule script execution for all scripts in the script map
ScriptMap const* s2 = &(s->second);
@@ -74,9 +74,9 @@ void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* sou
// NOTE: script record _must_ exist until command executed
// prepare static data
- uint64 sourceGUID = source ? source->GetGUID() : (uint64)0;
- uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
- uint64 ownerGUID = (source->GetTypeId() == TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
+ uint64 sourceGUID = source ? source->GetGUID() : uint64(0);
+ uint64 targetGUID = target ? target->GetGUID() : uint64(0);
+ uint64 ownerGUID = (source && source->GetTypeId() == TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : uint64(0);
ScriptAction sa;
sa.sourceGUID = sourceGUID;
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index cdec6bb3ffa..1207b654817 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -246,7 +246,6 @@ void AddSC_ironforge();
void AddSC_isle_of_queldanas();
void AddSC_loch_modan();
void AddSC_redridge_mountains();
-void AddSC_searing_gorge();
void AddSC_silvermoon_city();
void AddSC_silverpine_forest();
void AddSC_stormwind_city();
@@ -857,7 +856,6 @@ void AddEasternKingdomsScripts()
AddSC_isle_of_queldanas();
AddSC_loch_modan();
AddSC_redridge_mountains();
- AddSC_searing_gorge();
AddSC_silvermoon_city();
AddSC_silverpine_forest();
AddSC_stormwind_city();
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 99497870a15..cb79bd00776 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -4686,11 +4686,11 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (owner_aura)
{
owner_aura->SetStackAmount(owner_aura->GetSpellInfo()->StackAmount);
- }
- if (pet_aura)
- {
- pet_aura->SetCharges(0);
- pet_aura->SetStackAmount(owner_aura->GetSpellInfo()->StackAmount);
+ if (pet_aura)
+ {
+ pet_aura->SetCharges(0);
+ pet_aura->SetStackAmount(owner_aura->GetSpellInfo()->StackAmount);
+ }
}
break;
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 53356772ff6..db36eb30191 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -592,19 +592,6 @@ Spell::~Spell()
CheckEffectExecuteData();
}
-template<typename T>
-WorldObject* Spell::FindCorpseUsing()
-{
- // non-standard target selection
- float max_range = m_spellInfo->GetMaxRange(false);
-
- WorldObject* result = NULL;
- T u_check(m_caster, max_range);
- Trinity::WorldObjectSearcher<T> searcher(m_caster, result, u_check);
- m_caster->GetMap()->VisitFirstFound(m_caster->GetPositionX(), m_caster->GetPositionY(), max_range, searcher);
- return result;
-}
-
void Spell::InitExplicitTargets(SpellCastTargets const& targets)
{
m_targets = targets;
@@ -707,7 +694,8 @@ void Spell::SelectSpellTargets()
{
// select targets for cast phase
SelectExplicitTargets();
- uint32 processedTargets = 0;
+
+ uint32 processedAreaEffectsMask = 0;
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
// not call for empty effect.
@@ -715,9 +703,6 @@ void Spell::SelectSpellTargets()
if (!m_spellInfo->Effects[i].IsEffect())
continue;
- if (processedTargets & (1 << i))
- continue;
-
// set expected type of implicit targets to be sent to client
uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
if (implicitTargetMask & TARGET_FLAG_UNIT)
@@ -725,13 +710,8 @@ void Spell::SelectSpellTargets()
if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT);
- uint32 targetA = m_spellInfo->Effects[i].TargetA.GetTarget();
- uint32 targetB = m_spellInfo->Effects[i].TargetB.GetTarget();
-
- if (targetA)
- processedTargets |= SelectEffectTargets(i, m_spellInfo->Effects[i].TargetA);
- if (targetB)
- processedTargets |= SelectEffectTargets(i, m_spellInfo->Effects[i].TargetB);
+ SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
+ SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
// Select targets of effect based on effect type
// those are used when no valid target could be added for spell effect based on spell target type
@@ -793,6 +773,938 @@ void Spell::SelectSpellTargets()
}
}
+void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask)
+{
+ if (!targetType.GetTarget())
+ return;
+
+ uint32 effectMask = 1 << effIndex;
+ // set the same target list for all effects
+ // some spells appear to need this, however this requires more research
+ switch (targetType.GetSelectionCategory())
+ {
+ case TARGET_SELECT_CATEGORY_NEARBY:
+ case TARGET_SELECT_CATEGORY_CONE:
+ case TARGET_SELECT_CATEGORY_AREA:
+ // targets for effect already selected
+ if (effectMask & processedEffectMask)
+ return;
+ // choose which targets we can select at once
+ for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
+ if (GetSpellInfo()->Effects[effIndex].TargetA.GetTarget() == GetSpellInfo()->Effects[j].TargetA.GetTarget() &&
+ GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == GetSpellInfo()->Effects[j].TargetB.GetTarget() &&
+ GetSpellInfo()->Effects[effIndex].ImplicitTargetConditions == GetSpellInfo()->Effects[j].ImplicitTargetConditions &&
+ GetSpellInfo()->Effects[effIndex].CalcRadius(m_caster) == GetSpellInfo()->Effects[j].CalcRadius(m_caster))
+ effectMask |= 1 << j;
+ processedEffectMask |= effectMask;
+ break;
+ default:
+ break;
+ }
+
+ switch(targetType.GetSelectionCategory())
+ {
+ case TARGET_SELECT_CATEGORY_CHANNEL:
+ SelectImplicitChannelTargets(effIndex, targetType);
+ break;
+ case TARGET_SELECT_CATEGORY_NEARBY:
+ SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
+ break;
+ case TARGET_SELECT_CATEGORY_CONE:
+ SelectImplicitConeTargets(effIndex, targetType, effectMask);
+ break;
+ case TARGET_SELECT_CATEGORY_AREA:
+ SelectImplicitAreaTargets(effIndex, targetType, effectMask);
+ break;
+ case TARGET_SELECT_CATEGORY_DEFAULT:
+ switch (targetType.GetObjectType())
+ {
+ case TARGET_OBJECT_TYPE_SRC:
+ switch(targetType.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_CASTER:
+ m_targets.SetSrc(*m_caster);
+ break;
+ default:
+ ASSERT("Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
+ break;
+ }
+ break;
+ case TARGET_OBJECT_TYPE_DEST:
+ switch(targetType.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_CASTER:
+ SelectImplicitCasterDestTargets(effIndex, targetType);
+ break;
+ case TARGET_REFERENCE_TYPE_TARGET:
+ SelectImplicitTargetDestTargets(effIndex, targetType);
+ break;
+ case TARGET_REFERENCE_TYPE_DEST:
+ SelectImplicitDestDestTargets(effIndex, targetType);
+ break;
+ default:
+ ASSERT("Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
+ break;
+ }
+ break;
+ default:
+ switch(targetType.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_CASTER:
+ SelectImplicitCasterObjectTargets(effIndex, targetType);
+ break;
+ case TARGET_REFERENCE_TYPE_TARGET:
+ SelectImplicitTargetObjectTargets(effIndex, targetType);
+ break;
+ default:
+ ASSERT("Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
+ break;
+ }
+ break;
+ }
+ break;
+ case TARGET_SELECT_CATEGORY_NYI:
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: target type %u, found in spellID %u, effect %u is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
+ break;
+ default:
+ ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
+ break;
+ }
+}
+
+void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+{
+ if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
+ {
+ ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
+ return;
+ }
+
+ Spell* channeledSpell = m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
+ if (!channeledSpell)
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::SelectImplicitChannelTargets: cannot find channel spell for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ return;
+ }
+ switch (targetType.GetTarget())
+ {
+ case TARGET_UNIT_CHANNEL_TARGET:
+ // unit target may be no longer avalible - teleported out of map for example
+ if (Unit* target = Unit::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()))
+ AddUnitTarget(target, 1 << effIndex);
+ else
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ break;
+ case TARGET_DEST_CHANNEL_TARGET:
+ if (channeledSpell->m_targets.HasDst())
+ m_targets.SetDst(channeledSpell->m_targets);
+ else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID()))
+ m_targets.SetDst(*target);
+ else
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ break;
+ case TARGET_DEST_CHANNEL_CASTER:
+ m_targets.SetDst(*channeledSpell->GetCaster());
+ break;
+ default:
+ ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
+ break;
+ }
+}
+
+void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+{
+ if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
+ {
+ ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
+ return;
+ }
+
+ float range = 0.0f;
+ switch (targetType.GetCheckType())
+ {
+ case TARGET_CHECK_ENEMY:
+ range = m_spellInfo->GetMaxRange(false, m_caster, this);
+ break;
+ case TARGET_CHECK_ALLY:
+ case TARGET_CHECK_PARTY:
+ case TARGET_CHECK_RAID:
+ case TARGET_CHECK_RAID_CLASS:
+ range = m_spellInfo->GetMaxRange(true, m_caster, this);
+ break;
+ case TARGET_CHECK_ENTRY:
+ case TARGET_CHECK_DEFAULT:
+ range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive(), m_caster, this);
+ break;
+ default:
+ ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
+ break;
+ }
+
+ ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
+
+ // handle emergency case - try to use other provided targets if no conditions provided
+ if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::SelectImplicitNearbyTargets: no conditions entry for target with TARGET_CHECK_ENTRY of spell ID %u, effect %u - selecting default targets", m_spellInfo->Id, effIndex);
+ switch (targetType.GetObjectType())
+ {
+ case TARGET_OBJECT_TYPE_GOBJ:
+ if (m_spellInfo->RequiresSpellFocus)
+ {
+ if (focusObject)
+ AddGOTarget(focusObject, effMask);
+ return;
+ }
+ break;
+ case TARGET_OBJECT_TYPE_DEST:
+ if (m_spellInfo->RequiresSpellFocus)
+ {
+ if (focusObject)
+ m_targets.SetDst(*focusObject);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
+ if (!target)
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
+ return;
+ }
+
+ switch (targetType.GetObjectType())
+ {
+ case TARGET_OBJECT_TYPE_UNIT:
+ if (Unit* unitTarget = target->ToUnit())
+ AddUnitTarget(unitTarget, effMask, false);
+ break;
+ case TARGET_OBJECT_TYPE_GOBJ:
+ if (GameObject* gobjTarget = target->ToGameObject())
+ AddGOTarget(gobjTarget, effMask);
+ break;
+ case TARGET_OBJECT_TYPE_DEST:
+ m_targets.SetDst(*target);
+ break;
+ default:
+ ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
+ break;
+ }
+
+ SelectImplicitChainTargets(effIndex, targetType, target, effMask);
+}
+
+void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+{
+ if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
+ {
+ ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
+ return;
+ }
+ std::list<WorldObject*> targets;
+ SpellTargetObjectTypes objectType = targetType.GetObjectType();
+ SpellTargetCheckTypes selectionType = targetType.GetCheckType();
+ ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
+ float coneAngle = M_PI/2;
+ float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
+
+ if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
+ {
+ Trinity::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
+ Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, radius);
+
+ if (!targets.empty())
+ {
+ // Other special target selection goes here
+ if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
+ {
+ Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
+ if ((*j)->IsAffectedOnSpell(m_spellInfo))
+ maxTargets += (*j)->GetAmount();
+
+ Trinity::RandomResizeList(targets, maxTargets);
+ }
+
+ // for compability with older code - add only unit and go targets
+ // TODO: remove this
+ std::list<Unit*> unitTargets;
+ std::list<GameObject*> gObjTargets;
+
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ {
+ if (Unit* unitTarget = (*itr)->ToUnit())
+ unitTargets.push_back(unitTarget);
+ else if (GameObject* gObjTarget = (*itr)->ToGameObject())
+ gObjTargets.push_back(gObjTarget);
+ }
+
+ CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
+
+ for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
+ AddUnitTarget(*itr, effMask, false);
+
+ for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
+ AddGOTarget(*itr, effMask);
+ }
+ }
+}
+
+void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask)
+{
+ Unit* referer = NULL;
+ switch (targetType.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_SRC:
+ case TARGET_REFERENCE_TYPE_DEST:
+ case TARGET_REFERENCE_TYPE_CASTER:
+ referer = m_caster;
+ break;
+ case TARGET_REFERENCE_TYPE_TARGET:
+ referer = m_targets.GetUnitTarget();
+ break;
+ case TARGET_REFERENCE_TYPE_LAST:
+ {
+ // find last added target for this effect
+ for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
+ {
+ if (ihit->effectMask & (1<<effIndex))
+ {
+ referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
+ return;
+ }
+ if (!referer)
+ return;
+
+ Position const* center = NULL;
+ switch (targetType.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_SRC:
+ center = m_targets.GetSrc();
+ break;
+ case TARGET_REFERENCE_TYPE_DEST:
+ center = m_targets.GetDst();
+ break;
+ case TARGET_REFERENCE_TYPE_CASTER:
+ case TARGET_REFERENCE_TYPE_TARGET:
+ case TARGET_REFERENCE_TYPE_LAST:
+ center = referer;
+ break;
+ default:
+ ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
+ return;
+ }
+ std::list<WorldObject*> targets;
+ float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
+ SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
+
+ // Custom entries
+ // TODO: remove those
+ switch (m_spellInfo->Id)
+ {
+ case 46584: // Raise Dead
+ {
+ if (Player* playerCaster = m_caster->ToPlayer())
+ {
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ {
+ switch ((*itr)->GetTypeId())
+ {
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
+ {
+ Unit* unitTarget = (*itr)->ToUnit();
+ if (unitTarget->isAlive() || !playerCaster->isHonorOrXPTarget(unitTarget)
+ || ((unitTarget->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0)
+ || (unitTarget->GetDisplayId() != unitTarget->GetNativeDisplayId()))
+ break;
+ AddUnitTarget(unitTarget, effMask, false);
+ // no break;
+ }
+ case TYPEID_CORPSE: // wont work until corpses are allowed in target lists, but at least will send dest in packet
+ m_targets.SetDst(*(*itr));
+ return; // nothing more to do here
+ default:
+ break;
+ }
+ }
+ }
+ return; // don't add targets to target map
+ }
+ // Corpse Explosion
+ case 49158:
+ case 51325:
+ case 51326:
+ case 51327:
+ case 51328:
+ // check if our target is not valid (spell can target ghoul or dead unit)
+ if (!(m_targets.GetUnitTarget() && m_targets.GetUnitTarget()->GetDisplayId() == m_targets.GetUnitTarget()->GetNativeDisplayId() &&
+ ((m_targets.GetUnitTarget()->GetEntry() == 26125 && m_targets.GetUnitTarget()->GetOwnerGUID() == m_caster->GetGUID())
+ || m_targets.GetUnitTarget()->isDead())))
+ {
+ // remove existing targets
+ CleanupTargetList();
+
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ {
+ switch ((*itr)->GetTypeId())
+ {
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
+ if (!(*itr)->ToUnit()->isDead())
+ break;
+ AddUnitTarget((*itr)->ToUnit(), 1 << effIndex, false);
+ return;
+ default:
+ break;
+ }
+ }
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
+ SendCastResult(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
+ finish(false);
+ }
+ return;
+ default:
+ break;
+ }
+ std::list<Unit*> unitTargets;
+ std::list<GameObject*> gObjTargets;
+ // for compability with older code - add only unit and go targets
+ // TODO: remove this
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ {
+ if (Unit* unitTarget = (*itr)->ToUnit())
+ unitTargets.push_back(unitTarget);
+ else if (GameObject* gObjTarget = (*itr)->ToGameObject())
+ gObjTargets.push_back(gObjTarget);
+ }
+
+ if (!unitTargets.empty())
+ {
+ // Special target selection for smart heals and energizes
+ uint32 maxSize = 0;
+ int32 power = -1;
+ switch (m_spellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ switch (m_spellInfo->Id)
+ {
+ case 52759: // Ancestral Awakening
+ case 71610: // Echoes of Light (Althor's Abacus normal version)
+ case 71641: // Echoes of Light (Althor's Abacus heroic version)
+ maxSize = 1;
+ power = POWER_HEALTH;
+ break;
+ case 54968: // Glyph of Holy Light
+ maxSize = m_spellInfo->MaxAffectedTargets;
+ power = POWER_HEALTH;
+ break;
+ case 57669: // Replenishment
+ // In arenas Replenishment may only affect the caster
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->InArena())
+ {
+ unitTargets.clear();
+ unitTargets.push_back(m_caster);
+ break;
+ }
+ maxSize = 10;
+ power = POWER_MANA;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SPELLFAMILY_PRIEST:
+ if (m_spellInfo->SpellFamilyFlags[0] == 0x10000000) // Circle of Healing
+ {
+ maxSize = m_caster->HasAura(55675) ? 6 : 5; // Glyph of Circle of Healing
+ power = POWER_HEALTH;
+ }
+ else if (m_spellInfo->Id == 64844) // Divine Hymn
+ {
+ maxSize = 3;
+ power = POWER_HEALTH;
+ }
+ else if (m_spellInfo->Id == 64904) // Hymn of Hope
+ {
+ maxSize = 3;
+ power = POWER_MANA;
+ }
+ else
+ break;
+
+ // Remove targets outside caster's raid
+ for (std::list<Unit*>::iterator itr = unitTargets.begin() ; itr != unitTargets.end();)
+ {
+ if (!(*itr)->IsInRaidWith(m_caster))
+ itr = unitTargets.erase(itr);
+ else
+ ++itr;
+ }
+ break;
+ case SPELLFAMILY_DRUID:
+ if (m_spellInfo->SpellFamilyFlags[1] == 0x04000000) // Wild Growth
+ {
+ maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth
+ power = POWER_HEALTH;
+ }
+ else if (m_spellInfo->SpellFamilyFlags[2] == 0x0100) // Starfall
+ {
+ // Remove targets not in LoS or in stealth
+ for (std::list<Unit*>::iterator itr = unitTargets.begin() ; itr != unitTargets.end();)
+ {
+ if ((*itr)->HasStealthAura() || (*itr)->HasInvisibilityAura() || !(*itr)->IsWithinLOSInMap(m_caster))
+ itr = unitTargets.erase(itr);
+ else
+ ++itr;
+ }
+ break;
+ }
+ else
+ break;
+
+ // Remove targets outside caster's raid
+ for (std::list<Unit*>::iterator itr = unitTargets.begin() ; itr != unitTargets.end();)
+ if (!(*itr)->IsInRaidWith(m_caster))
+ itr = unitTargets.erase(itr);
+ else
+ ++itr;
+ break;
+ default:
+ break;
+ }
+
+ if (maxSize && power != -1)
+ {
+ if (Powers(power) == POWER_HEALTH)
+ {
+ if (unitTargets.size() > maxSize)
+ {
+ unitTargets.sort(Trinity::HealthPctOrderPred());
+ unitTargets.resize(maxSize);
+ }
+ }
+ else
+ {
+ for (std::list<Unit*>::iterator itr = unitTargets.begin() ; itr != unitTargets.end();)
+ if ((*itr)->getPowerType() != (Powers)power)
+ itr = unitTargets.erase(itr);
+ else
+ ++itr;
+
+ if (unitTargets.size() > maxSize)
+ {
+ unitTargets.sort(Trinity::PowerPctOrderPred((Powers)power));
+ unitTargets.resize(maxSize);
+ }
+ }
+ }
+
+ // Other special target selection goes here
+ if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
+ {
+ Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
+ if ((*j)->IsAffectedOnSpell(m_spellInfo))
+ maxTargets += (*j)->GetAmount();
+
+ if (m_spellInfo->Id == 5246) //Intimidating Shout
+ unitTargets.remove(m_targets.GetUnitTarget());
+ Trinity::RandomResizeList(unitTargets, maxTargets);
+ }
+
+ CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
+
+ for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
+ AddUnitTarget(*itr, effMask, false);
+ }
+
+ if (!gObjTargets.empty())
+ {
+ if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
+ {
+ Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
+ if ((*j)->IsAffectedOnSpell(m_spellInfo))
+ maxTargets += (*j)->GetAmount();
+
+ Trinity::RandomResizeList(gObjTargets, maxTargets);
+ }
+ for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
+ AddGOTarget(*itr, effMask);
+ }
+}
+
+void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+{
+ switch(targetType.GetTarget())
+ {
+ case TARGET_DEST_CASTER:
+ m_targets.SetDst(*m_caster);
+ return;
+ case TARGET_DEST_HOME:
+ if (Player* playerCaster = m_caster->ToPlayer())
+ m_targets.SetDst(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
+ return;
+ case TARGET_DEST_DB:
+ if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id))
+ {
+ // TODO: fix this check
+ if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS))
+ m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
+ else if (st->target_mapId == m_caster->GetMapId())
+ m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
+ }
+ else
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id);
+ WorldObject* target = m_targets.GetObjectTarget();
+ m_targets.SetDst(target ? *target : *m_caster);
+ }
+ return;
+ case TARGET_DEST_CASTER_FISHING:
+ {
+ float min_dis = m_spellInfo->GetMinRange(true);
+ float max_dis = m_spellInfo->GetMaxRange(true);
+ float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
+ float x, y, z, angle;
+ angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle);
+ m_targets.SetDst(x, y, z, m_caster->GetOrientation());
+ return;
+ }
+ default:
+ break;
+ }
+
+ float dist;
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = m_caster->GetObjectSize();
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
+ dist = PET_FOLLOW_DIST;
+ else
+ dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
+ dist = objSize + (dist - objSize) * (float)rand_norm();
+
+ Position pos;
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP)
+ m_caster->GetFirstCollisionPosition(pos, dist, angle);
+ else
+ m_caster->GetNearPosition(pos, dist, angle);
+ m_targets.SetDst(*m_caster);
+ m_targets.ModDst(pos);
+}
+
+void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+{
+ WorldObject* target = m_targets.GetObjectTarget();
+ switch(targetType.GetTarget())
+ {
+ case TARGET_DEST_TARGET_ENEMY:
+ case TARGET_DEST_TARGET_ANY:
+ m_targets.SetDst(*target);
+ return;
+ default:
+ break;
+ }
+
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = target->GetObjectSize();
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
+ dist = objSize + (dist - objSize) * (float)rand_norm();
+
+ Position pos;
+ target->GetNearPosition(pos, dist, angle);
+ m_targets.SetDst(*target);
+ m_targets.ModDst(pos);
+}
+
+void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+{
+ // set destination to caster if no dest provided
+ // can only happen if previous destination target could not be set for some reason
+ // (not found nearby target, or channel target for example
+ // maybe we should abort the spell in such case?
+ if (!m_targets.HasDst())
+ m_targets.SetDst(*m_caster);
+
+ switch(targetType.GetTarget())
+ {
+ case TARGET_DEST_DYNOBJ_ENEMY:
+ case TARGET_DEST_DYNOBJ_ALLY:
+ case TARGET_DEST_DYNOBJ_NONE:
+ case TARGET_DEST_DEST:
+ return;
+ case TARGET_DEST_TRAJ:
+ SelectImplicitTrajTargets();
+ return;
+ default:
+ break;
+ }
+
+ float angle = targetType.CalcDirectionAngle();
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
+ dist *= (float)rand_norm();
+
+ Position pos = *m_targets.GetDst();
+ m_caster->MovePosition(pos, dist, angle);
+ m_targets.ModDst(pos);
+}
+
+void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+{
+ switch(targetType.GetTarget())
+ {
+ case TARGET_UNIT_CASTER:
+ AddUnitTarget(m_caster, 1 << effIndex, false);
+ break;
+ case TARGET_UNIT_MASTER:
+ if (Unit* owner = m_caster->GetCharmerOrOwner())
+ AddUnitTarget(owner, 1 << effIndex);
+ break;
+ case TARGET_UNIT_PET:
+ if (Guardian* pet = m_caster->GetGuardianPet())
+ AddUnitTarget(pet, 1 << effIndex);
+ break;
+ case TARGET_UNIT_SUMMONER:
+ if (m_caster->isSummon())
+ if (Unit* unit = m_caster->ToTempSummon()->GetSummoner())
+ AddUnitTarget(unit, 1 << effIndex);
+ break;
+ case TARGET_UNIT_VEHICLE:
+ if (Unit *vehicle = m_caster->GetVehicleBase())
+ AddUnitTarget(vehicle, 1 << effIndex);
+ break;
+ case TARGET_UNIT_PASSENGER_0:
+ case TARGET_UNIT_PASSENGER_1:
+ case TARGET_UNIT_PASSENGER_2:
+ case TARGET_UNIT_PASSENGER_3:
+ case TARGET_UNIT_PASSENGER_4:
+ case TARGET_UNIT_PASSENGER_5:
+ case TARGET_UNIT_PASSENGER_6:
+ case TARGET_UNIT_PASSENGER_7:
+ if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle())
+ if (Unit *unit = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0))
+ AddUnitTarget(unit, 1 << effIndex);
+ break;
+ default:
+ break;
+ }
+}
+
+void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
+{
+ ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
+ if (Unit* unit = m_targets.GetUnitTarget())
+ AddUnitTarget(unit, 1 << effIndex);
+ else if (GameObject* gobj = m_targets.GetGOTarget())
+ AddGOTarget(gobj, 1 << effIndex);
+ else
+ AddItemTarget(m_targets.GetItemTarget(), effIndex);
+
+ if (WorldObject* target = m_targets.GetObjectTarget())
+ SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
+}
+
+void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask)
+{
+ uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
+ if (Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
+
+ if (maxTargets > 1)
+ {
+ // mark damage multipliers as used
+ for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
+ if (effMask & (1 << k))
+ m_damageMultipliers[k] = 1.0f;
+ m_applyMultiplierMask |= effMask;
+
+ std::list<WorldObject*> targets;
+ SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType()
+ , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
+
+ // for backward compability
+ std::list<Unit*> unitTargets;
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ if (Unit* unitTarget = (*itr)->ToUnit())
+ unitTargets.push_back(unitTarget);
+
+ CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
+
+ for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
+ AddUnitTarget(*itr, effMask, false);
+ }
+}
+
+float tangent(float x)
+{
+ x = tan(x);
+ //if (x < std::numeric_limits<float>::max() && x > -std::numeric_limits<float>::max()) return x;
+ //if (x >= std::numeric_limits<float>::max()) return std::numeric_limits<float>::max();
+ //if (x <= -std::numeric_limits<float>::max()) return -std::numeric_limits<float>::max();
+ if (x < 100000.0f && x > -100000.0f) return x;
+ if (x >= 100000.0f) return 100000.0f;
+ if (x <= 100000.0f) return -100000.0f;
+ return 0.0f;
+}
+
+#define DEBUG_TRAJ(a) //a
+
+void Spell::SelectImplicitTrajTargets()
+{
+ if (!m_targets.HasTraj())
+ return;
+
+ float dist2d = m_targets.GetDist2d();
+ if (!dist2d)
+ return;
+
+ float srcToDestDelta = m_targets.GetDst()->m_positionZ - m_targets.GetSrc()->m_positionZ;
+
+ std::list<WorldObject*> targets;
+ Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrc(), m_caster, m_spellInfo);
+ Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> searcher(m_caster, targets, check, GRID_MAP_TYPE_MASK_ALL);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrc(), dist2d);
+ if (targets.empty())
+ return;
+
+ targets.sort(Trinity::ObjectDistanceOrderPred(m_caster));
+
+ float b = tangent(m_targets.GetElevation());
+ float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
+ if (a > -0.0001f)
+ a = 0;
+ DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: a %f b %f", a, b);)
+
+ float bestDist = m_spellInfo->GetMaxRange(false);
+
+ std::list<WorldObject*>::const_iterator itr = targets.begin();
+ for (; itr != targets.end(); ++itr)
+ {
+ if (Unit* unitTarget = (*itr)->ToUnit())
+ if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
+ continue;
+
+ const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
+ // TODO: all calculation should be based on src instead of m_caster
+ const float objDist2d = m_targets.GetSrc()->GetExactDist2d(*itr) * cos(m_targets.GetSrc()->GetRelativeAngle(*itr));
+ const float dz = (*itr)->GetPositionZ() - m_targets.GetSrc()->m_positionZ;
+
+ DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);)
+
+ float dist = objDist2d - size;
+ float height = dist * (a * dist + b);
+ DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)
+ if (dist < bestDist && height < dz + size && height > dz - size)
+ {
+ bestDist = dist > 0 ? dist : 0;
+ break;
+ }
+
+#define CHECK_DIST {\
+ DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)\
+ if (dist > bestDist)\
+ continue;\
+ if (dist < objDist2d + size && dist > objDist2d - size)\
+ {\
+ bestDist = dist;\
+ break;\
+ }\
+ }
+
+ if (!a)
+ {
+ height = dz - size;
+ dist = height / b;
+ CHECK_DIST;
+
+ height = dz + size;
+ dist = height / b;
+ CHECK_DIST;
+
+ continue;
+ }
+
+ height = dz - size;
+ float sqrt1 = b * b + 4 * a * height;
+ if (sqrt1 > 0)
+ {
+ sqrt1 = sqrt(sqrt1);
+ dist = (sqrt1 - b) / (2 * a);
+ CHECK_DIST;
+ }
+
+ height = dz + size;
+ float sqrt2 = b * b + 4 * a * height;
+ if (sqrt2 > 0)
+ {
+ sqrt2 = sqrt(sqrt2);
+ dist = (sqrt2 - b) / (2 * a);
+ CHECK_DIST;
+
+ dist = (-sqrt2 - b) / (2 * a);
+ CHECK_DIST;
+ }
+
+ if (sqrt1 > 0)
+ {
+ dist = (-sqrt1 - b) / (2 * a);
+ CHECK_DIST;
+ }
+ }
+
+ if (m_targets.GetSrc()->GetExactDist2d(m_targets.GetDst()) > bestDist)
+ {
+ float x = m_targets.GetSrc()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
+ float y = m_targets.GetSrc()->m_positionY + sin(m_caster->GetOrientation()) * bestDist;
+ float z = m_targets.GetSrc()->m_positionZ + bestDist * (a * bestDist + b);
+
+ if (itr != targets.end())
+ {
+ float distSq = (*itr)->GetExactDistSq(x, y, z);
+ float sizeSq = (*itr)->GetObjectSize();
+ sizeSq *= sizeSq;
+ DEBUG_TRAJ(sLog->outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);)
+ if (distSq > sizeSq)
+ {
+ float factor = 1 - sqrt(sizeSq / distSq);
+ x += factor * ((*itr)->GetPositionX() - x);
+ y += factor * ((*itr)->GetPositionY() - y);
+ z += factor * ((*itr)->GetPositionZ() - z);
+
+ distSq = (*itr)->GetExactDistSq(x, y, z);
+ DEBUG_TRAJ(sLog->outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);)
+ }
+ }
+
+ Position trajDst;
+ trajDst.Relocate(x, y, z, m_caster->GetOrientation());
+ m_targets.ModDst(trajDst);
+ }
+}
+
void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
{
// special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
@@ -865,6 +1777,192 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
}
}
+uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList)
+{
+ // this function selects which containers need to be searched for spell target
+ uint32 retMask = GRID_MAP_TYPE_MASK_ALL;
+
+ // filter searchers based on searched object type
+ switch (objType)
+ {
+ case TARGET_OBJECT_TYPE_UNIT:
+ case TARGET_OBJECT_TYPE_UNIT_AND_DEST:
+ case TARGET_OBJECT_TYPE_CORPSE:
+ case TARGET_OBJECT_TYPE_CORPSE_ENEMY:
+ case TARGET_OBJECT_TYPE_CORPSE_ALLY:
+ retMask &= GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_CREATURE;
+ break;
+ case TARGET_OBJECT_TYPE_GOBJ:
+ case TARGET_OBJECT_TYPE_GOBJ_ITEM:
+ retMask &= GRID_MAP_TYPE_MASK_GAMEOBJECT;
+ break;
+ default:
+ break;
+ }
+ if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD))
+ retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
+ if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS)
+ retMask &= GRID_MAP_TYPE_MASK_CORPSE | GRID_MAP_TYPE_MASK_PLAYER;
+ if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS)
+ retMask &= GRID_MAP_TYPE_MASK_PLAYER;
+
+ if (condList)
+ retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
+ return retMask;
+}
+
+template<class SEARCHER>
+void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius)
+{
+ if (!containerMask)
+ return;
+
+ // search world and grid for possible targets
+ bool searchInGrid = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_GAMEOBJECT);
+ bool searchInWorld = containerMask & (GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER | GRID_MAP_TYPE_MASK_CORPSE);
+ if (searchInGrid || searchInWorld)
+ {
+ float x,y;
+ x = pos->GetPositionX();
+ y = pos->GetPositionY();
+
+ CellCoord p(Trinity::ComputeCellCoord(x, y));
+ Cell cell(p);
+ cell.SetNoCreate();
+
+ Map& map = *(referer->GetMap());
+
+ if (searchInWorld)
+ {
+ TypeContainerVisitor<SEARCHER, WorldTypeMapContainer> world_object_notifier(searcher);
+ cell.Visit(p, world_object_notifier, map, radius, x, y);
+ }
+ if (searchInGrid)
+ {
+ TypeContainerVisitor<SEARCHER, GridTypeMapContainer > grid_object_notifier(searcher);
+ cell.Visit(p, grid_object_notifier, map, radius, x , y);
+ }
+ }
+}
+
+WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
+{
+ WorldObject* target = NULL;
+ uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
+ if (!containerTypeMask)
+ return NULL;
+ Trinity::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
+ Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> searcher(m_caster, target, check, containerTypeMask);
+ SearchTargets<Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
+ return target;
+}
+
+void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
+{
+ uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
+ if (!containerTypeMask)
+ return;
+ Trinity::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
+ Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
+}
+
+void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionList* condList, bool isChainHeal)
+{
+ // max dist for jump target selection
+ float jumpRadius = 0.0f;
+ switch (m_spellInfo->DmgClass)
+ {
+ case SPELL_DAMAGE_CLASS_RANGED:
+ // 7.5y for multi shot
+ jumpRadius = 7.5f;
+ break;
+ case SPELL_DAMAGE_CLASS_MELEE:
+ // 5y for swipe, cleave and similar
+ jumpRadius = 5.0f;
+ break;
+ case SPELL_DAMAGE_CLASS_NONE:
+ case SPELL_DAMAGE_CLASS_MAGIC:
+ // 12.5y for chain heal spell since 3.2 patch
+ if (isChainHeal)
+ jumpRadius = 12.5f;
+ // 10y as default for magic chain spells
+ else
+ jumpRadius = 10.0f;
+ break;
+ }
+
+ // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
+ bool isBouncingFar = (m_spellInfo->AttributesEx4 & SPELL_ATTR4_AREA_TARGET_CHAIN
+ || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE
+ || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC);
+
+ // max dist which spell can reach
+ float searchRadius = jumpRadius;
+ if (isBouncingFar)
+ searchRadius *= chainTargets;
+
+ std::list<WorldObject*> tempTargets;
+ SearchAreaTargets(tempTargets, searchRadius, target, m_caster, objectType, selectType, condList);
+ tempTargets.remove(target);
+
+ // remove targets which are always invalid for chain spells
+ // for some spells allow only chain targets in front of caster (swipe for example)
+ if (!isBouncingFar)
+ {
+ for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end();)
+ {
+ std::list<WorldObject*>::iterator checkItr = itr++;
+ if (!m_caster->HasInArc(static_cast<float>(M_PI), *checkItr))
+ tempTargets.erase(checkItr);
+ }
+ }
+
+ while (chainTargets)
+ {
+ // try to get unit for next chain jump
+ std::list<WorldObject*>::iterator foundItr = tempTargets.end();
+ // get unit with highest hp deficit in dist
+ if (isChainHeal)
+ {
+ uint32 maxHPDeficit = 0;
+ for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
+ {
+ if (Unit* unitTarget = (*itr)->ToUnit())
+ {
+ uint32 deficit = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
+ if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unitTarget, jumpRadius) && target->IsWithinLOSInMap(unitTarget))
+ {
+ foundItr = itr;
+ maxHPDeficit = deficit;
+ }
+ }
+ }
+ }
+ // get closest object
+ else
+ {
+ for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
+ {
+ if (foundItr == tempTargets.end())
+ {
+ if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr))
+ foundItr = itr;
+ }
+ else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr))
+ foundItr = itr;
+ }
+ }
+ // not found any valid target - chain ends
+ if (foundItr == tempTargets.end())
+ break;
+ target = *foundItr;
+ tempTargets.erase(foundItr);
+ targets.push_back(target);
+ --chainTargets;
+ }
+}
+
void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
{
//==========================================================================================
@@ -1791,1077 +2889,6 @@ struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*,
}
};
-void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uint32 num, SpellTargets TargetType)
-{
- Unit* cur = m_targets.GetUnitTarget();
- if (!cur)
- return;
-
- //FIXME: This very like horrible hack and wrong for most spells
- if (m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE)
- max_range += num * CHAIN_SPELL_JUMP_RADIUS;
-
- std::list<Unit*> tempUnitMap;
- if (TargetType == SPELL_TARGETS_CHAINHEAL)
- {
- SearchAreaTarget(tempUnitMap, max_range, PUSH_CHAIN, SPELL_TARGETS_ALLY);
- tempUnitMap.sort(ChainHealingOrder(m_caster));
- }
- else
- SearchAreaTarget(tempUnitMap, max_range, PUSH_CHAIN, TargetType);
- tempUnitMap.remove(cur);
-
- while (num)
- {
- TagUnitMap.push_back(cur);
- --num;
-
- if (tempUnitMap.empty())
- break;
-
- std::list<Unit*>::iterator next;
-
- if (TargetType == SPELL_TARGETS_CHAINHEAL)
- {
- next = tempUnitMap.begin();
- while (cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS || !cur->IsWithinLOSInMap(*next))
- {
- ++next;
- if (next == tempUnitMap.end())
- return;
- }
- }
- else
- {
- tempUnitMap.sort(Trinity::ObjectDistanceOrderPred(cur));
- next = tempUnitMap.begin();
-
- if (cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) // Don't search beyond the max jump radius
- break;
-
- // Check if (*next) is a valid chain target. If not, don't add to TagUnitMap, and repeat loop.
- // If you want to add any conditions to exclude a target from TagUnitMap, add condition in this while () loop.
- while ((m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE
- && !m_caster->isInFrontInMap(*next, max_range))
- || !m_caster->canSeeOrDetect(*next)
- || !cur->IsWithinLOSInMap(*next)
- || (*next)->GetCreatureType() == CREATURE_TYPE_CRITTER
- || ((GetSpellInfo()->AttributesEx6 & SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED) && !(*next)->CanFreeMove()))
- {
- ++next;
- if (next == tempUnitMap.end() || cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) // Don't search beyond the max jump radius
- return;
- }
- }
-
- cur = *next;
- tempUnitMap.erase(next);
- }
-}
-
-void Spell::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
-{
- if (TargetType == SPELL_TARGETS_GO)
- return;
-
- Position const* pos;
- switch (type)
- {
- case PUSH_DST_CENTER:
- CheckDst();
- pos = m_targets.GetDst();
- break;
- case PUSH_SRC_CENTER:
- CheckSrc();
- pos = m_targets.GetSrc();
- break;
- case PUSH_CHAIN:
- {
- Unit* target = m_targets.GetUnitTarget();
- if (!target)
- {
- sLog->outError("SPELL: cannot find unit target for spell ID %u\n", m_spellInfo->Id);
- return;
- }
- pos = target;
- break;
- }
- default:
- pos = m_caster;
- break;
- }
-
- Trinity::SpellNotifierCreatureAndPlayer notifier(m_caster, TagUnitMap, radius, type, TargetType, pos, entry, m_spellInfo);
- if ((m_spellInfo->AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS) || (TargetType == SPELL_TARGETS_ENTRY && !entry))
- m_caster->GetMap()->VisitWorld(pos->m_positionX, pos->m_positionY, radius, notifier);
- else
- m_caster->GetMap()->VisitAll(pos->m_positionX, pos->m_positionY, radius, notifier);
-}
-
-void Spell::SearchGOAreaTarget(std::list<GameObject*> &TagGOMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
-{
- if (TargetType != SPELL_TARGETS_GO)
- return;
-
- Position const* pos;
- switch (type)
- {
- case PUSH_DST_CENTER:
- CheckDst();
- pos = m_targets.GetDst();
- break;
- case PUSH_SRC_CENTER:
- CheckSrc();
- pos = m_targets.GetSrc();
- break;
- default:
- pos = m_caster;
- break;
- }
-
- Trinity::GameObjectInRangeCheck check(pos->m_positionX, pos->m_positionY, pos->m_positionZ, radius, entry);
- Trinity::GameObjectListSearcher<Trinity::GameObjectInRangeCheck> searcher(m_caster, TagGOMap, check);
- m_caster->GetMap()->VisitGrid(pos->m_positionX, pos->m_positionY, radius, searcher);
-}
-
-WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType, SpellEffIndex effIndex)
-{
- switch (TargetType)
- {
- case SPELL_TARGETS_ENTRY:
- {
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
- if (conditions.empty())
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell (ID: %u) (caster Entry: %u) does not have record in `conditions` for spell script target (ConditionSourceType 13)", m_spellInfo->Id, m_caster->GetEntry());
- if (m_spellInfo->IsPositive())
- return SearchNearbyTarget(range, SPELL_TARGETS_ALLY, effIndex);
- else
- return SearchNearbyTarget(range, SPELL_TARGETS_ENEMY, effIndex);
- }
-
- Creature* creatureScriptTarget = NULL;
- GameObject* goScriptTarget = NULL;
-
- for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
- {
- if ((*i_spellST)->ConditionType != CONDITION_SPELL_SCRIPT_TARGET)
- continue;
- if ((*i_spellST)->ConditionValue3 && !((*i_spellST)->ConditionValue3 & (1 << uint32(effIndex))))
- continue;
- switch ((*i_spellST)->ConditionValue1)
- {
- case SPELL_TARGET_TYPE_CONTROLLED:
- for (Unit::ControlList::iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
- if ((*itr)->GetEntry() == (*i_spellST)->ConditionValue2 && (*itr)->IsWithinDistInMap(m_caster, range))
- {
- goScriptTarget = NULL;
- creatureScriptTarget = (*itr)->ToCreature();
- range = m_caster->GetDistance(creatureScriptTarget);
- }
- break;
- case SPELL_TARGET_TYPE_GAMEOBJECT:
- if ((*i_spellST)->ConditionValue2)
- {
- if (GameObject* go = m_caster->FindNearestGameObject((*i_spellST)->ConditionValue2, range))
- {
- // remember found target and range, next attempt will find more near target with another entry
- goScriptTarget = go;
- creatureScriptTarget = NULL;
- range = m_caster->GetDistance(goScriptTarget);
- }
- }
- else if (focusObject) //Focus Object
- {
- float frange = m_caster->GetDistance(focusObject);
- if (range >= frange)
- {
- creatureScriptTarget = NULL;
- goScriptTarget = focusObject;
- range = frange;
- }
- }
- break;
- case SPELL_TARGET_TYPE_CREATURE:
- if (m_targets.GetUnitTarget() && m_targets.GetUnitTarget()->GetEntry() == (*i_spellST)->ConditionValue2)
- return m_targets.GetUnitTarget();
- case SPELL_TARGET_TYPE_DEAD:
- default:
- if (Creature* cre = m_caster->FindNearestCreature((*i_spellST)->ConditionValue2, range, (*i_spellST)->ConditionValue1 != SPELL_TARGET_TYPE_DEAD))
- {
- creatureScriptTarget = cre;
- goScriptTarget = NULL;
- range = m_caster->GetDistance(creatureScriptTarget);
- }
- break;
- }
- }
-
- if (creatureScriptTarget)
- return creatureScriptTarget;
- else
- return goScriptTarget;
- }
- default:
- case SPELL_TARGETS_ENEMY:
- {
- Unit* target = NULL;
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, range);
- Trinity::UnitLastSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
- m_caster->VisitNearbyObject(range, searcher);
- return target;
- }
- case SPELL_TARGETS_ALLY:
- {
- Unit* target = NULL;
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, range);
- Trinity::UnitLastSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(m_caster, target, u_check);
- m_caster->VisitNearbyObject(range, searcher);
- return target;
- }
- }
-}
-
-uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur)
-{
- SpellNotifyPushType pushType = PUSH_NONE;
- Player* modOwner = NULL;
- if (m_originalCaster)
- modOwner = m_originalCaster->GetSpellModOwner();
-
- uint32 effectMask = 1 << i;
- // ENTRY targets may have different selection lists, skip those for now until we can compare lists easily and quickly
- if (GetSpellInfo()->Effects[i].TargetA.GetSelectionCheckType() != TARGET_SELECT_CHECK_ENTRY &&
- GetSpellInfo()->Effects[i].TargetB.GetSelectionCheckType() != TARGET_SELECT_CHECK_ENTRY)
- for (uint32 j = i + 1; j < MAX_SPELL_EFFECTS; ++j)
- if (GetSpellInfo()->Effects[i].TargetA.GetTarget() == GetSpellInfo()->Effects[j].TargetA.GetTarget() &&
- GetSpellInfo()->Effects[i].TargetB.GetTarget() == GetSpellInfo()->Effects[j].TargetB.GetTarget() &&
- GetSpellInfo()->Effects[i].CalcRadius(m_caster) == GetSpellInfo()->Effects[j].CalcRadius(m_caster))
- effectMask |= 1 << j;
-
- switch (cur.GetType())
- {
- case TARGET_TYPE_UNIT_CASTER:
- {
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_CASTER:
- AddUnitTarget(m_caster, effectMask, false);
- break;
- case TARGET_DEST_CASTER_FISHING:
- {
- float min_dis = m_spellInfo->GetMinRange(true);
- float max_dis = m_spellInfo->GetMaxRange(true);
- float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
- float x, y, z, angle;
- angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle);
- m_targets.SetDst(x, y, z, m_caster->GetOrientation());
- break;
- }
- case TARGET_UNIT_MASTER:
- if (Unit* owner = m_caster->GetCharmerOrOwner())
- AddUnitTarget(owner, effectMask);
- break;
- case TARGET_UNIT_PET:
- if (Guardian* pet = m_caster->GetGuardianPet())
- AddUnitTarget(pet, effectMask);
- break;
- case TARGET_UNIT_SUMMONER:
- if (m_caster->isSummon())
- if (Unit* unit = m_caster->ToTempSummon()->GetSummoner())
- AddUnitTarget(unit, effectMask);
- break;
- case TARGET_UNIT_CASTER_AREA_PARTY:
- case TARGET_UNIT_CASTER_AREA_RAID:
- pushType = PUSH_CASTER_CENTER;
- break;
- case TARGET_UNIT_VEHICLE:
- if (Unit* vehicle = m_caster->GetVehicleBase())
- AddUnitTarget(vehicle, effectMask);
- break;
- case TARGET_UNIT_PASSENGER_0:
- case TARGET_UNIT_PASSENGER_1:
- case TARGET_UNIT_PASSENGER_2:
- case TARGET_UNIT_PASSENGER_3:
- case TARGET_UNIT_PASSENGER_4:
- case TARGET_UNIT_PASSENGER_5:
- case TARGET_UNIT_PASSENGER_6:
- case TARGET_UNIT_PASSENGER_7:
- if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle())
- if (Unit* unit = m_caster->GetVehicleKit()->GetPassenger(cur.GetTarget() - TARGET_UNIT_PASSENGER_0))
- AddUnitTarget(unit, effectMask);
- break;
- default:
- break;
- }
- break;
- }
-
- case TARGET_TYPE_UNIT_TARGET:
- {
- Unit* target = m_targets.GetUnitTarget();
- if (!target)
- {
- sLog->outError("SPELL: no unit target for spell ID %u", m_spellInfo->Id);
- break;
- }
-
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_TARGET_ENEMY:
- case TARGET_UNIT_TARGET_ANY:
- pushType = PUSH_CHAIN;
- break;
- case TARGET_UNIT_TARGET_CHAINHEAL_ALLY:
- pushType = PUSH_CHAIN;
- break;
- case TARGET_UNIT_TARGET_ALLY:
- AddUnitTarget(target, effectMask, false);
- break;
- case TARGET_UNIT_TARGET_RAID:
- case TARGET_UNIT_TARGET_PARTY:
- case TARGET_UNIT_TARGET_MINIPET:
- AddUnitTarget(target, effectMask, false);
- break;
- case TARGET_UNIT_TARGET_PASSENGER:
- AddUnitTarget(target, effectMask, false);
- break;
- case TARGET_UNIT_LASTTARGET_AREA_PARTY:
- case TARGET_UNIT_TARGET_AREA_RAID_CLASS:
- pushType = PUSH_CASTER_CENTER; // not real
- break;
- default:
- break;
- }
- break;
- }
-
- case TARGET_TYPE_UNIT_NEARBY:
- {
- WorldObject* target = NULL;
- float range;
-
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_NEARBY_ENEMY:
- range = m_spellInfo->GetMaxRange(false);
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- target = SearchNearbyTarget(range, SPELL_TARGETS_ENEMY, SpellEffIndex(i));
- break;
- case TARGET_UNIT_NEARBY_ALLY:
- case TARGET_UNIT_NEARBY_PARTY: // TODO: fix party/raid targets
- case TARGET_UNIT_NEARBY_RAID:
- range = m_spellInfo->GetMaxRange(true);
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- target = SearchNearbyTarget(range, SPELL_TARGETS_ALLY, SpellEffIndex(i));
- break;
- case TARGET_UNIT_NEARBY_ENTRY:
- case TARGET_GAMEOBJECT_NEARBY_ENTRY:
- range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive());
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY, SpellEffIndex(i));
- break;
- default:
- break;
- }
-
- if (!target)
- return 0;
- else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
- AddGOTarget((GameObject*)target, effectMask);
- else
- {
- pushType = PUSH_CHAIN;
-
- if (m_targets.GetUnitTarget() != target)
- m_targets.SetUnitTarget((Unit*)target);
- }
-
- break;
- }
-
- case TARGET_TYPE_AREA_SRC:
- pushType = PUSH_SRC_CENTER;
- break;
-
- case TARGET_TYPE_AREA_DST:
- pushType = PUSH_DST_CENTER;
- break;
-
- case TARGET_TYPE_AREA_CONE:
- if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_BACK)
- pushType = PUSH_IN_BACK;
- else if (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_LINE)
- pushType = PUSH_IN_LINE;
- else
- pushType = PUSH_IN_FRONT;
- break;
-
- case TARGET_TYPE_DEST_CASTER: //4+8+2
- {
- if (cur.GetTarget() == TARGET_SRC_CASTER)
- {
- m_targets.SetSrc(*m_caster);
- break;
- }
- else if (cur.GetTarget() == TARGET_DEST_CASTER)
- {
- m_targets.SetDst(*m_caster);
- break;
- }
-
- float angle, dist;
-
- float objSize = m_caster->GetObjectSize();
- if (cur.GetTarget() == TARGET_DEST_CASTER_SUMMON)
- dist = 0.0f;
- else
- dist = m_spellInfo->Effects[i].CalcRadius(m_caster);
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, dist, this);
- if (dist < objSize)
- dist = objSize;
- else if (cur.GetTarget() == TARGET_DEST_CASTER_RANDOM)
- dist = objSize + (dist - objSize) * (float)rand_norm();
-
- switch (cur.GetTarget())
- {
- case TARGET_DEST_CASTER_FRONT_LEFT: angle = static_cast<float>(-M_PI/4); break;
- case TARGET_DEST_CASTER_BACK_LEFT: angle = static_cast<float>(-3*M_PI/4); break;
- case TARGET_DEST_CASTER_BACK_RIGHT: angle = static_cast<float>(3*M_PI/4); break;
- case TARGET_DEST_CASTER_FRONT_RIGHT:angle = static_cast<float>(M_PI/4); break;
- case TARGET_DEST_CASTER_SUMMON:
- case TARGET_DEST_CASTER_FRONT_LEAP:
- case TARGET_DEST_CASTER_FRONT: angle = 0.0f; break;
- case TARGET_DEST_CASTER_BACK: angle = static_cast<float>(M_PI); break;
- case TARGET_DEST_CASTER_RIGHT: angle = static_cast<float>(-M_PI/2); break;
- case TARGET_DEST_CASTER_LEFT: angle = static_cast<float>(M_PI/2); break;
- default: angle = (float)rand_norm()*static_cast<float>(2*M_PI); break;
- }
-
- Position pos;
- if (cur.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP)
- m_caster->GetFirstCollisionPosition(pos, dist, angle);
- else
- m_caster->GetNearPosition(pos, dist, angle);
- m_targets.SetDst(*m_caster);
- m_targets.ModDst(pos);
- break;
- }
-
- case TARGET_TYPE_DEST_TARGET: //2+8+2
- {
- Unit* target = m_targets.GetUnitTarget();
- if (!target)
- {
- sLog->outError("SPELL: no unit target for spell ID %u", m_spellInfo->Id);
- break;
- }
-
- if (cur.GetTarget() == TARGET_DEST_TARGET_ENEMY || cur.GetTarget() == TARGET_DEST_TARGET_ANY)
- {
- m_targets.SetDst(*target);
- break;
- }
-
- float angle, dist;
-
- float objSize = target->GetObjectSize();
- dist = m_spellInfo->Effects[i].CalcRadius(m_caster);
- if (dist < objSize)
- dist = objSize;
- else if (cur.GetTarget() == TARGET_DEST_TARGET_RANDOM)
- dist = objSize + (dist - objSize) * (float)rand_norm();
-
- switch (cur.GetTarget())
- {
- case TARGET_DEST_TARGET_FRONT: angle = 0.0f; break;
- case TARGET_DEST_TARGET_BACK: angle = static_cast<float>(M_PI); break;
- case TARGET_DEST_TARGET_RIGHT: angle = static_cast<float>(M_PI/2); break;
- case TARGET_DEST_TARGET_LEFT: angle = static_cast<float>(-M_PI/2); break;
- case TARGET_DEST_TARGET_FRONT_LEFT: angle = static_cast<float>(-M_PI/4); break;
- case TARGET_DEST_TARGET_BACK_LEFT: angle = static_cast<float>(-3*M_PI/4); break;
- case TARGET_DEST_TARGET_BACK_RIGHT: angle = static_cast<float>(3*M_PI/4); break;
- case TARGET_DEST_TARGET_FRONT_RIGHT:angle = static_cast<float>(M_PI/4); break;
- default: angle = (float)rand_norm()*static_cast<float>(2*M_PI); break;
- }
-
- Position pos;
- target->GetNearPosition(pos, dist, angle);
- m_targets.SetDst(*target);
- m_targets.ModDst(pos);
- break;
- }
-
- case TARGET_TYPE_DEST_DEST: //5+8+1
- {
- if (!m_targets.HasDst())
- {
- sLog->outError("SPELL: no destination for spell ID %u", m_spellInfo->Id);
- break;
- }
-
- float angle;
- switch (cur.GetTarget())
- {
- case TARGET_DEST_DYNOBJ_ENEMY:
- case TARGET_DEST_DYNOBJ_ALLY:
- case TARGET_DEST_DYNOBJ_NONE:
- case TARGET_DEST_DEST:
- return effectMask;
- case TARGET_DEST_TRAJ:
- SelectTrajTargets();
- return effectMask;
- case TARGET_DEST_DEST_FRONT: angle = 0.0f; break;
- case TARGET_DEST_DEST_BACK: angle = static_cast<float>(M_PI); break;
- case TARGET_DEST_DEST_RIGHT: angle = static_cast<float>(M_PI/2); break;
- case TARGET_DEST_DEST_LEFT: angle = static_cast<float>(-M_PI/2); break;
- case TARGET_DEST_DEST_FRONT_LEFT: angle = static_cast<float>(-M_PI/4); break;
- case TARGET_DEST_DEST_BACK_LEFT: angle = static_cast<float>(-3*M_PI/4); break;
- case TARGET_DEST_DEST_BACK_RIGHT: angle = static_cast<float>(3*M_PI/4); break;
- case TARGET_DEST_DEST_FRONT_RIGHT:angle = static_cast<float>(M_PI/4); break;
- default: angle = (float)rand_norm()*static_cast<float>(2*M_PI); break;
- }
-
- float dist = m_spellInfo->Effects[i].CalcRadius(m_caster);
- if (cur.GetTarget() == TARGET_DEST_DEST_RANDOM || cur.GetTarget() == TARGET_DEST_DEST_RADIUS)
- dist *= (float)rand_norm();
-
- // must has dst, no need to set flag
- Position pos = *m_targets.GetDst();
- m_caster->MovePosition(pos, dist, angle);
- m_targets.ModDst(pos);
- break;
- }
-
- case TARGET_TYPE_DEST_SPECIAL:
- {
- switch (cur.GetTarget())
- {
- case TARGET_DEST_DB:
- if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id))
- {
- //TODO: fix this check
- if (m_spellInfo->Effects[0].Effect == SPELL_EFFECT_TELEPORT_UNITS || m_spellInfo->Effects[1].Effect == SPELL_EFFECT_TELEPORT_UNITS || m_spellInfo->Effects[2].Effect == SPELL_EFFECT_TELEPORT_UNITS)
- m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
- else if (st->target_mapId == m_caster->GetMapId())
- m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
- }
- else
- {
- sLog->outError("SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id);
- Unit* target = NULL;
- if (uint64 guid = m_caster->GetUInt64Value(UNIT_FIELD_TARGET))
- target = ObjectAccessor::GetUnit(*m_caster, guid);
- m_targets.SetDst(target ? *target : *m_caster);
- }
- break;
- case TARGET_DEST_HOME:
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_targets.SetDst(m_caster->ToPlayer()->m_homebindX, m_caster->ToPlayer()->m_homebindY, m_caster->ToPlayer()->m_homebindZ, m_caster->ToPlayer()->GetOrientation(), m_caster->ToPlayer()->m_homebindMapId);
- break;
- case TARGET_DEST_NEARBY_ENTRY:
- {
- float range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive());
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
-
- if (WorldObject* target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY, SpellEffIndex(i)))
- m_targets.SetDst(*target);
- break;
- }
- default:
- break;
- }
- break;
- }
-
- case TARGET_TYPE_CHANNEL:
- {
- if (!m_originalCaster || !m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: no current channeled spell for spell ID %u - spell triggering this spell was interrupted.", m_spellInfo->Id);
- break;
- }
-
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_CHANNEL_TARGET:
- // unit target may be no longer avalible - teleported out of map for example
- if (Unit* target = Unit::GetUnit(*m_caster, m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.GetUnitTargetGUID()))
- AddUnitTarget(target, effectMask);
- else
- sLog->outError("SPELL: cannot find channel spell target for spell ID %u", m_spellInfo->Id);
- break;
- case TARGET_DEST_CHANNEL_TARGET:
- if (m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.HasDst())
- m_targets.SetDst(m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets);
- else if (Unit* target = Unit::GetUnit(*m_caster, m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.GetUnitTargetGUID()))
- m_targets.SetDst(*target);
- else
- sLog->outError("SPELL: cannot find channel spell destination for spell ID %u", m_spellInfo->Id);
- break;
- case TARGET_DEST_CHANNEL_CASTER:
- m_targets.SetDst(*m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->GetCaster());
- break;
- default:
- break;
- }
- break;
- }
-
- default:
- {
- switch (cur.GetTarget())
- {
- case TARGET_GAMEOBJECT_TARGET:
- if (m_targets.GetGOTarget())
- AddGOTarget(m_targets.GetGOTarget(), effectMask);
- break;
- case TARGET_GAMEOBJECT_ITEM_TARGET:
- if (m_targets.GetGOTargetGUID())
- AddGOTarget(m_targets.GetGOTarget(), effectMask);
- else if (m_targets.GetItemTarget())
- AddItemTarget(m_targets.GetItemTarget(), effectMask);
- break;
- default:
- sLog->outError("SPELL (caster[type: %u; guidlow: %u], spell: %u): unhandled spell target (%u)",
- m_caster->GetTypeId(), m_caster->GetGUIDLow(), m_spellInfo->Id, cur.GetTarget());
- break;
- }
- break;
- }
- }
-
- if (pushType == PUSH_CHAIN) // Chain
- {
- Unit* target = m_targets.GetUnitTarget();
- if (!target)
- {
- sLog->outError("SPELL: no chain unit target for spell ID %u", m_spellInfo->Id);
- return 0;
- }
-
- //Chain: 2, 6, 22, 25, 45, 77
- uint32 maxTargets = m_spellInfo->Effects[i].ChainTarget;
- if (modOwner)
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
-
- if (maxTargets > 1)
- {
- //otherwise, this multiplier is used for something else
- for (uint32 k = i; k < MAX_SPELL_EFFECTS; ++k)
- if (effectMask & (1 << k))
- m_damageMultipliers[k] = 1.0f;
- m_applyMultiplierMask |= effectMask;
-
- float range;
- std::list<Unit*> unitList;
-
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_NEARBY_ENEMY:
- case TARGET_UNIT_TARGET_ENEMY:
- case TARGET_UNIT_NEARBY_ENTRY: // fix me
- range = m_spellInfo->GetMaxRange(false);
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- SearchChainTarget(unitList, range, maxTargets, SPELL_TARGETS_ENEMY);
- break;
- case TARGET_UNIT_TARGET_CHAINHEAL_ALLY:
- case TARGET_UNIT_NEARBY_ALLY: // fix me
- case TARGET_UNIT_NEARBY_PARTY:
- case TARGET_UNIT_NEARBY_RAID:
- range = m_spellInfo->GetMaxRange(true);
- if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- SearchChainTarget(unitList, range, maxTargets, SPELL_TARGETS_CHAINHEAL);
- break;
- default:
- break;
- }
-
- CallScriptAfterUnitTargetSelectHandlers(unitList, SpellEffIndex(i));
-
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
- AddUnitTarget(*itr, effectMask, false);
- }
- else
- AddUnitTarget(target, effectMask, false);
- }
- else if (pushType)
- {
- float radius;
- SpellTargets targetType;
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_SRC_AREA_ENEMY:
- case TARGET_UNIT_DEST_AREA_ENEMY:
- case TARGET_UNIT_CONE_ENEMY_24:
- case TARGET_UNIT_CONE_ENEMY_54:
- case TARGET_UNIT_CONE_ENEMY_104:
- radius = m_spellInfo->Effects[i].CalcRadius();
- targetType = SPELL_TARGETS_ENEMY;
- break;
- case TARGET_UNIT_SRC_AREA_ALLY:
- case TARGET_UNIT_DEST_AREA_ALLY:
- case TARGET_UNIT_CONE_ALLY:
- radius = m_spellInfo->Effects[i].CalcRadius();
- targetType = SPELL_TARGETS_ALLY;
- break;
- case TARGET_UNIT_DEST_AREA_ENTRY:
- case TARGET_UNIT_SRC_AREA_ENTRY:
- case TARGET_UNIT_CONE_ENTRY: // fix me
- radius = m_spellInfo->Effects[i].CalcRadius();
- targetType = SPELL_TARGETS_ENTRY;
- break;
- case TARGET_GAMEOBJECT_SRC_AREA:
- case TARGET_GAMEOBJECT_DEST_AREA:
- case TARGET_GAMEOBJECT_CONE:
- radius = m_spellInfo->Effects[i].CalcRadius();
- targetType = SPELL_TARGETS_GO;
- break;
- default:
- radius = m_spellInfo->Effects[i].CalcRadius();
- targetType = SPELL_TARGETS_NONE;
- break;
- }
-
- if (modOwner)
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
- radius *= m_spellValue->RadiusMod;
-
- std::list<Unit*> unitList;
- std::list<GameObject*> gobjectList;
- switch (targetType)
- {
- case SPELL_TARGETS_ENTRY:
- {
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
- if (!conditions.empty())
- {
- for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
- {
- if ((*i_spellST)->ConditionType != CONDITION_SPELL_SCRIPT_TARGET)
- continue;
- if ((*i_spellST)->ConditionValue3 && !((*i_spellST)->ConditionValue3 & effectMask))
- continue;
- if ((*i_spellST)->ConditionValue1 == SPELL_TARGET_TYPE_CREATURE)
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, (*i_spellST)->ConditionValue2);
- else if ((*i_spellST)->ConditionValue1 == SPELL_TARGET_TYPE_CONTROLLED)
- {
- for (Unit::ControlList::iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
- if ((*itr)->GetEntry() == (*i_spellST)->ConditionValue2 &&
- (*itr)->IsInMap(m_caster)) // For 60243 and 52173 need skip radius check or use range (no radius entry for effect)
- unitList.push_back(*itr);
- }
- }
- }
- else
- {
- // Custom entries
- // TODO: move these to sql
- switch (m_spellInfo->Id)
- {
- case 46584: // Raise Dead
- {
- if (WorldObject* result = FindCorpseUsing<Trinity::RaiseDeadObjectCheck>())
- {
- switch (result->GetTypeId())
- {
- case TYPEID_UNIT:
- case TYPEID_PLAYER:
- unitList.push_back(result->ToUnit());
- // no break;
- case TYPEID_CORPSE: // wont work until corpses are allowed in target lists, but at least will send dest in packet
- m_targets.SetDst(*result);
- break;
- default:
- break;
- }
- }
- break;
- }
- // Corpse Explosion
- case 49158:
- case 51325:
- case 51326:
- case 51327:
- case 51328:
- // Search for ghoul if our ghoul or dead body not valid unit target
- if (!(m_targets.GetUnitTarget() && ((m_targets.GetUnitTarget()->GetEntry() == 26125 && m_targets.GetUnitTarget()->GetOwnerGUID() == m_caster->GetGUID())
- || (m_targets.GetUnitTarget()->getDeathState() == CORPSE
- && m_targets.GetUnitTarget()->GetTypeId() == TYPEID_UNIT
- && !(m_targets.GetUnitTarget()->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)
- && m_targets.GetUnitTarget()->GetDisplayId() == m_targets.GetUnitTarget()->GetNativeDisplayId()))))
- {
- CleanupTargetList();
-
- WorldObject* result = FindCorpseUsing<Trinity::ExplodeCorpseObjectCheck>();
-
- if (result)
- {
- switch (result->GetTypeId())
- {
- case TYPEID_UNIT:
- case TYPEID_PLAYER:
- m_targets.SetUnitTarget((Unit*)result);
- break;
- default:
- break;
- }
- }
- else
- {
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
- SendCastResult(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
- finish(false);
- }
- }
- break;
-
- default:
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell (ID: %u) (caster Entry: %u) does not have type CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET record in `conditions` table.", m_spellInfo->Id, m_caster->GetEntry());
-
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_TELEPORT_UNITS)
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, 0);
- else if (m_spellInfo->IsPositiveEffect(i))
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
- else
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
- }
- }
- break;
- }
- case SPELL_TARGETS_GO:
- {
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
- if (!conditions.empty())
- {
- for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
- {
- if ((*i_spellST)->ConditionType != CONDITION_SPELL_SCRIPT_TARGET)
- continue;
- if ((*i_spellST)->ConditionValue3 && !((*i_spellST)->ConditionValue3 & effectMask))
- continue;
- if ((*i_spellST)->ConditionValue1 == SPELL_TARGET_TYPE_GAMEOBJECT)
- SearchGOAreaTarget(gobjectList, radius, pushType, SPELL_TARGETS_GO, (*i_spellST)->ConditionValue2);
- }
- }
- else
- {
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ACTIVATE_OBJECT)
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell (ID: %u) (caster Entry: %u) with SPELL_EFFECT_ACTIVATE_OBJECT does not have type CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET record in `conditions` table.", m_spellInfo->Id, m_caster->GetEntry());
- SearchGOAreaTarget(gobjectList, radius, pushType, SPELL_TARGETS_GO);
- }
- break;
- }
- case SPELL_TARGETS_ALLY:
- case SPELL_TARGETS_ENEMY:
- case SPELL_TARGETS_CHAINHEAL:
- case SPELL_TARGETS_ANY:
- SearchAreaTarget(unitList, radius, pushType, targetType);
- break;
- default:
- switch (cur.GetTarget())
- {
- case TARGET_UNIT_SRC_AREA_PARTY:
- case TARGET_UNIT_DEST_AREA_PARTY:
- m_caster->GetPartyMemberInDist(unitList, radius); //fix me
- break;
- case TARGET_UNIT_LASTTARGET_AREA_PARTY:
- m_targets.GetUnitTarget()->GetPartyMemberInDist(unitList, radius);
- break;
- case TARGET_UNIT_CASTER_AREA_PARTY:
- m_caster->GetPartyMemberInDist(unitList, radius);
- break;
- case TARGET_UNIT_CASTER_AREA_RAID:
- m_caster->GetRaidMember(unitList, radius);
- break;
- case TARGET_UNIT_TARGET_AREA_RAID_CLASS:
- {
- Player* targetPlayer = m_targets.GetUnitTarget() && m_targets.GetUnitTarget()->GetTypeId() == TYPEID_PLAYER
- ? (Player*)m_targets.GetUnitTarget() : NULL;
-
- Group* group = targetPlayer ? targetPlayer->GetGroup() : NULL;
- if (group)
- {
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- Player* Target = itr->getSource();
-
- // IsHostileTo check duel and controlled by enemy
- if (Target && targetPlayer->IsWithinDistInMap(Target, radius) && targetPlayer->getClass() == Target->getClass() && !m_caster->IsHostileTo(Target))
- AddUnitTarget(Target, effectMask);
- }
- }
- else if (m_targets.GetUnitTarget())
- AddUnitTarget(m_targets.GetUnitTarget(), effectMask);
- break;
- }
- default:
- break;
- }
- break;
- }
-
- if (!unitList.empty())
- {
- // Special target selection for smart heals and energizes
- uint32 maxSize = 0;
- int32 power = -1;
- switch (m_spellInfo->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- switch (m_spellInfo->Id)
- {
- case 52759: // Ancestral Awakening
- case 71610: // Echoes of Light (Althor's Abacus normal version)
- case 71641: // Echoes of Light (Althor's Abacus heroic version)
- maxSize = 1;
- power = POWER_HEALTH;
- break;
- case 54968: // Glyph of Holy Light
- maxSize = m_spellInfo->MaxAffectedTargets;
- power = POWER_HEALTH;
- break;
- case 57669: // Replenishment
- // In arenas Replenishment may only affect the caster
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->InArena())
- {
- unitList.clear();
- unitList.push_back(m_caster);
- break;
- }
- maxSize = 10;
- power = POWER_MANA;
- break;
- default:
- break;
- }
- break;
- case SPELLFAMILY_PRIEST:
- if (m_spellInfo->SpellFamilyFlags[0] == 0x10000000) // Circle of Healing
- {
- maxSize = m_caster->HasAura(55675) ? 6 : 5; // Glyph of Circle of Healing
- power = POWER_HEALTH;
- }
- else if (m_spellInfo->Id == 64844) // Divine Hymn
- {
- maxSize = 3;
- power = POWER_HEALTH;
- }
- else if (m_spellInfo->Id == 64904) // Hymn of Hope
- {
- maxSize = 3;
- power = POWER_MANA;
- }
- else
- break;
-
- // Remove targets outside caster's raid
- for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();)
- {
- if (!(*itr)->IsInRaidWith(m_caster))
- itr = unitList.erase(itr);
- else
- ++itr;
- }
- break;
- case SPELLFAMILY_DRUID:
- if (m_spellInfo->SpellFamilyFlags[1] == 0x04000000) // Wild Growth
- {
- maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth
- power = POWER_HEALTH;
- }
- else if (m_spellInfo->SpellFamilyFlags[2] == 0x0100) // Starfall
- {
- // Remove targets not in LoS or in stealth
- for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();)
- {
- if ((*itr)->HasStealthAura() || (*itr)->HasInvisibilityAura() || !(*itr)->IsWithinLOSInMap(m_caster))
- itr = unitList.erase(itr);
- else
- ++itr;
- }
- break;
- }
- else
- break;
-
- // Remove targets outside caster's raid
- for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();)
- if (!(*itr)->IsInRaidWith(m_caster))
- itr = unitList.erase(itr);
- else
- ++itr;
- break;
- default:
- break;
- }
-
- if (maxSize && power != -1)
- {
- if (Powers(power) == POWER_HEALTH)
- {
- if (unitList.size() > maxSize)
- {
- unitList.sort(Trinity::HealthPctOrderPred());
- unitList.resize(maxSize);
- }
- }
- else
- {
- for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();)
- if ((*itr)->getPowerType() != (Powers)power)
- itr = unitList.erase(itr);
- else
- ++itr;
-
- if (unitList.size() > maxSize)
- {
- unitList.sort(Trinity::PowerPctOrderPred((Powers)power));
- unitList.resize(maxSize);
- }
- }
- }
-
- // Other special target selection goes here
- if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
- {
- Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
- for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
- maxTargets += (*j)->GetAmount();
-
- if (m_spellInfo->Id == 5246) //Intimidating Shout
- unitList.remove(m_targets.GetUnitTarget());
- Trinity::RandomResizeList(unitList, maxTargets);
- }
-
- CallScriptAfterUnitTargetSelectHandlers(unitList, SpellEffIndex(i));
-
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
- AddUnitTarget(*itr, effectMask, false);
- }
-
- if (!gobjectList.empty())
- {
- if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
- {
- Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
- for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
- maxTargets += (*j)->GetAmount();
-
- Trinity::RandomResizeList(gobjectList, maxTargets);
- }
- for (std::list<GameObject*>::iterator itr = gobjectList.begin(); itr != gobjectList.end(); ++itr)
- AddGOTarget(*itr, effectMask);
- }
- }
-
- return effectMask;
-}
-
void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura)
{
if (m_CastItem)
@@ -4478,9 +4505,7 @@ void Spell::TakeReagents()
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- ItemTemplate const* castItemTemplate = m_CastItem
- ? m_CastItem->GetTemplate()
- : NULL;
+ ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : NULL;
// do not take reagents for these item casts
if (castItemTemplate && castItemTemplate->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)
@@ -6847,150 +6872,6 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
}
}
-float tangent(float x)
-{
- x = tan(x);
- //if (x < std::numeric_limits<float>::max() && x > -std::numeric_limits<float>::max()) return x;
- //if (x >= std::numeric_limits<float>::max()) return std::numeric_limits<float>::max();
- //if (x <= -std::numeric_limits<float>::max()) return -std::numeric_limits<float>::max();
- if (x < 100000.0f && x > -100000.0f) return x;
- if (x >= 100000.0f) return 100000.0f;
- if (x <= 100000.0f) return -100000.0f;
- return 0.0f;
-}
-
-#define DEBUG_TRAJ(a) //a
-
-void Spell::SelectTrajTargets()
-{
- if (!m_targets.HasTraj())
- return;
-
- float dist2d = m_targets.GetDist2d();
- if (!dist2d)
- return;
-
- float srcToDestDelta = m_targets.GetDst()->m_positionZ - m_targets.GetSrc()->m_positionZ;
-
- UnitList unitList;
- SearchAreaTarget(unitList, dist2d, PUSH_IN_THIN_LINE, SPELL_TARGETS_ANY);
- if (unitList.empty())
- return;
-
- unitList.sort(Trinity::ObjectDistanceOrderPred(m_caster));
-
- float b = tangent(m_targets.GetElevation());
- float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
- if (a > -0.0001f)
- a = 0;
- DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: a %f b %f", a, b);)
-
- float bestDist = m_spellInfo->GetMaxRange(false);
-
- UnitList::const_iterator itr = unitList.begin();
- for (; itr != unitList.end(); ++itr)
- {
- if (m_caster == *itr || m_caster->IsOnVehicle(*itr) || (*itr)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
- continue;
-
- const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
- // TODO: all calculation should be based on src instead of m_caster
- const float objDist2d = m_targets.GetSrc()->GetExactDist2d(*itr) * cos(m_targets.GetSrc()->GetRelativeAngle(*itr));
- const float dz = (*itr)->GetPositionZ() - m_targets.GetSrc()->m_positionZ;
-
- DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);)
-
- float dist = objDist2d - size;
- float height = dist * (a * dist + b);
- DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)
- if (dist < bestDist && height < dz + size && height > dz - size)
- {
- bestDist = dist > 0 ? dist : 0;
- break;
- }
-
-#define CHECK_DIST {\
- DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height);)\
- if (dist > bestDist)\
- continue;\
- if (dist < objDist2d + size && dist > objDist2d - size)\
- {\
- bestDist = dist;\
- break;\
- }\
- }
-
- if (!a)
- {
- height = dz - size;
- dist = height / b;
- CHECK_DIST;
-
- height = dz + size;
- dist = height / b;
- CHECK_DIST;
-
- continue;
- }
-
- height = dz - size;
- float sqrt1 = b * b + 4 * a * height;
- if (sqrt1 > 0)
- {
- sqrt1 = sqrt(sqrt1);
- dist = (sqrt1 - b) / (2 * a);
- CHECK_DIST;
- }
-
- height = dz + size;
- float sqrt2 = b * b + 4 * a * height;
- if (sqrt2 > 0)
- {
- sqrt2 = sqrt(sqrt2);
- dist = (sqrt2 - b) / (2 * a);
- CHECK_DIST;
-
- dist = (-sqrt2 - b) / (2 * a);
- CHECK_DIST;
- }
-
- if (sqrt1 > 0)
- {
- dist = (-sqrt1 - b) / (2 * a);
- CHECK_DIST;
- }
- }
-
- if (m_targets.GetSrc()->GetExactDist2d(m_targets.GetDst()) > bestDist)
- {
- float x = m_targets.GetSrc()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
- float y = m_targets.GetSrc()->m_positionY + sin(m_caster->GetOrientation()) * bestDist;
- float z = m_targets.GetSrc()->m_positionZ + bestDist * (a * bestDist + b);
-
- if (itr != unitList.end())
- {
- float distSq = (*itr)->GetExactDistSq(x, y, z);
- float sizeSq = (*itr)->GetObjectSize();
- sizeSq *= sizeSq;
- DEBUG_TRAJ(sLog->outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);)
- if (distSq > sizeSq)
- {
- float factor = 1 - sqrt(sizeSq / distSq);
- x += factor * ((*itr)->GetPositionX() - x);
- y += factor * ((*itr)->GetPositionY() - y);
- z += factor * ((*itr)->GetPositionZ() - z);
-
- distSq = (*itr)->GetExactDistSq(x, y, z);
- DEBUG_TRAJ(sLog->outError("Initial %f %f %f %f %f", x, y, z, distSq, sizeSq);)
- }
- }
-
- Position trajDst;
- trajDst.Relocate(x, y, z, m_caster->GetOrientation());
- m_targets.ModDst(trajDst);
- }
-}
-
void Spell::PrepareTargetProcessing()
{
CheckEffectExecuteData();
@@ -7342,3 +7223,152 @@ void Spell::CancelGlobalCooldown()
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
}
+
+namespace Trinity
+{
+
+WorldObjectSpellTargetCheck::WorldObjectSpellTargetCheck(Unit* caster, Unit* referer, SpellInfo const* spellInfo,
+ SpellTargetCheckTypes selectionType, ConditionList* condList) : _caster(caster), _referer(referer), _spellInfo(spellInfo),
+ _targetSelectionType(selectionType), _condList(condList)
+{
+ if (condList)
+ _condSrcInfo = new ConditionSourceInfo(NULL, caster);
+ else
+ _condSrcInfo = NULL;
+}
+
+WorldObjectSpellTargetCheck::~WorldObjectSpellTargetCheck()
+{
+ if (_condSrcInfo)
+ delete _condSrcInfo;
+}
+
+bool WorldObjectSpellTargetCheck::operator()(WorldObject* target)
+{
+ if (_spellInfo->CheckTarget(_caster, target, true) != SPELL_CAST_OK)
+ return false;
+ Unit* unitTarget = target->ToUnit();
+ if (Corpse* corpseTarget = target->ToCorpse())
+ {
+ // use ofter for party/assistance checks
+ if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
+ unitTarget = owner;
+ else
+ return false;
+ }
+ if (unitTarget)
+ {
+ switch (_targetSelectionType)
+ {
+ case TARGET_CHECK_ENEMY:
+ if (unitTarget->isTotem())
+ return false;
+ if (!_caster->_IsValidAttackTarget(unitTarget, _spellInfo))
+ return false;
+ break;
+ case TARGET_CHECK_ALLY:
+ if (unitTarget->isTotem())
+ return false;
+ if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo))
+ return false;
+ break;
+ case TARGET_CHECK_PARTY:
+ if (unitTarget->isTotem())
+ return false;
+ if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo))
+ return false;
+ if (!_referer->IsInPartyWith(unitTarget))
+ return false;
+ break;
+ case TARGET_CHECK_RAID_CLASS:
+ if (_referer->getClass() != unitTarget->getClass())
+ return false;
+ // nobreak;
+ case TARGET_CHECK_RAID:
+ if (unitTarget->isTotem())
+ return false;
+ if (!_caster->_IsValidAssistTarget(unitTarget, _spellInfo))
+ return false;
+ if (!_referer->IsInRaidWith(unitTarget))
+ return false;
+ break;
+ default:
+ break;
+ }
+ }
+ if (!_condSrcInfo)
+ return true;
+ _condSrcInfo->mConditionTargets[0] = target;
+ return sConditionMgr->IsObjectMeetToConditions(*_condSrcInfo, *_condList);
+}
+
+WorldObjectSpellNearbyTargetCheck::WorldObjectSpellNearbyTargetCheck(float range, Unit* caster, SpellInfo const* spellInfo,
+ SpellTargetCheckTypes selectionType, ConditionList* condList)
+ : WorldObjectSpellTargetCheck(caster, caster, spellInfo, selectionType, condList), _range(range), _position(caster)
+{
+}
+
+bool WorldObjectSpellNearbyTargetCheck::operator()(WorldObject* target)
+{
+ float dist = target->GetDistance(*_position);
+ if (dist < _range && WorldObjectSpellTargetCheck::operator ()(target))
+ {
+ _range = dist;
+ return true;
+ }
+ return false;
+}
+
+WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Position const* position, Unit* caster,
+ Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList)
+ : WorldObjectSpellTargetCheck(caster, referer, spellInfo, selectionType, condList), _range(range), _position(position)
+{
+}
+
+bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
+{
+ if (!target->IsWithinDist3d(_position, _range))
+ return false;
+ return WorldObjectSpellTargetCheck::operator ()(target);
+}
+
+WorldObjectSpellConeTargetCheck::WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster,
+ SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList)
+ : WorldObjectSpellAreaTargetCheck(range, caster, caster, caster, spellInfo, selectionType, condList), _coneAngle(coneAngle)
+{
+}
+
+bool WorldObjectSpellConeTargetCheck::operator()(WorldObject* target)
+{
+ if (_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_BACK)
+ {
+ if (!_caster->isInBack(target, _coneAngle))
+ return false;
+ }
+ else if (_spellInfo->AttributesCu & SPELL_ATTR0_CU_CONE_LINE)
+ {
+ if (!_caster->HasInLine(target, _caster->GetObjectSize()))
+ return false;
+ }
+ else
+ {
+ if (!_caster->isInFront(target, _coneAngle))
+ return false;
+ }
+ return WorldObjectSpellAreaTargetCheck::operator ()(target);
+}
+
+WorldObjectSpellTrajTargetCheck::WorldObjectSpellTrajTargetCheck(float range, Position const* position, Unit* caster, SpellInfo const* spellInfo)
+ : WorldObjectSpellAreaTargetCheck(range, position, caster, caster, spellInfo, TARGET_CHECK_DEFAULT, NULL)
+{
+}
+
+bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target)
+{
+ // return all targets on missile trajectory (0 - size of a missile)
+ if (!_caster->HasInLine(target, 0))
+ return false;
+ return WorldObjectSpellAreaTargetCheck::operator ()(target);
+}
+
+} //namespace Trinity
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 583123eb261..971bc1989ab 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -79,19 +79,6 @@ enum SpellRangeFlag
SPELL_RANGE_RANGED = 2, //hunter range and ranged weapon
};
-enum SpellNotifyPushType
-{
- PUSH_NONE = 0,
- PUSH_IN_FRONT,
- PUSH_IN_BACK,
- PUSH_IN_LINE,
- PUSH_IN_THIN_LINE,
- PUSH_SRC_CENTER,
- PUSH_DST_CENTER,
- PUSH_CASTER_CENTER, //this is never used in grid search
- PUSH_CHAIN,
-};
-
class SpellCastTargets
{
public:
@@ -210,17 +197,6 @@ enum SpellEffectHandleMode
SPELL_EFFECT_HANDLE_HIT_TARGET,
};
-enum SpellTargets
-{
- SPELL_TARGETS_NONE = 0,
- SPELL_TARGETS_ALLY,
- SPELL_TARGETS_ENEMY,
- SPELL_TARGETS_ENTRY,
- SPELL_TARGETS_CHAINHEAL,
- SPELL_TARGETS_ANY,
- SPELL_TARGETS_GO
-};
-
namespace Trinity
{
struct SpellNotifierCreatureAndPlayer;
@@ -228,7 +204,6 @@ namespace Trinity
class Spell
{
- friend struct Trinity::SpellNotifierCreatureAndPlayer;
friend void Unit::SetCurrentCastedSpell(Spell* pSpell);
friend class SpellScript;
public:
@@ -364,6 +339,32 @@ class Spell
Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, uint64 originalCasterGUID = 0, bool skipCheck = false);
~Spell();
+ void InitExplicitTargets(SpellCastTargets const& targets);
+ void SelectExplicitTargets();
+
+ void SelectSpellTargets();
+ void SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask);
+ void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+ void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+ void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask);
+ void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
+ void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
+ void SelectImplicitTrajTargets();
+
+ void SelectEffectTypeImplicitTargets(uint8 effIndex);
+
+ uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList);
+ template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius);
+
+ WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList = NULL);
+ void SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList);
+ void SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionList* condList, bool isChainHeal);
+
void prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura = NULL);
void cancel();
void update(uint32 difftime);
@@ -404,15 +405,6 @@ class Spell
void WriteSpellGoTargets(WorldPacket* data);
void WriteAmmoToPacket(WorldPacket* data);
- void InitExplicitTargets(SpellCastTargets const& targets);
- void SelectExplicitTargets();
- void SelectSpellTargets();
- void SelectEffectTypeImplicitTargets(uint8 effIndex);
- uint32 SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur);
- void SelectTrajTargets();
-
- template<typename T> WorldObject* FindCorpseUsing();
-
bool CheckEffectTarget(Unit const* target, uint32 eff) const;
bool CanAutoCast(Unit* target);
void CheckSrc() { if (!m_targets.HasSrc()) m_targets.SetSrc(*m_caster); }
@@ -607,10 +599,6 @@ class Spell
void DoAllEffectOnTarget(GOTargetInfo* target);
void DoAllEffectOnTarget(ItemTargetInfo* target);
bool UpdateChanneledTargetList();
- void SearchAreaTarget(std::list<Unit*> &unitList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
- void SearchGOAreaTarget(std::list<GameObject*> &gobjectList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
- void SearchChainTarget(std::list<Unit*> &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType);
- WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType, SpellEffIndex effIndex);
bool IsValidDeadOrAliveTarget(Unit const* target) const;
void HandleLaunchPhase();
void DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier);
@@ -676,98 +664,52 @@ class Spell
namespace Trinity
{
- struct SpellNotifierCreatureAndPlayer
+ struct WorldObjectSpellTargetCheck
{
- std::list<Unit*> *i_data;
- SpellNotifyPushType i_push_type;
- float i_radius;
- SpellTargets i_TargetType;
- const Unit* const i_source;
- uint32 i_entry;
- const Position* const i_pos;
- SpellInfo const* i_spellProto;
-
- SpellNotifierCreatureAndPlayer(Unit* source, std::list<Unit*> &data, float radius, SpellNotifyPushType type,
- SpellTargets TargetType = SPELL_TARGETS_ENEMY, const Position* pos = NULL, uint32 entry = 0, SpellInfo const* spellProto = NULL)
- : i_data(&data), i_push_type(type), i_radius(radius), i_TargetType(TargetType),
- i_source(source), i_entry(entry), i_pos(pos), i_spellProto(spellProto)
- {
- ASSERT(i_source);
- }
+ Unit* _caster;
+ Unit* _referer;
+ SpellInfo const* _spellInfo;
+ SpellTargetCheckTypes _targetSelectionType;
+ ConditionSourceInfo* _condSrcInfo;
+ ConditionList* _condList;
+
+ WorldObjectSpellTargetCheck(Unit* caster, Unit* referer, SpellInfo const* spellInfo,
+ SpellTargetCheckTypes selectionType, ConditionList* condList);
+ ~WorldObjectSpellTargetCheck();
+ bool operator()(WorldObject* target);
+ };
- template<class T> inline void Visit(GridRefManager<T>& m)
- {
- for (typename GridRefManager<T>::iterator itr = m.begin(); itr != m.end(); ++itr)
- {
- Unit* target = (Unit*)itr->getSource();
-
- if (i_spellProto->CheckTarget(i_source, target, true) != SPELL_CAST_OK)
- continue;
-
- switch (i_TargetType)
- {
- case SPELL_TARGETS_ENEMY:
- if (target->isTotem())
- continue;
- if (!i_source->_IsValidAttackTarget(target, i_spellProto))
- continue;
- break;
- case SPELL_TARGETS_ALLY:
- if (target->isTotem())
- continue;
- if (!i_source->_IsValidAssistTarget(target, i_spellProto))
- continue;
- break;
- case SPELL_TARGETS_ENTRY:
- if (target->GetEntry()!= i_entry)
- continue;
- break;
- case SPELL_TARGETS_ANY:
- default:
- break;
- }
-
- switch (i_push_type)
- {
- case PUSH_SRC_CENTER:
- case PUSH_DST_CENTER:
- case PUSH_CHAIN:
- default:
- if (target->IsWithinDist3d(i_pos, i_radius))
- i_data->push_back(target);
- break;
- case PUSH_IN_FRONT:
- if (i_source->isInFront(target, i_radius, static_cast<float>(M_PI/2)))
- i_data->push_back(target);
- break;
- case PUSH_IN_BACK:
- if (i_source->isInBack(target, i_radius, static_cast<float>(M_PI/2)))
- i_data->push_back(target);
- break;
- case PUSH_IN_LINE:
- if (i_source->HasInLine(target, i_radius, i_source->GetObjectSize()))
- i_data->push_back(target);
- break;
- case PUSH_IN_THIN_LINE: // only traj
- if (i_pos->HasInLine(target, i_radius, 0))
- i_data->push_back(target);
- break;
- }
- }
- }
+ struct WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck
+ {
+ float _range;
+ Position const* _position;
+ WorldObjectSpellNearbyTargetCheck(float range, Unit* caster, SpellInfo const* spellInfo,
+ SpellTargetCheckTypes selectionType, ConditionList* condList);
+ bool operator()(WorldObject* target);
+ };
+
+ struct WorldObjectSpellAreaTargetCheck : public WorldObjectSpellTargetCheck
+ {
+ float _range;
+ Position const* _position;
+ WorldObjectSpellAreaTargetCheck(float range, Position const* position, Unit* caster,
+ Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList);
+ bool operator()(WorldObject* target);
+ };
- #ifdef _WIN32
- template<> inline void Visit(CorpseMapType &) {}
- template<> inline void Visit(GameObjectMapType &) {}
- template<> inline void Visit(DynamicObjectMapType &) {}
- #endif
+ struct WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck
+ {
+ float _coneAngle;
+ WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster,
+ SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList);
+ bool operator()(WorldObject* target);
};
- #ifndef _WIN32
- template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType&) {}
- template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType&) {}
- template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType&) {}
- #endif
+ struct WorldObjectSpellTrajTargetCheck : public WorldObjectSpellAreaTargetCheck
+ {
+ WorldObjectSpellTrajTargetCheck(float range, Position const* position, Unit* caster, SpellInfo const* spellInfo);
+ bool operator()(WorldObject* target);
+ };
}
typedef void(Spell::*pEffect)(SpellEffIndex effIndex);
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index ad465767ab0..3365aad1cd9 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -20,6 +20,7 @@
#include "SpellMgr.h"
#include "Spell.h"
#include "DBCStores.h"
+#include "ConditionMgr.h"
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
{
@@ -80,7 +81,7 @@ SpellTargetObjectTypes SpellImplicitTargetInfo::GetObjectType() const
return _data[_target].ObjectType;
}
-SpellTargetSelectionCheckTypes SpellImplicitTargetInfo::GetSelectionCheckType() const
+SpellTargetCheckTypes SpellImplicitTargetInfo::GetCheckType() const
{
return _data[_target].SelectionCheckType;
}
@@ -158,23 +159,25 @@ uint32 SpellImplicitTargetInfo::GetExplicitTargetMask(bool& srcSet, bool& dstSet
case TARGET_OBJECT_TYPE_UNIT_AND_DEST:
case TARGET_OBJECT_TYPE_UNIT:
case TARGET_OBJECT_TYPE_DEST:
- switch (GetSelectionCheckType())
+ switch (GetCheckType())
{
- case TARGET_SELECT_CHECK_ENEMY:
+ case TARGET_CHECK_ENEMY:
targetMask = TARGET_FLAG_UNIT_ENEMY;
break;
- case TARGET_SELECT_CHECK_ALLY:
+ case TARGET_CHECK_ALLY:
targetMask = TARGET_FLAG_UNIT_ALLY;
break;
- case TARGET_SELECT_CHECK_PARTY:
+ case TARGET_CHECK_PARTY:
targetMask = TARGET_FLAG_UNIT_PARTY;
break;
- case TARGET_SELECT_CHECK_RAID:
+ case TARGET_CHECK_RAID:
targetMask = TARGET_FLAG_UNIT_RAID;
break;
- case TARGET_SELECT_CHECK_PASSENGER:
+ case TARGET_CHECK_PASSENGER:
targetMask = TARGET_FLAG_UNIT_PASSENGER;
break;
+ case TARGET_CHECK_RAID_CLASS:
+ // nobreak;
default:
targetMask = TARGET_FLAG_UNIT;
break;
@@ -344,117 +347,117 @@ SpellSelectTargetTypes SpellImplicitTargetInfo::Type[TOTAL_SPELL_TARGETS];
SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_TARGETS] =
{
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, //
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 1 TARGET_UNIT_CASTER
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 2 TARGET_UNIT_NEARBY_ENEMY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_PARTY, TARGET_DIR_NONE}, // 3 TARGET_UNIT_NEARBY_PARTY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_NONE}, // 4 TARGET_UNIT_NEARBY_ALLY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 5 TARGET_UNIT_PET
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 6 TARGET_UNIT_TARGET_ENEMY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_ENTRY, TARGET_DIR_NONE}, // 7 TARGET_UNIT_SRC_AREA_ENTRY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_ENTRY, TARGET_DIR_NONE}, // 8 TARGET_UNIT_DEST_AREA_ENTRY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 9 TARGET_DEST_HOME
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 10
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 11 TARGET_UNIT_SRC_AREA_UNK_11
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 12
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 13
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 14
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 15 TARGET_UNIT_SRC_AREA_ENEMY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 16 TARGET_UNIT_DEST_AREA_ENEMY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 17 TARGET_DEST_DB
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 18 TARGET_DEST_CASTER
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 19
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_PARTY, TARGET_DIR_NONE}, // 20 TARGET_UNIT_CASTER_AREA_PARTY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_NONE}, // 21 TARGET_UNIT_TARGET_ALLY
- {TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 22 TARGET_SRC_CASTER
- {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 23 TARGET_GAMEOBJECT_TARGET
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_FRONT}, // 24 TARGET_UNIT_CONE_ENEMY_24
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 25 TARGET_UNIT_TARGET_ANY
- {TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 26 TARGET_GAMEOBJECT_ITEM_TARGET
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 27 TARGET_UNIT_MASTER
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 28 TARGET_DEST_DYNOBJ_ENEMY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_NONE}, // 29 TARGET_DEST_DYNOBJ_ALLY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_NONE}, // 30 TARGET_UNIT_SRC_AREA_ALLY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_NONE}, // 31 TARGET_UNIT_DEST_AREA_ALLY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 32 TARGET_DEST_CASTER_SUMMON
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_PARTY, TARGET_DIR_NONE}, // 33 TARGET_UNIT_SRC_AREA_PARTY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_PARTY, TARGET_DIR_NONE}, // 34 TARGET_UNIT_DEST_AREA_PARTY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_PARTY, TARGET_DIR_NONE}, // 35 TARGET_UNIT_TARGET_PARTY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 36 TARGET_DEST_CASTER_UNK_36
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_LAST, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_PARTY, TARGET_DIR_NONE}, // 37 TARGET_UNIT_LASTTARGET_AREA_PARTY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_ENTRY, TARGET_DIR_NONE}, // 38 TARGET_UNIT_NEARBY_ENTRY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 39 TARGET_DEST_CASTER_FISHING
- {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_ENTRY, TARGET_DIR_NONE}, // 40 TARGET_GAMEOBJECT_NEARBY_ENTRY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_RIGHT}, // 41 TARGET_DEST_CASTER_FRONT_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK_RIGHT}, // 42 TARGET_DEST_CASTER_BACK_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK_LEFT}, // 43 TARGET_DEST_CASTER_BACK_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 44 TARGET_DEST_CASTER_FRONT_LEFT
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_NONE}, // 45 TARGET_UNIT_TARGET_CHAINHEAL_ALLY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_ENTRY, TARGET_DIR_NONE}, // 46 TARGET_DEST_NEARBY_ENTRY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 47 TARGET_DEST_CASTER_FRONT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK}, // 48 TARGET_DEST_CASTER_BACK
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RIGHT}, // 49 TARGET_DEST_CASTER_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_LEFT}, // 50 TARGET_DEST_CASTER_LEFT
- {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 51 TARGET_GAMEOBJECT_SRC_AREA
- {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 52 TARGET_GAMEOBJECT_DEST_AREA
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 53 TARGET_DEST_TARGET_ENEMY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_FRONT}, // 54 TARGET_UNIT_CONE_ENEMY_54
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 55 TARGET_DEST_CASTER_FRONT_LEAP
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_RAID, TARGET_DIR_NONE}, // 56 TARGET_UNIT_CASTER_AREA_RAID
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_RAID, TARGET_DIR_NONE}, // 57 TARGET_UNIT_TARGET_RAID
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_SELECT_CHECK_RAID, TARGET_DIR_NONE}, // 58 TARGET_UNIT_NEARBY_RAID
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CHECK_ALLY, TARGET_DIR_FRONT}, // 59 TARGET_UNIT_CONE_ALLY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CHECK_ENTRY, TARGET_DIR_FRONT}, // 60 TARGET_UNIT_CONE_ENTRY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_SELECT_CHECK_RAID, TARGET_DIR_NONE}, // 61 TARGET_UNIT_TARGET_AREA_RAID_CLASS
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 62 TARGET_UNK_62
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 63 TARGET_DEST_TARGET_ANY
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 64 TARGET_DEST_TARGET_FRONT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK}, // 65 TARGET_DEST_TARGET_BACK
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RIGHT}, // 66 TARGET_DEST_TARGET_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_LEFT}, // 67 TARGET_DEST_TARGET_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_RIGHT}, // 68 TARGET_DEST_TARGET_FRONT_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK_RIGHT}, // 69 TARGET_DEST_TARGET_BACK_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK_LEFT}, // 70 TARGET_DEST_TARGET_BACK_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 71 TARGET_DEST_TARGET_FRONT_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 72 TARGET_DEST_CASTER_RANDOM
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 73 TARGET_DEST_CASTER_RADIUS
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 74 TARGET_DEST_TARGET_RANDOM
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 75 TARGET_DEST_TARGET_RADIUS
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 76 TARGET_DEST_CHANNEL_TARGET
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 77 TARGET_UNIT_CHANNEL_TARGET
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 78 TARGET_DEST_DEST_FRONT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK}, // 79 TARGET_DEST_DEST_BACK
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RIGHT}, // 80 TARGET_DEST_DEST_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_LEFT}, // 81 TARGET_DEST_DEST_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_RIGHT}, // 82 TARGET_DEST_DEST_FRONT_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK_RIGHT}, // 83 TARGET_DEST_DEST_BACK_RIGHT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_BACK_LEFT}, // 84 TARGET_DEST_DEST_BACK_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 85 TARGET_DEST_DEST_FRONT_LEFT
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 86 TARGET_DEST_DEST_RANDOM
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 87 TARGET_DEST_DEST
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 88 TARGET_DEST_DYNOBJ_NONE
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 89 TARGET_DEST_TRAJ
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 90 TARGET_UNIT_TARGET_MINIPET
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 91 TARGET_DEST_DEST_RADIUS
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 92 TARGET_UNIT_SUMMONER
- {TARGET_OBJECT_TYPE_CORPSE, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_NONE}, // 93 TARGET_CORPSE_SRC_AREA_ENEMY
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 94 TARGET_UNIT_VEHICLE
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_PASSENGER, TARGET_DIR_NONE}, // 95 TARGET_UNIT_TARGET_PASSENGER
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 96 TARGET_UNIT_PASSENGER_0
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 97 TARGET_UNIT_PASSENGER_1
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 98 TARGET_UNIT_PASSENGER_2
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 99 TARGET_UNIT_PASSENGER_3
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 100 TARGET_UNIT_PASSENGER_4
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 101 TARGET_UNIT_PASSENGER_5
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 102 TARGET_UNIT_PASSENGER_6
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 103 TARGET_UNIT_PASSENGER_7
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CHECK_ENEMY, TARGET_DIR_FRONT}, // 104 TARGET_UNIT_CONE_ENEMY_104
- {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 105 TARGET_UNIT_UNK_105
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 106 TARGET_DEST_CHANNEL_CASTER
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 107 TARGET_UNK_DEST_AREA_UNK_107
- {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 108 TARGET_GAMEOBJECT_CONE
- {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 109
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_SELECT_CHECK_DEFAULT, TARGET_DIR_NONE}, // 110 TARGET_DEST_UNK_110
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, //
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 1 TARGET_UNIT_CASTER
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 2 TARGET_UNIT_NEARBY_ENEMY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 3 TARGET_UNIT_NEARBY_PARTY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 4 TARGET_UNIT_NEARBY_ALLY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 5 TARGET_UNIT_PET
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 6 TARGET_UNIT_TARGET_ENEMY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 7 TARGET_UNIT_SRC_AREA_ENTRY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 8 TARGET_UNIT_DEST_AREA_ENTRY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 9 TARGET_DEST_HOME
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 10
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 11 TARGET_UNIT_SRC_AREA_UNK_11
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 12
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 13
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 14
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 15 TARGET_UNIT_SRC_AREA_ENEMY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 16 TARGET_UNIT_DEST_AREA_ENEMY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 17 TARGET_DEST_DB
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 18 TARGET_DEST_CASTER
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 19
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 20 TARGET_UNIT_CASTER_AREA_PARTY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 21 TARGET_UNIT_TARGET_ALLY
+ {TARGET_OBJECT_TYPE_SRC, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 22 TARGET_SRC_CASTER
+ {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 23 TARGET_GAMEOBJECT_TARGET
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_ENEMY, TARGET_DIR_FRONT}, // 24 TARGET_UNIT_CONE_ENEMY_24
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 25 TARGET_UNIT_TARGET_ANY
+ {TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 26 TARGET_GAMEOBJECT_ITEM_TARGET
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 27 TARGET_UNIT_MASTER
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 28 TARGET_DEST_DYNOBJ_ENEMY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 29 TARGET_DEST_DYNOBJ_ALLY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 30 TARGET_UNIT_SRC_AREA_ALLY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 31 TARGET_UNIT_DEST_AREA_ALLY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 32 TARGET_DEST_CASTER_SUMMON
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 33 TARGET_UNIT_SRC_AREA_PARTY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 34 TARGET_UNIT_DEST_AREA_PARTY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 35 TARGET_UNIT_TARGET_PARTY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 36 TARGET_DEST_CASTER_UNK_36
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_LAST, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_PARTY, TARGET_DIR_NONE}, // 37 TARGET_UNIT_LASTTARGET_AREA_PARTY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 38 TARGET_UNIT_NEARBY_ENTRY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 39 TARGET_DEST_CASTER_FISHING
+ {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 40 TARGET_GAMEOBJECT_NEARBY_ENTRY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_RIGHT}, // 41 TARGET_DEST_CASTER_FRONT_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK_RIGHT}, // 42 TARGET_DEST_CASTER_BACK_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK_LEFT}, // 43 TARGET_DEST_CASTER_BACK_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 44 TARGET_DEST_CASTER_FRONT_LEFT
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ALLY, TARGET_DIR_NONE}, // 45 TARGET_UNIT_TARGET_CHAINHEAL_ALLY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ENTRY, TARGET_DIR_NONE}, // 46 TARGET_DEST_NEARBY_ENTRY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 47 TARGET_DEST_CASTER_FRONT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK}, // 48 TARGET_DEST_CASTER_BACK
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RIGHT}, // 49 TARGET_DEST_CASTER_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_LEFT}, // 50 TARGET_DEST_CASTER_LEFT
+ {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 51 TARGET_GAMEOBJECT_SRC_AREA
+ {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 52 TARGET_GAMEOBJECT_DEST_AREA
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 53 TARGET_DEST_TARGET_ENEMY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_ENEMY, TARGET_DIR_FRONT}, // 54 TARGET_UNIT_CONE_ENEMY_54
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 55 TARGET_DEST_CASTER_FRONT_LEAP
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_RAID, TARGET_DIR_NONE}, // 56 TARGET_UNIT_CASTER_AREA_RAID
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_RAID, TARGET_DIR_NONE}, // 57 TARGET_UNIT_TARGET_RAID
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_RAID, TARGET_DIR_NONE}, // 58 TARGET_UNIT_NEARBY_RAID
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_ALLY, TARGET_DIR_FRONT}, // 59 TARGET_UNIT_CONE_ALLY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_ENTRY, TARGET_DIR_FRONT}, // 60 TARGET_UNIT_CONE_ENTRY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_RAID_CLASS,TARGET_DIR_NONE}, // 61 TARGET_UNIT_TARGET_AREA_RAID_CLASS
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 62 TARGET_UNK_62
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 63 TARGET_DEST_TARGET_ANY
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 64 TARGET_DEST_TARGET_FRONT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK}, // 65 TARGET_DEST_TARGET_BACK
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RIGHT}, // 66 TARGET_DEST_TARGET_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_LEFT}, // 67 TARGET_DEST_TARGET_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_RIGHT}, // 68 TARGET_DEST_TARGET_FRONT_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK_RIGHT}, // 69 TARGET_DEST_TARGET_BACK_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK_LEFT}, // 70 TARGET_DEST_TARGET_BACK_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 71 TARGET_DEST_TARGET_FRONT_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 72 TARGET_DEST_CASTER_RANDOM
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 73 TARGET_DEST_CASTER_RADIUS
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 74 TARGET_DEST_TARGET_RANDOM
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 75 TARGET_DEST_TARGET_RADIUS
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 76 TARGET_DEST_CHANNEL_TARGET
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 77 TARGET_UNIT_CHANNEL_TARGET
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 78 TARGET_DEST_DEST_FRONT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK}, // 79 TARGET_DEST_DEST_BACK
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RIGHT}, // 80 TARGET_DEST_DEST_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_LEFT}, // 81 TARGET_DEST_DEST_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_RIGHT}, // 82 TARGET_DEST_DEST_FRONT_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK_RIGHT}, // 83 TARGET_DEST_DEST_BACK_RIGHT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_BACK_LEFT}, // 84 TARGET_DEST_DEST_BACK_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT_LEFT}, // 85 TARGET_DEST_DEST_FRONT_LEFT
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 86 TARGET_DEST_DEST_RANDOM
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 87 TARGET_DEST_DEST
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 88 TARGET_DEST_DYNOBJ_NONE
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 89 TARGET_DEST_TRAJ
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 90 TARGET_UNIT_TARGET_MINIPET
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 91 TARGET_DEST_DEST_RADIUS
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 92 TARGET_UNIT_SUMMONER
+ {TARGET_OBJECT_TYPE_CORPSE, TARGET_REFERENCE_TYPE_SRC, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 93 TARGET_CORPSE_SRC_AREA_ENEMY
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 94 TARGET_UNIT_VEHICLE
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_TARGET, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_PASSENGER, TARGET_DIR_NONE}, // 95 TARGET_UNIT_TARGET_PASSENGER
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 96 TARGET_UNIT_PASSENGER_0
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 97 TARGET_UNIT_PASSENGER_1
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 98 TARGET_UNIT_PASSENGER_2
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 99 TARGET_UNIT_PASSENGER_3
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 100 TARGET_UNIT_PASSENGER_4
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 101 TARGET_UNIT_PASSENGER_5
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 102 TARGET_UNIT_PASSENGER_6
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 103 TARGET_UNIT_PASSENGER_7
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_ENEMY, TARGET_DIR_FRONT}, // 104 TARGET_UNIT_CONE_ENEMY_104
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 105 TARGET_UNIT_UNK_105
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CHANNEL, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 106 TARGET_DEST_CHANNEL_CASTER
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 107 TARGET_UNK_DEST_AREA_UNK_107
+ {TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 108 TARGET_GAMEOBJECT_CONE
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 109
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 110 TARGET_DEST_UNK_110
};
SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex)
@@ -481,6 +484,7 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const*
ItemType = spellEntry->EffectItemType[effIndex];
TriggerSpell = spellEntry->EffectTriggerSpell[effIndex];
SpellClassMask = spellEntry->EffectSpellClassMask[effIndex];
+ ImplicitTargetConditions = NULL;
}
bool SpellEffectInfo::IsEffect() const
@@ -938,6 +942,11 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry)
ChainEntry = NULL;
}
+SpellInfo::~SpellInfo()
+{
+ _UnloadImplicitTargetConditionLists();
+}
+
bool SpellInfo::HasEffect(SpellEffects effect) const
{
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
@@ -1563,38 +1572,99 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
return SPELL_CAST_OK;
}
-SpellCastResult SpellInfo::CheckTarget(Unit const* caster, Unit const* target, bool implicit) const
+SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* target, bool implicit) const
{
if (AttributesEx & SPELL_ATTR1_CANT_TARGET_SELF && caster == target)
return SPELL_FAILED_BAD_TARGETS;
- if (AttributesEx & SPELL_ATTR1_CANT_TARGET_IN_COMBAT && target->isInCombat())
- return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
+ // check visibility - ignore stealth for implicit (area) targets
+ if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE) && !caster->canSeeOrDetect(target, implicit))
+ return SPELL_FAILED_BAD_TARGETS;
+
+ Unit const* unitTarget = target->ToUnit();
+
+ // creature/player specific target checks
+ if (unitTarget)
+ {
+ if (AttributesEx & SPELL_ATTR1_CANT_TARGET_IN_COMBAT && unitTarget->isInCombat())
+ return SPELL_FAILED_TARGET_AFFECTING_COMBAT;
+
+ // only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
+ if (((AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS) != 0) != unitTarget->HasAuraType(SPELL_AURA_GHOST))
+ {
+ if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS)
+ return SPELL_FAILED_TARGET_NOT_GHOST;
+ else
+ return SPELL_FAILED_BAD_TARGETS;
+ }
+
+ if (caster != unitTarget)
+ {
+ if (caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
+ if (AttributesEx2 & SPELL_ATTR2_CANT_TARGET_TAPPED)
+ if (Creature const* targetCreature = unitTarget->ToCreature())
+ if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
+ return SPELL_FAILED_CANT_CAST_ON_TAPPED;
+
+ if (AttributesCu & SPELL_ATTR0_CU_PICKPOCKET)
+ {
+ if (unitTarget->GetTypeId() == TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_TARGETS;
+ else if ((unitTarget->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) == 0)
+ return SPELL_FAILED_TARGET_NO_POCKETS;
+ }
+
+ // Not allow disarm unarmed player
+ if (Mechanic == MECHANIC_DISARM)
+ {
+ if (unitTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ Player const* player = unitTarget->ToPlayer();
+ if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
+ return SPELL_FAILED_TARGET_NO_WEAPONS;
+ }
+ else if (!unitTarget->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID))
+ return SPELL_FAILED_TARGET_NO_WEAPONS;
+ }
+ }
+ }
+ }
+ // corpse specific target checks
+ else if (Corpse const* corpseTarget = target->ToCorpse())
+ {
+ // cannot target bare bones
+ if (corpseTarget->GetType() == CORPSE_BONES)
+ return SPELL_FAILED_BAD_TARGETS;
+ // we have to use owner for some checks (aura preventing resurrection for example)
+ if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
+ unitTarget = owner;
+ // we're not interested in corpses without owner
+ else
+ return SPELL_FAILED_BAD_TARGETS;
+ }
+ // other types of objects - always valid
+ else return SPELL_CAST_OK;
- if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS && !target->ToPlayer())
+ // corpseOwner and unit specific target checks
+ if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_PLAYERS && !unitTarget->ToPlayer())
return SPELL_FAILED_TARGET_NOT_PLAYER;
- if (!IsAllowingDeadTarget() && !target->isAlive())
+ if (!IsAllowingDeadTarget() && !unitTarget->isAlive())
return SPELL_FAILED_TARGETS_DEAD;
- if (AttributesEx3 & SPELL_ATTR3_ONLY_TARGET_GHOSTS && !(!target->isAlive() && target->HasAuraType(SPELL_AURA_GHOST)))
- return SPELL_FAILED_TARGET_NOT_GHOST;
-
// check this flag only for implicit targets (chain and area), allow to explicitly target units for spells like Shield of Righteousness
- if (implicit && AttributesEx6 & SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED && !target->CanFreeMove())
+ if (implicit && AttributesEx6 & SPELL_ATTR6_CANT_TARGET_CROWD_CONTROLLED && !unitTarget->CanFreeMove())
return SPELL_FAILED_BAD_TARGETS;
- // check visibility - ignore stealth for implicit (area) targets
- if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE) && !caster->canSeeOrDetect(target, implicit))
- return SPELL_FAILED_BAD_TARGETS;
-
// checked in Unit::IsValidAttack/AssistTarget, shouldn't be checked for ENTRY targets
//if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_UNTARGETABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
// return SPELL_FAILED_BAD_TARGETS;
//if (!(AttributesEx6 & SPELL_ATTR6_CAN_TARGET_POSSESSED_FRIENDS)
- if (!CheckTargetCreatureType(target))
+ if (!CheckTargetCreatureType(unitTarget))
{
if (target->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_TARGET_IS_PLAYER;
@@ -1603,65 +1673,32 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, Unit const* target, b
}
// check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
- if (target != caster && (caster->IsControlledByPlayer() || !IsPositive()) && target->GetTypeId() == TYPEID_PLAYER)
+ if (unitTarget != caster && (caster->IsControlledByPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
{
- if (!target->ToPlayer()->IsVisible())
+ if (!unitTarget->ToPlayer()->IsVisible())
return SPELL_FAILED_BM_OR_INVISGOD;
- if (target->ToPlayer()->isGameMaster())
+ if (unitTarget->ToPlayer()->isGameMaster())
return SPELL_FAILED_BM_OR_INVISGOD;
}
// not allow casting on flying player
- if (target->HasUnitState(UNIT_STATE_IN_FLIGHT))
+ if (unitTarget->HasUnitState(UNIT_STATE_IN_FLIGHT))
return SPELL_FAILED_BAD_TARGETS;
- if (TargetAuraState && !target->HasAuraState(AuraStateType(TargetAuraState), this, caster))
+ if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, caster))
return SPELL_FAILED_TARGET_AURASTATE;
- if (TargetAuraStateNot && target->HasAuraState(AuraStateType(TargetAuraStateNot), this, caster))
+ if (TargetAuraStateNot && unitTarget->HasAuraState(AuraStateType(TargetAuraStateNot), this, caster))
return SPELL_FAILED_TARGET_AURASTATE;
- if (TargetAuraSpell && !target->HasAura(sSpellMgr->GetSpellIdForDifficulty(TargetAuraSpell, caster)))
+ if (TargetAuraSpell && !unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(TargetAuraSpell, caster)))
return SPELL_FAILED_TARGET_AURASTATE;
- if (ExcludeTargetAuraSpell && target->HasAura(sSpellMgr->GetSpellIdForDifficulty(ExcludeTargetAuraSpell, caster)))
+ if (ExcludeTargetAuraSpell && unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(ExcludeTargetAuraSpell, caster)))
return SPELL_FAILED_TARGET_AURASTATE;
- if (caster != target)
- {
- if (caster->GetTypeId() == TYPEID_PLAYER)
- {
- // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
- if (AttributesEx2 & SPELL_ATTR2_CANT_TARGET_TAPPED)
- if (Creature const* targetCreature = target->ToCreature())
- if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer()))
- return SPELL_FAILED_CANT_CAST_ON_TAPPED;
-
- if (AttributesCu & SPELL_ATTR0_CU_PICKPOCKET)
- {
- if (target->GetTypeId() == TYPEID_PLAYER)
- return SPELL_FAILED_BAD_TARGETS;
- else if ((target->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) == 0)
- return SPELL_FAILED_TARGET_NO_POCKETS;
- }
-
- // Not allow disarm unarmed player
- if (Mechanic == MECHANIC_DISARM)
- {
- if (target->GetTypeId() == TYPEID_PLAYER)
- {
- Player const* player = target->ToPlayer();
- if (!player->GetWeaponForAttack(BASE_ATTACK) || !player->IsUseEquipedWeapon(true))
- return SPELL_FAILED_TARGET_NO_WEAPONS;
- }
- else if (!target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID))
- return SPELL_FAILED_TARGET_NO_WEAPONS;
- }
- }
- }
-
- if (target->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
+ if (unitTarget->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
if (HasEffect(SPELL_EFFECT_SELF_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT_NEW))
return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
@@ -2035,13 +2072,19 @@ float SpellInfo::GetMinRange(bool positive) const
return RangeEntry->minRangeHostile;
}
-float SpellInfo::GetMaxRange(bool positive) const
+float SpellInfo::GetMaxRange(bool positive, Unit* caster, Spell* spell) const
{
if (!RangeEntry)
return 0.0f;
+ float range;
if (positive)
- return RangeEntry->maxRangeFriend;
- return RangeEntry->maxRangeHostile;
+ range = RangeEntry->maxRangeFriend;
+ else
+ range = RangeEntry->maxRangeHostile;
+ if (caster)
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(Id, SPELLMOD_RANGE, range, spell);
+ return range;
}
int32 SpellInfo::GetDuration() const
@@ -2552,3 +2595,20 @@ bool SpellInfo::_IsPositiveTarget(uint32 targetA, uint32 targetB)
return _IsPositiveTarget(targetB, 0);
return true;
}
+
+void SpellInfo::_UnloadImplicitTargetConditionLists()
+{
+ // find the same instances of ConditionList and delete them.
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ ConditionList* cur = Effects[i].ImplicitTargetConditions;
+ if (!cur)
+ continue;
+ for (uint8 j = i; j < MAX_SPELL_EFFECTS; ++j)
+ {
+ if (Effects[j].ImplicitTargetConditions == cur)
+ Effects[j].ImplicitTargetConditions = NULL;
+ }
+ delete cur;
+ }
+}
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 65be5981c64..69ea07f7563 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -36,6 +36,7 @@ struct SpellRangeEntry;
struct SpellRadiusEntry;
struct SpellEntry;
struct SpellCastTimesEntry;
+struct Condition;
enum SpellCastTargetFlags
{
@@ -105,15 +106,16 @@ enum SpellTargetObjectTypes
TARGET_OBJECT_TYPE_CORPSE_ALLY,
};
-enum SpellTargetSelectionCheckTypes
+enum SpellTargetCheckTypes
{
- TARGET_SELECT_CHECK_DEFAULT,
- TARGET_SELECT_CHECK_ENTRY,
- TARGET_SELECT_CHECK_ENEMY,
- TARGET_SELECT_CHECK_ALLY,
- TARGET_SELECT_CHECK_PARTY,
- TARGET_SELECT_CHECK_RAID,
- TARGET_SELECT_CHECK_PASSENGER,
+ TARGET_CHECK_DEFAULT,
+ TARGET_CHECK_ENTRY,
+ TARGET_CHECK_ENEMY,
+ TARGET_CHECK_ALLY,
+ TARGET_CHECK_PARTY,
+ TARGET_CHECK_RAID,
+ TARGET_CHECK_RAID_CLASS,
+ TARGET_CHECK_PASSENGER,
};
enum SpellTargetDirectionTypes
@@ -220,7 +222,7 @@ public:
SpellTargetSelectionCategories GetSelectionCategory() const;
SpellTargetReferenceTypes GetReferenceType() const;
SpellTargetObjectTypes GetObjectType() const;
- SpellTargetSelectionCheckTypes GetSelectionCheckType() const;
+ SpellTargetCheckTypes GetCheckType() const;
SpellTargetDirectionTypes GetDirectionType() const;
float CalcDirectionAngle() const;
@@ -240,7 +242,7 @@ private:
SpellTargetObjectTypes ObjectType; // type of object returned by target type
SpellTargetReferenceTypes ReferenceType; // defines which object is used as a reference when selecting target
SpellTargetSelectionCategories SelectionCategory;
- SpellTargetSelectionCheckTypes SelectionCheckType; // defines selection criteria
+ SpellTargetCheckTypes SelectionCheckType; // defines selection criteria
SpellTargetDirectionTypes DirectionType; // direction for cone and dest targets
};
static StaticData _data[TOTAL_SPELL_TARGETS];
@@ -271,6 +273,7 @@ public:
uint32 ItemType;
uint32 TriggerSpell;
flag96 SpellClassMask;
+ std::list<Condition*>* ImplicitTargetConditions;
SpellEffectInfo() {}
SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex);
@@ -388,6 +391,7 @@ public:
SpellChainNode const* ChainEntry;
SpellInfo(SpellEntry const* spellEntry);
+ ~SpellInfo();
bool HasEffect(SpellEffects effect) const;
bool HasAura(AuraType aura) const;
@@ -438,7 +442,7 @@ public:
SpellCastResult CheckShapeshift(uint32 form) const;
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = NULL) const;
- SpellCastResult CheckTarget(Unit const* caster, Unit const* target, bool implicit = true) const;
+ SpellCastResult CheckTarget(Unit const* caster, WorldObject const* target, bool implicit = true) const;
SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = NULL) const;
bool CheckTargetCreatureType(Unit const* target) const;
@@ -456,7 +460,7 @@ public:
SpellSpecificType GetSpellSpecific() const;
float GetMinRange(bool positive = false) const;
- float GetMaxRange(bool positive = false) const;
+ float GetMaxRange(bool positive = false, Unit* caster = NULL, Spell* spell = NULL) const;
int32 GetDuration() const;
int32 GetMaxDuration() const;
@@ -482,6 +486,9 @@ public:
bool _IsPositiveEffect(uint8 effIndex, bool deep) const;
bool _IsPositiveSpell() const;
static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
+
+ // unloading helpers
+ void _UnloadImplicitTargetConditionLists();
};
#endif // _SPELLINFO_H
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index ff4eaae42f2..c1b267d9fac 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2644,11 +2644,20 @@ void SpellMgr::UnloadSpellInfoStore()
for (uint32 i = 0; i < mSpellInfoMap.size(); ++i)
{
if (mSpellInfoMap[i])
- delete mSpellInfoMap[i];
+ delete mSpellInfoMap[i];
}
mSpellInfoMap.clear();
}
+void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists()
+{
+ for (uint32 i = 0; i < mSpellInfoMap.size(); ++i)
+ {
+ if (mSpellInfoMap[i])
+ mSpellInfoMap[i]->_UnloadImplicitTargetConditionLists();
+ }
+}
+
void SpellMgr::LoadSpellCustomAttr()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 14137b6a91b..9fffd474651 100755
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -360,17 +360,6 @@ struct SpellThreatEntry
typedef std::map<uint32, SpellThreatEntry> SpellThreatMap;
-// Spell script target related declarations (accessed using SpellMgr functions)
-enum SpellScriptTargetType
-{
- SPELL_TARGET_TYPE_GAMEOBJECT = 0,
- SPELL_TARGET_TYPE_CREATURE = 1,
- SPELL_TARGET_TYPE_DEAD = 2,
- SPELL_TARGET_TYPE_CONTROLLED = 3,
-};
-
-#define MAX_SPELL_TARGET_TYPE 4
-
// coordinates for spells (accessed using SpellMgr functions)
struct SpellTargetPosition
{
@@ -726,6 +715,7 @@ class SpellMgr
void LoadSpellAreas();
void LoadSpellInfoStore();
void UnloadSpellInfoStore();
+ void UnloadSpellInfoImplicitTargetConditionLists();
void LoadSpellCustomAttr();
void LoadDbcDataCorrections();
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 14dd32a71b6..03fea614c0d 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -473,11 +473,6 @@ void SpellScript::GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f
m_spell->GetSummonPosition(i, pos, radius, count);
}
-void SpellScript::SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry)
-{
- m_spell->SearchAreaTarget(TagUnitMap, radius, type, TargetType, entry);
-}
-
void SpellScript::PreventHitEffect(SpellEffIndex effIndex)
{
if (!IsInHitPhase() && !IsInEffectHook())
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 09b9eaebd62..1bf8d25adef 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -336,7 +336,6 @@ class SpellScript : public _SpellScript
void PreventHitHeal() { SetHitHeal(0); }
Spell* GetSpell() { return m_spell; }
void GetSummonPosition(uint32 i, Position &pos, float radius, uint32 count);
- void SearchAreaTarget(std::list<Unit*> &TagUnitMap, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry);
// returns current spell hit target aura
Aura* GetHitAura();
// prevents applying aura on current spell hit target
diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp
index 77332bd30a8..589b666c035 100644
--- a/src/server/game/Warden/WardenCheckMgr.cpp
+++ b/src/server/game/Warden/WardenCheckMgr.cpp
@@ -82,7 +82,7 @@ void WardenCheckMgr::LoadWardenChecks()
uint32 count = 0;
do
{
- Field* fields = result->Fetch();
+ fields = result->Fetch();
uint16 id = fields[0].GetUInt16();
uint8 checkType = fields[1].GetUInt8();
@@ -156,11 +156,11 @@ void WardenCheckMgr::LoadWardenChecks()
uint32 overrideCount = 0;
- if(overrideResult)
+ if (overrideResult)
{
do
{
- Field * fields = overrideResult->Fetch();
+ fields = overrideResult->Fetch();
uint16 checkId = fields[0].GetUInt16();
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 7372c92c4dd..df83fe8118f 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -502,11 +502,12 @@ public:
stmt->setUInt32(0, targetAccountId);
stmt->setUInt32(1, realmID);
}
+
LoginDatabase.Execute(stmt);
if (gm != 0)
{
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS);
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_ACCESS);
stmt->setUInt32(0, targetAccountId);
stmt->setUInt8(1, uint8(gm));
diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt
index af106ea0004..5af9dd2f23e 100644
--- a/src/server/scripts/EasternKingdoms/CMakeLists.txt
+++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt
@@ -33,7 +33,6 @@ set(scripts_STAT_SRCS
EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp
EasternKingdoms/isle_of_queldanas.cpp
EasternKingdoms/boss_kruul.cpp
- EasternKingdoms/searing_gorge.cpp
EasternKingdoms/ZulGurub/boss_hakkar.cpp
EasternKingdoms/ZulGurub/boss_mandokir.cpp
EasternKingdoms/ZulGurub/boss_marli.cpp
diff --git a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
index 76bdfe753c6..a75eda93d1d 100644
--- a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
+++ b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
@@ -156,7 +156,7 @@ class instance_deadmines : public InstanceMapScript
void MoveCreatureInside(Creature* creature)
{
- creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ creature->SetWalk(false);
creature->GetMotionMaster()->MovePoint(0, -102.7f, -655.9f, creature->GetPositionZ());
}
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
index 728446aa833..2a8676d7915 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
@@ -121,8 +121,8 @@ public:
MovePhase = 0;
me->SetSpeed(MOVE_RUN, 2.0f);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetLevitate(true);
+ me->SetWalk(false);
me->setActive(true);
if (instance)
@@ -240,7 +240,7 @@ public:
me->InterruptSpell(CURRENT_GENERIC_SPELL);
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
(*me).GetMotionMaster()->Clear(false);
(*me).GetMotionMaster()->MovePoint(0, IntroWay[2][0], IntroWay[2][1], IntroWay[2][2]);
@@ -263,7 +263,7 @@ public:
{
if (MovePhase >= 7)
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
}
@@ -277,7 +277,7 @@ public:
{
if (MovePhase >= 7)
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
}
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
index 056a2e95448..30fc8a2f9c4 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
@@ -527,7 +527,7 @@ public:
if (!Arcanagos)
return;
ArcanagosGUID = Arcanagos->GetGUID();
- Arcanagos->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Arcanagos->SetLevitate(true);
(*Arcanagos).GetMotionMaster()->MovePoint(0, ArcanagosPos[0], ArcanagosPos[1], ArcanagosPos[2]);
Arcanagos->SetOrientation(ArcanagosPos[3]);
me->SetOrientation(MedivPos[3]);
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
index 94c894f7e47..a46037f2662 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
@@ -497,7 +497,7 @@ public:
void Reset()
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
DoCast(me, SPELL_PHOENIX_BURN, true);
BurnTimer = 2000;
Death_Timer = 3000;
@@ -651,7 +651,7 @@ public:
ChangeTargetTimer = urand(6000, 12000);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->setFaction(14);
DoCast(me, SPELL_ARCANE_SPHERE_PASSIVE, true);
}
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
index fa97e4eefc0..62acd96d0a9 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
@@ -171,7 +171,7 @@ public:
float x, y, z; // coords that we move to, close to the crystal.
CrystalChosen->GetClosePoint(x, y, z, me->GetObjectSize(), CONTACT_DISTANCE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->GetMotionMaster()->MovePoint(1, x, y, z);
DrainingCrystal = true;
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index a2c8a890feb..342c0d18dc9 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -587,7 +587,7 @@ public:
return;
TargetGUID = who->GetGUID();
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->SetSpeed(MOVE_RUN, 0.4f);
me->GetMotionMaster()->MoveChase(who);
me->SetTarget(TargetGUID);
@@ -892,7 +892,7 @@ public:
{
if (Creature* miner = Unit::GetCreature(*me, minerGUID))
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
//Not 100% correct, but movement is smooth. Sometimes miner walks faster
//than normal, this speed is fast enough to keep up at those times.
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
index 4583a33a196..d8cbf0e8595 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
@@ -400,7 +400,7 @@ public:
switch (uiStage)
{
case 1:
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
if (GameObject* tree = me->FindNearestGameObject(GO_INCONSPICUOUS_TREE, 40.0f))
{
DoScriptText(SAY_TREE1, me);
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
index 81c4b1261ef..2df31971275 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
@@ -502,7 +502,7 @@ public:
switch (wpId)
{
case 0:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
SetHoldState(true);
break;
case 1:
@@ -537,7 +537,7 @@ public:
bIsBattle = true;
break;
case 2:
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
DoCast(me, SPELL_THE_LIGHT_OF_DAWN);
break;
case 3:
@@ -551,30 +551,30 @@ public:
{
if (temp->HasAura(SPELL_THE_LIGHT_OF_DAWN, 0))
temp->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN);
- temp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(true);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[19].x, LightofDawnLoc[19].y, LightofDawnLoc[19].z);
}
if (Creature* temp = Unit::GetCreature(*me, uiThassarianGUID))
{
if (temp->HasAura(SPELL_THE_LIGHT_OF_DAWN, 0))
temp->RemoveAurasDueToSpell(SPELL_THE_LIGHT_OF_DAWN);
- temp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(true);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[21].x, LightofDawnLoc[21].y, LightofDawnLoc[21].z);
}
if (Creature* temp = Unit::GetCreature(*me, uiKorfaxGUID))
{
- temp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(true);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[10].x, LightofDawnLoc[10].y, LightofDawnLoc[10].z);
}
if (Creature* temp = Unit::GetCreature(*me, uiMaxwellGUID))
{
- temp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(true);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[13].x, LightofDawnLoc[13].y, LightofDawnLoc[13].z);
}
if (Creature* temp = Unit::GetCreature(*me, uiEligorGUID))
{
- temp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(true);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[16].x, LightofDawnLoc[16].y, LightofDawnLoc[16].z);
}
JumpToNextStep(10000);
@@ -664,7 +664,7 @@ public:
if (uiSummon_counter < ENCOUNTER_GHOUL_NUMBER)
{
Unit* temp = me->SummonCreature(NPC_ACHERUS_GHOUL, (me->GetPositionX()-20)+rand()%40, (me->GetPositionY()-20)+rand()%40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->setFaction(2084);
uiGhoulGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
@@ -682,7 +682,7 @@ public:
if (uiSummon_counter < ENCOUNTER_ABOMINATION_NUMBER)
{
Unit* temp = me->SummonCreature(NPC_RAMPAGING_ABOMINATION, (me->GetPositionX()-20)+rand()%40, (me->GetPositionY()-20)+rand()%40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->setFaction(2084);
uiAbominationGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
@@ -700,7 +700,7 @@ public:
if (uiSummon_counter < ENCOUNTER_WARRIOR_NUMBER)
{
Unit* temp = me->SummonCreature(NPC_WARRIOR_OF_THE_FROZEN_WASTES, (me->GetPositionX()-20)+rand()%40, (me->GetPositionY()-20)+rand()%40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->setFaction(2084);
uiWarriorGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
@@ -718,7 +718,7 @@ public:
if (uiSummon_counter < ENCOUNTER_BEHEMOTH_NUMBER)
{
Unit* temp = me->SummonCreature(NPC_FLESH_BEHEMOTH, (me->GetPositionX()-20)+rand()%40, (me->GetPositionY()-20)+rand()%40, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->setFaction(2084);
uiBehemothGUID[uiSummon_counter] = temp->GetGUID();
++uiSummon_counter;
@@ -739,17 +739,17 @@ public:
SetHoldState(false);
if (Creature* temp = Unit::GetCreature(*me, uiKoltiraGUID))
{
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z);
}
if (Creature* temp = Unit::GetCreature(*me, uiOrbazGUID))
{
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z);
}
if (Creature* temp = Unit::GetCreature(*me, uiThassarianGUID))
{
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].x+rand()%30, LightofDawnLoc[0].y+rand()%30, LightofDawnLoc[0].z);
}
for (uint8 i = 0; i < ENCOUNTER_ABOMINATION_NUMBER; ++i)
@@ -824,7 +824,7 @@ public:
if (Unit* temp = me->SummonCreature(NPC_DARION_MOGRAINE, LightofDawnLoc[24].x, LightofDawnLoc[24].y, LightofDawnLoc[24].z, LightofDawnLoc[24].o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000))
{
DoScriptText(SAY_LIGHT_OF_DAWN35, temp);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
uiDarionGUID = temp->GetGUID();
}
JumpToNextStep(4000);
@@ -940,7 +940,7 @@ public:
DoCast(me, SPELL_MOGRAINE_CHARGE); // jumping charge
// doesn't make it looks well, so workarounds, Darion charges, looks better
me->SetSpeed(MOVE_RUN, 3.0f);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
SetHoldState(false);
JumpToNextStep(0);
break;
@@ -1013,7 +1013,7 @@ public:
Unit* temp;
temp = me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].x+rand()%10, LightofDawnLoc[0].y+rand()%10, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->SetSpeed(MOVE_RUN, 2.0f);
temp->setFaction(me->getFaction());
temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ);
@@ -1021,7 +1021,7 @@ public:
temp = me->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].x+rand()%10, LightofDawnLoc[0].y+rand()%10, LightofDawnLoc[0].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000);
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->SetSpeed(MOVE_RUN, 2.0f);
temp->setFaction(me->getFaction());
temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ);
@@ -1030,7 +1030,7 @@ public:
if (Creature* temp = Unit::GetCreature(*me, uiMaxwellGUID))
{
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->SetSpeed(MOVE_RUN, 2.0f);
temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ);
DoScriptText(SAY_LIGHT_OF_DAWN50, temp);
@@ -1038,7 +1038,7 @@ public:
if (Creature* temp = Unit::GetCreature(*me, uiKorfaxGUID))
{
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->SetSpeed(MOVE_RUN, 2.0f);
temp->HandleEmoteCommand(EMOTE_STATE_ATTACK_UNARMED);
temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ);
@@ -1046,7 +1046,7 @@ public:
if (Creature* temp = Unit::GetCreature(*me, uiEligorGUID))
{
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED);
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->SetSpeed(MOVE_RUN, 2.0f);
temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ);
}
@@ -1111,7 +1111,7 @@ public:
case 46: // Darion stand up, "not today"
me->SetSpeed(MOVE_RUN, 1.0f);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->SetStandState(UNIT_STAND_STATE_STAND);
DoScriptText(SAY_LIGHT_OF_DAWN53, me);
SetHoldState(false); // Darion throws sword
@@ -1171,7 +1171,7 @@ public:
temp->CastSpell(temp, SPELL_TIRION_CHARGE, false); // jumping charge
temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H);
temp->SetSpeed(MOVE_RUN, 3.0f); // workarounds, make Tirion still running
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[2].x, LightofDawnLoc[2].y, LightofDawnLoc[2].z);
if (Creature* lktemp = Unit::GetCreature(*me, uiLichKingGUID))
lktemp->Relocate(LightofDawnLoc[28].x, LightofDawnLoc[28].y, LightofDawnLoc[28].z); // workarounds, he should kick back by Tirion, but here we relocate him
@@ -1189,7 +1189,7 @@ public:
if (Creature* temp = Unit::GetCreature(*me, uiLichKingGUID))
{
temp->SetSpeed(MOVE_RUN, 1.0f);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[29].x, LightofDawnLoc[29].y, LightofDawnLoc[29].z); // 26
}
JumpToNextStep(4000);
@@ -1249,7 +1249,7 @@ public:
case 62:
if (Creature* temp = Unit::GetCreature(*me, uiTirionGUID))
{
- temp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(true);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[7].x, LightofDawnLoc[7].y, LightofDawnLoc[7].z);
}
JumpToNextStep(5500);
@@ -1438,7 +1438,7 @@ public:
me->DeleteThreatList();
me->CombatStop(true);
me->InterruptNonMeleeSpells(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
for (uint8 i = 0; i < ENCOUNTER_DEFENDER_NUMBER; ++i)
DespawnNPC(uiDefenderGUID[i]);
@@ -1460,7 +1460,7 @@ public:
temp->CombatStop(true);
temp->AttackStop();
temp->setFaction(me->getFaction());
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[9].x, LightofDawnLoc[9].y, LightofDawnLoc[9].z);
}
@@ -1471,7 +1471,7 @@ public:
temp->CombatStop(true);
temp->AttackStop();
temp->setFaction(me->getFaction());
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[12].x, LightofDawnLoc[12].y, LightofDawnLoc[12].z);
}
@@ -1482,7 +1482,7 @@ public:
temp->CombatStop(true);
temp->AttackStop();
temp->setFaction(me->getFaction());
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[15].x, LightofDawnLoc[15].y, LightofDawnLoc[15].z);
}
DespawnNPC(uiRayneGUID);
@@ -1494,7 +1494,7 @@ public:
temp->CombatStop(true);
temp->AttackStop();
temp->setFaction(me->getFaction());
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[18].x, LightofDawnLoc[18].y, LightofDawnLoc[18].z);
temp->CastSpell(temp, SPELL_THE_LIGHT_OF_DAWN, false);
}
@@ -1509,7 +1509,7 @@ public:
temp->CombatStop(true);
temp->AttackStop();
temp->setFaction(me->getFaction());
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[20].x, LightofDawnLoc[20].y, LightofDawnLoc[20].z);
temp->CastSpell(temp, SPELL_THE_LIGHT_OF_DAWN, false);
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp
index 9512d66b6eb..4f4622b6d4a 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/the_scarlet_enclave.cpp
@@ -74,7 +74,7 @@ public:
switch (phase)
{
case 0:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->HandleEmoteCommand(EMOTE_STATE_FLYGRABCLOSED);
FlyBackTimer = 500;
break;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
index 1404fd14e91..78d00e19cdf 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
@@ -216,7 +216,7 @@ public:
break;
case 3:
DoCast(me, SPELL_INTRO_FROST_BLAST);
- Madrigosa->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Madrigosa->SetLevitate(true);
me->AttackStop();
Madrigosa->AttackStop();
IntroFrostBoltTimer = 3000;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
index c65ce2c8f98..0d98efd703b 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
@@ -137,7 +137,7 @@ public:
uiFlightCount = 0;
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
@@ -391,7 +391,7 @@ public:
}
break;
case 10:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
EnterPhase(PHASE_GROUND);
AttackStart(SelectTarget(SELECT_TARGET_TOPAGGRO));
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
index d7c90732a80..1735c0c4f07 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kalecgos.cpp
@@ -159,7 +159,7 @@ public:
if (!bJustReset) //first reset at create
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetVisible(true);
me->SetStandState(UNIT_STAND_STATE_SLEEP);
}
@@ -231,7 +231,7 @@ public:
if (ResetTimer <= diff)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetVisible(true);
me->SetStandState(UNIT_STAND_STATE_SLEEP);
ResetTimer = 10000;
@@ -400,7 +400,7 @@ public:
TalkTimer = 10000;
break;
case 3:
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->GetMotionMaster()->MovePoint(0, FLY_X, FLY_Y, FLY_Z);
TalkTimer = 600000;
break;
@@ -418,7 +418,7 @@ public:
TalkTimer = 3000;
break;
case 2:
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->GetMotionMaster()->MovePoint(0, FLY_X, FLY_Y, FLY_Z);
TalkTimer = 15000;
break;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index 337eea13438..02a8de14fdf 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -660,17 +660,9 @@ public:
DoScriptText(RAND(SAY_KJ_REFLECTION1, SAY_KJ_REFLECTION2), me);
for (uint8 i = 0; i < 4; ++i)
{
- float x, y, z;
- Unit* target = NULL;
- for (uint8 i = 0; i < 6; ++i)
- {
- target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
- if (!target || !target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT, 0))
- break;
- }
-
- if (target)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true, -SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT))
{
+ float x, y, z;
target->GetPosition(x, y, z);
if (Creature* pSinisterReflection = me->SummonCreature(CREATURE_SINISTER_REFLECTION, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0))
{
@@ -1196,7 +1188,7 @@ public:
void Reset()
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
bPointReached = true;
uiTimer = urand(500, 1000);
uiCheckTimer = 1000;
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
index 21245209e45..dd2bef556c4 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
@@ -501,7 +501,7 @@ class mob_janalai_hatcher : public CreatureScript
void Reset()
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
side =(me->GetPositionY() < 1150);
waypoint = 0;
isHatching = false;
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
index 954f232f786..a6b74ddf06e 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
@@ -136,7 +136,7 @@ class boss_nalorakk : public CreatureScript
inMove = false;
waitTimer = 0;
me->SetSpeed(MOVE_RUN, 2);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
}else
{
(*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]);
diff --git a/src/server/scripts/EasternKingdoms/ghostlands.cpp b/src/server/scripts/EasternKingdoms/ghostlands.cpp
index 412613572f1..effc333d6f8 100644
--- a/src/server/scripts/EasternKingdoms/ghostlands.cpp
+++ b/src/server/scripts/EasternKingdoms/ghostlands.cpp
@@ -168,8 +168,10 @@ public:
me->AI()->AttackStart(Summ1);
break;
}
- case 19: me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); break;
- case 25: me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); break;
+ case 19: me->SetWalk(false);
+ break;
+ case 25: me->SetWalk(true);
+ break;
case 30:
if (player && player->GetTypeId() == TYPEID_PLAYER)
CAST_PLR(player)->GroupEventHappens(QUEST_ESCAPE_FROM_THE_CATACOMBS, me);
diff --git a/src/server/scripts/EasternKingdoms/hinterlands.cpp b/src/server/scripts/EasternKingdoms/hinterlands.cpp
index 7021deeae75..a66a01e00e5 100644
--- a/src/server/scripts/EasternKingdoms/hinterlands.cpp
+++ b/src/server/scripts/EasternKingdoms/hinterlands.cpp
@@ -273,7 +273,7 @@ public:
void JustSummoned(Creature* summoned)
{
- summoned->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ summoned->SetWalk(false);
summoned->GetMotionMaster()->MovePoint(0, m_afAmbushMoveTo[m_iSpawnId].m_fX, m_afAmbushMoveTo[m_iSpawnId].m_fY, m_afAmbushMoveTo[m_iSpawnId].m_fZ);
}
diff --git a/src/server/scripts/EasternKingdoms/redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/redridge_mountains.cpp
index d7b00af33e8..310ecbf7b66 100644
--- a/src/server/scripts/EasternKingdoms/redridge_mountains.cpp
+++ b/src/server/scripts/EasternKingdoms/redridge_mountains.cpp
@@ -84,7 +84,7 @@ public:
return;
if (uiI >= 65 && me->GetUnitMovementFlags() == MOVEMENTFLAG_WALKING)
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
switch (uiI)
{
@@ -94,7 +94,7 @@ public:
uiPhase = 1;
break;
case 65:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
break;
case 115:
player->AreaExploredOrEventHappens(QUEST_MISSING_IN_ACTION);
diff --git a/src/server/scripts/EasternKingdoms/searing_gorge.cpp b/src/server/scripts/EasternKingdoms/searing_gorge.cpp
deleted file mode 100644
index 74172dda743..00000000000
--- a/src/server/scripts/EasternKingdoms/searing_gorge.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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/>.
- */
-
-/* ScriptData
-SDName: Searing_Gorge
-SD%Complete: 80
-SDComment: Quest support: 3377, 3441 (More accurate info on Kalaran needed). Lothos Riftwaker teleport to Molten Core.
-SDCategory: Searing Gorge
-EndScriptData */
-
-/* ContentData
-npc_kalaran_windblade
-npc_lothos_riftwaker
-npc_zamael_lunthistle
-EndContentData */
-
-#include "ScriptPCH.h"
-
-/*######
-## npc_kalaran_windblade
-######*/
-
-#define GOSSIP_HELLO_KW "Tell me what drives this vengance?"
-#define GOSSIP_SELECT_KW1 "Continue please"
-#define GOSSIP_SELECT_KW2 "Let me confer with my colleagues"
-
-class npc_kalaran_windblade : public CreatureScript
-{
-public:
- npc_kalaran_windblade() : CreatureScript("npc_kalaran_windblade") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (uiAction)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_KW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(1954, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_KW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(1955, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(3441);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(3441) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_KW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
-## npc_lothos_riftwaker
-######*/
-
-#define GOSSIP_HELLO_LR "Teleport me to the Molten Core"
-
-class npc_lothos_riftwaker : public CreatureScript
-{
-public:
- npc_lothos_riftwaker() : CreatureScript("npc_lothos_riftwaker") { }
-
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- if (uiAction == GOSSIP_ACTION_INFO_DEF + 1)
- {
- player->CLOSE_GOSSIP_MENU();
- player->TeleportTo(409, 1096, -467, -104.6f, 3.64f);
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestRewardStatus(7487) || player->GetQuestRewardStatus(7848))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
-## npc_zamael_lunthistle
-######*/
-
-#define GOSSIP_HELLO_ZL "Tell me your story"
-#define GOSSIP_SELECT_ZL1 "Please continue..."
-#define GOSSIP_SELECT_ZL2 "Goodbye"
-
-class npc_zamael_lunthistle : public CreatureScript
-{
-public:
- npc_zamael_lunthistle() : CreatureScript("npc_zamael_lunthistle") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (uiAction)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_ZL1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(1921, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_ZL2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(1922, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(3377);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(3377) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_ZL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(1920, creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
-##
-######*/
-
-void AddSC_searing_gorge()
-{
- new npc_kalaran_windblade();
- new npc_lothos_riftwaker();
- new npc_zamael_lunthistle();
-}
diff --git a/src/server/scripts/EasternKingdoms/stormwind_city.cpp b/src/server/scripts/EasternKingdoms/stormwind_city.cpp
index a4eca1950f8..26267497aa1 100644
--- a/src/server/scripts/EasternKingdoms/stormwind_city.cpp
+++ b/src/server/scripts/EasternKingdoms/stormwind_city.cpp
@@ -391,7 +391,7 @@ public:
{
npc_marzon_silent_bladeAI(Creature* creature) : ScriptedAI(creature)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
}
void Reset()
diff --git a/src/server/scripts/EasternKingdoms/undercity.cpp b/src/server/scripts/EasternKingdoms/undercity.cpp
index fe9c40e6dbd..1724572f796 100644
--- a/src/server/scripts/EasternKingdoms/undercity.cpp
+++ b/src/server/scripts/EasternKingdoms/undercity.cpp
@@ -114,7 +114,7 @@ public:
summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false);
}
- summoned->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ summoned->SetLevitate(true);
targetGUID = summoned->GetGUID();
}
}
@@ -185,7 +185,7 @@ public:
{
if (EventMove_Timer <= diff)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(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());
EventMove = false;
diff --git a/src/server/scripts/EasternKingdoms/western_plaguelands.cpp b/src/server/scripts/EasternKingdoms/western_plaguelands.cpp
index a04a94f73b1..4ec8dbb647b 100644
--- a/src/server/scripts/EasternKingdoms/western_plaguelands.cpp
+++ b/src/server/scripts/EasternKingdoms/western_plaguelands.cpp
@@ -359,7 +359,7 @@ public:
break;
case 23:
Ughost = me->SummonCreature(NPC_GHOST_UTHER, 971.86f, -1825.42f, 81.99f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- Ughost->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Ughost->SetLevitate(true);
DoScriptText(SAY_WP_4, Ughost, me);
m_uiChatTimer = 4000;
break;
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
index 107c9e8f2f9..8a0ea30ca6a 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
@@ -492,7 +492,7 @@ void hyjalAI::SummonCreature(uint32 entry, float Base[4][3])
// Increment Enemy Count to be used in World States and instance script
++EnemyCount;
- creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ creature->SetWalk(false);
creature->setActive(true);
switch (entry)
{
@@ -1014,7 +1014,7 @@ void hyjalAI::WaypointReached(uint32 i)
if ((*itr) && (*itr)->isAlive() && (*itr) != me && (*itr)->GetEntry() != JAINA)
{
if (!(*itr)->IsWithinDist(me, 60))
- (*itr)->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ (*itr)->SetWalk(false);
float x, y, z;
(*itr)->SetDefaultMovementType(IDLE_MOTION_TYPE);
(*itr)->GetMotionMaster()->Initialize();
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index c94cb874bfa..ecc6b865b3d 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -459,7 +459,7 @@ public:
{
trigger->SetVisible(false);
trigger->setFaction(me->getFaction());
- trigger->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ trigger->SetLevitate(true);
trigger->CastSpell(me, SPELL_METEOR, true);
}
me->GetMotionMaster()->Clear();
@@ -1176,7 +1176,7 @@ public:
{
FrostBreathTimer = 5000;
MoveTimer = 0;
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
}
void WaypointReached(uint32 i)
@@ -1298,7 +1298,7 @@ public:
Zpos = 10.0f;
StrikeTimer = 2000+rand()%5000;
MoveTimer = 0;
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
}
void WaypointReached(uint32 i)
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
index 9518abd1635..e891f00ea36 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
@@ -591,11 +591,11 @@ public:
}
//After waypoint 0
case 1:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
if (Unit* pUther = me->SummonCreature(NPC_UTHER, 1794.357f, 1272.183f, 140.558f, 1.37f, TEMPSUMMON_DEAD_DESPAWN, 180000))
{
uiUtherGUID = pUther->GetGUID();
- pUther->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pUther->SetWalk(false);
pUther->GetMotionMaster()->MovePoint(0, 1897.018f, 1287.487f, 143.481f);
pUther->SetTarget(me->GetGUID());
me->SetTarget(uiUtherGUID);
@@ -680,7 +680,7 @@ public:
case 17:
if (Creature* pUther = Unit::GetCreature(*me, uiUtherGUID))
{
- pUther->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pUther->SetWalk(true);
pUther->GetMotionMaster()->MovePoint(0, 1794.357f, 1272.183f, 140.558f);
}
JumpToNextStep(1000);
@@ -689,7 +689,7 @@ public:
if (Creature* pJaina = Unit::GetCreature(*me, uiJainaGUID))
{
me->SetTarget(uiJainaGUID);
- pJaina->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pJaina->SetWalk(true);
pJaina->GetMotionMaster()->MovePoint(0, 1794.357f, 1272.183f, 140.558f);
}
JumpToNextStep(1000);
@@ -755,7 +755,7 @@ public:
if (Creature* pCityman = Unit::GetCreature(*me, uiCitymenGUID[0]))
{
pCityman->SetTarget(me->GetGUID());
- pCityman->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pCityman->SetWalk(true);
pCityman->GetMotionMaster()->MovePoint(0, 2088.625f, 1279.191f, 140.743f);
}
JumpToNextStep(2000);
@@ -929,7 +929,7 @@ public:
if (Unit* pBoss = me->SummonCreature(uiBossID, 2232.19f, 1331.933f, 126.662f, 3.15f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
{
uiBossGUID = pBoss->GetGUID();
- pBoss->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pBoss->SetWalk(true);
pBoss->GetMotionMaster()->MovePoint(0, 2194.110f, 1332.00f, 130.00f);
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
index aa57b3d9499..f5745f0f894 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
@@ -401,7 +401,7 @@ public:
SetRun();
break;
case 91:
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
SetRun(false);
break;
case 93:
diff --git a/src/server/scripts/Kalimdor/ZulFarrak/instance_zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/instance_zulfarrak.cpp
index 33a2ce73e21..da29c911c9f 100644
--- a/src/server/scripts/Kalimdor/ZulFarrak/instance_zulfarrak.cpp
+++ b/src/server/scripts/Kalimdor/ZulFarrak/instance_zulfarrak.cpp
@@ -301,7 +301,7 @@ public:
{
if (npc->isAlive())
{
- npc->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ npc->SetWalk(true);
npc->GetMotionMaster()->MovePoint(1, x, y, z);
npc->SetHomePosition(x, y, z, o);
}
diff --git a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp
index 61fe526407c..98de619c127 100644
--- a/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp
+++ b/src/server/scripts/Kalimdor/ZulFarrak/zulfarrak.cpp
@@ -204,7 +204,7 @@ void initBlyCrewMember(InstanceScript* instance, uint32 entry, float x, float y,
if (Creature* crew = instance->instance->GetCreature(instance->GetData64(entry)))
{
crew->SetReactState(REACT_AGGRESSIVE);
- crew->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ crew->SetWalk(true);
crew->SetHomePosition(x, y, z, 0);
crew->GetMotionMaster()->MovePoint(1, x, y, z);
crew->setFaction(FACTION_FREED);
diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp
index eede1aa069a..1a6ba36bbb1 100644
--- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp
@@ -640,7 +640,7 @@ public:
case 37:
DoScriptText(SAY_QUEST_COMPLETE, me, player);
me->SetSpeed(MOVE_RUN, 1.2f, true);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
if (player && player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H))
player->GroupEventHappens(QUEST_STINKYS_ESCAPE_H, me);
if (player && player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A))
diff --git a/src/server/scripts/Kalimdor/silithus.cpp b/src/server/scripts/Kalimdor/silithus.cpp
index fac56021c3a..71cc92da438 100644
--- a/src/server/scripts/Kalimdor/silithus.cpp
+++ b/src/server/scripts/Kalimdor/silithus.cpp
@@ -576,7 +576,7 @@ public:
break;
case 10:
Merithra->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- Merithra->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Merithra->SetLevitate(true);
Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 3);
break;
case 11:
@@ -603,7 +603,7 @@ public:
break;
case 18:
Arygos->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- Arygos->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Arygos->SetLevitate(true);
Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 6.61f, 42);
break;
case 19:
@@ -630,7 +630,7 @@ public:
break;
case 26:
Caelestrasz->HandleEmoteCommand(254);
- Caelestrasz->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Caelestrasz->SetLevitate(true);
Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 7.61f, 4);
break;
case 27:
@@ -769,7 +769,7 @@ public:
break;
case 63:
me->HandleEmoteCommand(254);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
break;
case 64:
me->GetMotionMaster()->MoveCharge(-8000, 1400, 150, 9);
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
index 0f4b046f7d5..636be5e29be 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
@@ -389,8 +389,10 @@ public:
bool OnGossipHello(Player* /*player*/, GameObject* pGO)
{
InstanceScript* instance = pGO->GetInstanceScript();
+ if (!instance)
+ return true;
- Creature* pPrinceTaldaram = Unit::GetCreature(*pGO, instance ? instance->GetData64(DATA_PRINCE_TALDARAM) : 0);
+ Creature* pPrinceTaldaram = Unit::GetCreature(*pGO, instance->GetData64(DATA_PRINCE_TALDARAM));
if (pPrinceTaldaram && pPrinceTaldaram->isAlive())
{
// maybe these are hacks :(
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
index 3e9d8144c19..547544fb754 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
@@ -480,7 +480,7 @@ public:
if (temp->isAlive() && !temp->getVictim())
{
if (temp->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- temp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ temp->SetWalk(false);
if (temp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
index 78810e27b05..03a04648793 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
@@ -106,7 +106,7 @@ class boss_saviana_ragefire : public CreatureScript
break;
case POINT_LAND:
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetReactState(REACT_AGGRESSIVE);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
@@ -121,7 +121,7 @@ class boss_saviana_ragefire : public CreatureScript
{
_JustReachedHome();
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
}
void KilledUnit(Unit* victim)
@@ -147,7 +147,7 @@ class boss_saviana_ragefire : public CreatureScript
case EVENT_FLIGHT:
{
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetReactState(REACT_PASSIVE);
me->GetMotionMaster()->MovePoint(POINT_FLIGHT, SavianaRagefireFlyPos);
events.ScheduleEvent(EVENT_FLIGHT, 50000);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
index cfbbb79c5f6..19ae66b6a60 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.cpp
@@ -71,7 +71,7 @@ class npc_xerestrasza : public CreatureScript
_isIntro = false;
Talk(SAY_XERESTRASZA_EVENT);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(0, xerestraszaMovePos);
_events.ScheduleEvent(EVENT_XERESTRASZA_EVENT_1, 16000);
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 d5695a0f39d..19ed96e8885 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
@@ -62,7 +62,7 @@ class OrientationCheck : public std::unary_function<Unit*, bool>
explicit OrientationCheck(Unit* _caster) : caster(_caster) { }
bool operator() (Unit* unit)
{
- return !unit->isInFront(caster, 40.0f, 2.5f);
+ return !unit->isInFront(caster, 2.5f) || !unit->IsWithinDist(caster, 40.0f);
}
private:
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
index 9fcfcfa47e5..7c82454ba87 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
@@ -208,7 +208,7 @@ public:
switch (i)
{
case 2:
- if ((instance && uiWaypointPath == 3) || uiWaypointPath == 2)
+ if (instance && (uiWaypointPath == 3 || uiWaypointPath == 2))
instance->SetData(DATA_MOVEMENT_DONE, instance->GetData(DATA_MOVEMENT_DONE)+1);
break;
case 3:
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
index 242b2f2f0ea..0e604566276 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
@@ -176,7 +176,7 @@ struct boss_twin_baseAI : public ScriptedAI
me->SetReactState(REACT_PASSIVE);
me->ModifyAuraState(m_uiAuraState, true);
/* Uncomment this once that they are flying above the ground
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetFlying(true); */
m_bIsBerserk = false;
@@ -576,7 +576,7 @@ struct mob_unleashed_ballAI : public ScriptedAI
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetFlying(true);
SetCombatMovement(false);
MoveToNextPoint();
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index 3831e4824ad..28110d883c6 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -255,7 +255,7 @@ class boss_lich_king_toc : public CreatureScript
summoned->SetDisplayId(11686);
}
if (m_instance) m_instance->SetData(TYPE_LICH_KING, IN_PROGRESS);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
}
void MovementInform(uint32 uiType, uint32 uiId)
@@ -378,7 +378,7 @@ class npc_fizzlebang_toc : public CreatureScript
void Reset()
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
m_uiPortalGUID = 0;
me->GetMotionMaster()->MovePoint(1, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY()-60, ToCCommonLoc[10].GetPositionZ());
}
@@ -390,7 +390,7 @@ class npc_fizzlebang_toc : public CreatureScript
switch (uiId)
{
case 1:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
if (m_instance)
{
m_instance->DoUseDoorOrButton(m_instance->GetData64(GO_MAIN_GATE_DOOR));
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
index 0f9495d4928..64609efd7ff 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_forgemaster_garfrost.cpp
@@ -27,7 +27,7 @@ enum Yells
SAY_PHASE2 = -1658005,
SAY_PHASE3 = -1658006,
- SAY_TYRANNUS_DEATH = -1659007,
+ SAY_TYRANNUS_DEATH = -1658007,
};
enum Spells
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index 70b07c61e79..8ee0ef02cbd 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -1058,7 +1058,7 @@ class npc_blood_queen_lana_thel : public CreatureScript
void Reset()
{
_events.Reset();
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
if (_instance->GetBossState(DATA_BLOOD_PRINCE_COUNCIL) == DONE)
{
me->SetVisible(false);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index 79a577f6591..5eeb941d9aa 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -216,7 +216,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
_killMinchar = true;
else
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(true);
me->SendMovementFlagUpdate();
@@ -230,7 +230,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
if (_killMinchar)
{
_killMinchar = false;
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(true);
me->GetMotionMaster()->MovePoint(POINT_MINCHAR, mincharPos);
@@ -244,7 +244,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
void JustReachedHome()
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(false);
me->SetReactState(REACT_AGGRESSIVE);
@@ -295,7 +295,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
events.ScheduleEvent(EVENT_AIR_FLY_DOWN, 10000);
break;
case POINT_GROUND:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(false);
me->SendMovementFlagUpdate();
@@ -424,7 +424,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos);
break;
case EVENT_AIR_START_FLYING:
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x01);
me->SetFlying(true);
me->SendMovementFlagUpdate();
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 3c795187f43..5177f65f670 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -605,7 +605,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
_events.ScheduleEvent(EVENT_OUTRO_HORDE_3, 18000); // say
_events.ScheduleEvent(EVENT_OUTRO_HORDE_4, 24000); // cast
_events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 30000); // move
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SendMovementFlagUpdate();
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
@@ -629,7 +629,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
{
if (spell->Id == SPELL_GRIP_OF_AGONY)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[0]);
}
}
@@ -641,7 +641,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
switch (id)
{
case POINT_FIRST_STEP:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
Talk(SAY_INTRO_HORDE_3);
_events.ScheduleEvent(EVENT_INTRO_HORDE_5, 15500, 0, PHASE_INTRO_H);
_events.ScheduleEvent(EVENT_INTRO_HORDE_6, 29500, 0, PHASE_INTRO_H);
@@ -687,7 +687,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
switch (eventId)
{
case EVENT_INTRO_HORDE_3:
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_FIRST_STEP, firstStepPos.GetPositionX(), firstStepPos.GetPositionY(), firstStepPos.GetPositionZ());
break;
case EVENT_INTRO_HORDE_5:
@@ -718,7 +718,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
{
float x, y, z;
deathbringer->GetClosePoint(x, y, z, deathbringer->GetObjectSize());
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_CORPSE, x, y, z);
}
break;
@@ -812,7 +812,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
{
me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
Talk(SAY_OUTRO_ALLIANCE_1);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SendMovementFlagUpdate();
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
@@ -832,7 +832,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
{
if (spell->Id == SPELL_GRIP_OF_AGONY)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[0]);
}
}
@@ -841,7 +841,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
{
if (type == POINT_MOTION_TYPE && id == POINT_FIRST_STEP)
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
Talk(SAY_INTRO_ALLIANCE_4);
_events.ScheduleEvent(EVENT_INTRO_ALLIANCE_5, 5000, 0, PHASE_INTRO_A);
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_DEATHBRINGER_SAURFANG)))
@@ -865,7 +865,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
switch (eventId)
{
case EVENT_INTRO_ALLIANCE_4:
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_FIRST_STEP, firstStepPos.GetPositionX(), firstStepPos.GetPositionY(), firstStepPos.GetPositionZ());
break;
case EVENT_INTRO_ALLIANCE_5:
@@ -934,7 +934,7 @@ class npc_saurfang_event : public CreatureScript
{
if (spell->Id == SPELL_GRIP_OF_AGONY)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[_index]);
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 8623fcfde81..44bc40d08bd 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -191,7 +191,7 @@ class boss_professor_putricide : public CreatureScript
SetPhase(PHASE_COMBAT_1);
_experimentState = EXPERIMENT_STATE_OOZE;
me->SetReactState(REACT_DEFENSIVE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
@@ -230,7 +230,7 @@ class boss_professor_putricide : public CreatureScript
void JustReachedHome()
{
_JustReachedHome();
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
if (events.GetPhaseMask() & PHASE_MASK_COMBAT)
instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 1d9c3c14897..a544f2f4710 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -199,7 +199,7 @@ class boss_sindragosa : public CreatureScript
if (instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) != 255)
{
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
}
}
@@ -229,7 +229,7 @@ class boss_sindragosa : public CreatureScript
BossAI::JustReachedHome();
instance->SetBossState(DATA_SINDRAGOSA, FAIL);
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
}
void KilledUnit(Unit* victim)
@@ -276,7 +276,7 @@ class boss_sindragosa : public CreatureScript
case POINT_FROSTWYRM_LAND:
me->setActive(false);
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetHomePosition(SindragosaLandPos);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetSpeed(MOVE_FLIGHT, 2.0f);
@@ -293,7 +293,7 @@ class boss_sindragosa : public CreatureScript
break;
case POINT_LAND:
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetReactState(REACT_DEFENSIVE);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
@@ -426,7 +426,7 @@ class boss_sindragosa : public CreatureScript
_isInAirPhase = true;
Talk(SAY_AIR_PHASE);
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetReactState(REACT_PASSIVE);
Position pos;
pos.Relocate(me);
@@ -618,7 +618,7 @@ class npc_spinestalker : public CreatureScript
if (_instance->GetData(DATA_SPINESTALKER) != 255)
{
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
}
}
@@ -661,7 +661,7 @@ class npc_spinestalker : public CreatureScript
me->setActive(false);
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetHomePosition(SpinestalkerLandPos);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
@@ -743,7 +743,7 @@ class npc_rimefang : public CreatureScript
if (_instance->GetData(DATA_RIMEFANG) != 255)
{
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
}
}
@@ -786,7 +786,7 @@ class npc_rimefang : public CreatureScript
me->setActive(false);
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetHomePosition(RimefangLandPos);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index fbed870eb19..7ca371d1c82 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -499,7 +499,7 @@ class boss_the_lich_king : public CreatureScript
{
_JustDied();
DoCastAOE(SPELL_PLAY_MOVIE, false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03);
me->GetMotionMaster()->MoveFall();
}
@@ -660,7 +660,7 @@ class boss_the_lich_king : public CreatureScript
summons.DespawnAll();
SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE);
DoCastAOE(SPELL_FURY_OF_FROSTMOURNE);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO);
events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO);
events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 17600, 0, PHASE_OUTRO);
@@ -864,7 +864,7 @@ class boss_the_lich_king : public CreatureScript
case EVENT_INTRO_MOVE_1:
me->SetSheath(SHEATH_STATE_MELEE);
me->RemoveAurasDueToSpell(SPELL_EMOTE_SIT_NO_SHEATH);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_1, LichKingIntro[0]);
break;
case EVENT_INTRO_MOVE_2:
@@ -894,7 +894,7 @@ class boss_the_lich_king : public CreatureScript
events.ScheduleEvent(EVENT_FINISH_INTRO, 1000, 0, PHASE_INTRO);
break;
case EVENT_FINISH_INTRO:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetReactState(REACT_AGGRESSIVE);
events.SetPhase(PHASE_ONE);
@@ -1072,7 +1072,7 @@ class boss_the_lich_king : public CreatureScript
DoCastAOE(SPELL_SOUL_BARRAGE);
sCreatureTextMgr->SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false);
// set flight
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x03);
me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying);
break;
@@ -1226,7 +1226,7 @@ class npc_tirion_fordring_tft : public CreatureScript
{
_events.SetPhase(PHASE_INTRO);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_TIRION_INTRO, TirionIntro);
}
}
@@ -1264,7 +1264,7 @@ class npc_tirion_fordring_tft : public CreatureScript
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
break;
case EVENT_INTRO_CHARGE:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->GetMotionMaster()->MovePoint(POINT_TIRION_CHARGE, TirionCharge);
break;
case EVENT_OUTRO_TALK_1:
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
index 47151ef6d80..05206102762 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
@@ -194,7 +194,7 @@ public:
{
movementStarted = true;
me->SetReactState(REACT_PASSIVE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true);
switch (id)
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
index 16b1e7ac996..63f7c653c5a 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
@@ -296,7 +296,7 @@ public:
{
case EVENT_LIFTOFF:
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_ICEBOLT, 1500);
iceboltCount = RAID_MODE(2, 3);
@@ -340,7 +340,7 @@ public:
return;
case EVENT_LAND:
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_GROUND, 1500);
return;
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 437d9980af3..64060464d7c 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -271,7 +271,7 @@ public:
{
me->SetHomePosition(_homePosition);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
BossAI::EnterEvadeMode();
@@ -354,7 +354,7 @@ public:
{
_EnterCombat();
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetFlying(false);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -412,7 +412,7 @@ public:
void PrepareForVortex()
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetFlying(true);
me->GetMotionMaster()->MovementExpired();
@@ -461,7 +461,7 @@ public:
{
SetPhase(PHASE_TWO, true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->SetFlying(true);
me->GetMotionMaster()->MoveIdle();
@@ -704,7 +704,7 @@ class spell_malygos_vortex_visual : public SpellScriptLoader
// Anyway even with this issue, the boss does not enter in evade mode - this prevents iterate an empty list in the next vortex execution.
malygos->SetInCombatWithZone();
- malygos->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ malygos->SetLevitate(false);
malygos->SetFlying(false);
malygos->GetMotionMaster()->MoveChase(caster->getVictim());
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
index 8852338c362..187dbed6901 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
@@ -169,7 +169,8 @@ class npc_azure_ring_captain : public CreatureScript
{
targetGUID = 0;
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING | MOVEMENTFLAG_FLYING);
+ me->SetWalk(true);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
me->SetReactState(REACT_AGGRESSIVE);
}
@@ -214,7 +215,7 @@ class npc_azure_ring_captain : public CreatureScript
if (Unit* victim = varos->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0))
{
me->SetReactState(REACT_PASSIVE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->GetMotionMaster()->MovePoint(ACTION_CALL_DRAGON_EVENT, victim->GetPositionX(), victim->GetPositionY(), victim->GetPositionZ() + 20.0f);
targetGUID = victim->GetGUID();
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
index eadc524348b..1671953aba1 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
@@ -575,7 +575,7 @@ class boss_stormcaller_brundir : public CreatureScript
_Reset();
phase = 0;
me->RemoveAllAuras();
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, false); // Should be interruptable unless overridden by spell (Overload)
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, false); // Reset immumity, Brundir should be stunnable by default
RespawnEncounter(instance, me);
@@ -681,7 +681,7 @@ class boss_stormcaller_brundir : public CreatureScript
DoCast(RAID_MODE(SPELL_LIGHTNING_TENDRILS_10M, SPELL_LIGHTNING_TENDRILS_25M));
DoCast(SPELL_LIGHTNING_TENDRILS_VISUAL);
me->AttackStop();
- //me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ //me->SetLevitate(true);
me->GetMotionMaster()->Initialize();
me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), FINAL_FLIGHT_Z);
events.DelayEvents(35000);
@@ -708,7 +708,7 @@ class boss_stormcaller_brundir : public CreatureScript
events.ScheduleEvent(EVENT_GROUND, 2500);
break;
case EVENT_GROUND:
- //me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ //me->SetLevitate(false);
me->RemoveAurasDueToSpell(RAID_MODE(SPELL_LIGHTNING_TENDRILS_10M, SPELL_LIGHTNING_TENDRILS_25M));
me->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS_VISUAL);
DoStartMovement(me->getVictim());
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 da46d016e91..c4f973726bc 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -1736,25 +1736,29 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader
if (Vehicle* vehicle = GetCaster()->GetVehicleKit())
if (Unit* passenger = vehicle->GetPassenger(damage - 1))
{
- std::list<Unit*> unitList;
// use 99 because it is 3d search
- SearchAreaTarget(unitList, 99, PUSH_DST_CENTER, SPELL_TARGETS_ENTRY, NPC_SEAT);
+ std::list<WorldObject*> targetList;
+ Trinity::WorldObjectSpellAreaTargetCheck check(99, GetTargetDest(), GetCaster(), GetCaster(), GetSpellInfo(), TARGET_CHECK_DEFAULT, NULL);
+ Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(GetCaster(), targetList, check);
+ GetCaster()->GetMap()->VisitAll(GetCaster()->m_positionX, GetCaster()->m_positionY, 99, searcher);
float minDist = 99 * 99;
Unit* target = NULL;
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
+ for (std::list<WorldObject*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
{
- if (Vehicle* seat = (*itr)->GetVehicleKit())
- if (!seat->GetPassenger(0))
- if (Unit* device = seat->GetPassenger(2))
- if (!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
- {
- float dist = (*itr)->GetExactDistSq(targets.GetDst());
- if (dist < minDist)
- {
- minDist = dist;
- target = (*itr);
- }
- }
+ if (Unit* unit = (*itr)->ToUnit())
+ if (unit->GetEntry() == NPC_SEAT)
+ if (Vehicle* seat = unit->GetVehicleKit())
+ if (!seat->GetPassenger(0))
+ if (Unit* device = seat->GetPassenger(2))
+ if (!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
+ {
+ float dist = unit->GetExactDistSq(targets.GetDst());
+ if (dist < minDist)
+ {
+ minDist = dist;
+ target = unit;
+ }
+ }
}
if (target && target->IsWithinDist2d(targets.GetDst(), GetSpellInfo()->Effects[effIndex].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
passenger->EnterVehicle(target, 0);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
index a156e6ef08b..d5034e4827e 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
@@ -485,6 +485,8 @@ class spell_ulduar_squeezed_lifeless : public SpellScriptLoader
if (!GetHitPlayer() || !GetHitPlayer()->GetVehicle())
return;
+ //! Proper exit position does not work currently,
+ //! See documentation in void Unit::ExitVehicle(Position const* exitPosition)
Position pos;
pos.m_positionX = 1756.25f + irand(-3, 3);
pos.m_positionY = -8.3f + irand(-3, 3);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
index 45f9a1fa012..7ad859e3e8d 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
@@ -647,7 +647,7 @@ class npc_expedition_commander : public CreatureScript
for (uint8 n = 0; n < RAID_MODE(2, 4); n++)
{
Engineer[n] = me->SummonCreature(NPC_ENGINEER, PosEngSpawn, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
- Engineer[n]->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ Engineer[n]->SetWalk(false);
Engineer[n]->SetSpeed(MOVE_RUN, 0.5f);
Engineer[n]->SetHomePosition(PosEngRepair[n]);
Engineer[n]->GetMotionMaster()->MoveTargetedHome();
@@ -660,7 +660,7 @@ class npc_expedition_commander : public CreatureScript
for (uint8 n = 0; n < 4; n++)
{
Defender[n] = me->SummonCreature(NPC_DEFENDER, PosDefSpawn[n], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000);
- Defender[n]->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ Defender[n]->SetWalk(false);
Defender[n]->SetHomePosition(PosDefCombat[n]);
Defender[n]->GetMotionMaster()->MoveTargetedHome();
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
index d5cd79b25f1..dd3557071cd 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
@@ -240,7 +240,7 @@ public:
m_instance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, IN_PROGRESS);
m_instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
me->GetMotionMaster()->MoveJump(Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 5.0f, 10.0f);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
m_uiMountTimer = 1000;
Summons.DespawnEntry(CREATURE_GRAUF);
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
index 915ead98bb7..a4289b2eb06 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
@@ -161,7 +161,7 @@ public:
if (Phase > INTRO)
{
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
}
if (Phase > NORMAL)
@@ -183,7 +183,7 @@ public:
if (Phase > INTRO)
{
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetOrientation(1.58f);
me->SendMovementFlagUpdate();
}
@@ -326,7 +326,7 @@ public:
case 2:
arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
pos.Relocate(me);
pos.m_positionZ += 8.0f;
me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f);
@@ -340,7 +340,7 @@ public:
if ((*itr)->isAlive())
{
(*itr)->SetStandState(UNIT_STAND_STATE_STAND);
- (*itr)->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ (*itr)->SetWalk(false);
(*itr)->GetMotionMaster()->MovePoint(1, spectatorWP[0][0], spectatorWP[0][1], spectatorWP[0][2]);
}
}
@@ -383,7 +383,7 @@ public:
break;
case 8:
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SendMovementFlagUpdate();
pos.Relocate(me);
pos.m_positionX = me->GetHomePosition().GetPositionX();
@@ -417,7 +417,7 @@ public:
if (me->IsWithinMeleeRange(me->getVictim()) && me->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING))
{
me->SetFlying(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SendMovementFlagUpdate();
}
@@ -451,7 +451,7 @@ public:
SetCombatMovement(false);
me->SetFlying(true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
Phase = SACRIFICING;
sacrePhase = 0;
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
index 29d6278124f..35bbb98fd77 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_ymiron.cpp
@@ -218,7 +218,7 @@ public:
m_uiActivedCreatureGUID = temp->GetGUID();
temp->CastSpell(me, SPELL_CHANNEL_SPIRIT_TO_YMIRON, true);
temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- temp->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ temp->SetLevitate(true);
switch (m_uiActiveOrder[m_uiActivedNumber])
{
case 0: m_bIsActiveWithBJORN = true; break;
diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
index 8b77cb250da..d9e8798b179 100644
--- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
+++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
@@ -363,7 +363,7 @@ public:
{
if (Creature* pGuard = *itr)
{
- pGuard->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pGuard->SetWalk(false);
pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
}
}
diff --git a/src/server/scripts/Northrend/borean_tundra.cpp b/src/server/scripts/Northrend/borean_tundra.cpp
index 11fb0933b9b..a8fcd6139da 100644
--- a/src/server/scripts/Northrend/borean_tundra.cpp
+++ b/src/server/scripts/Northrend/borean_tundra.cpp
@@ -1030,16 +1030,16 @@ public:
uiArthas = pArthas->GetGUID();
pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pArthas->SetReactState(REACT_PASSIVE);
- pArthas->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pArthas->SetWalk(true);
pArthas->GetMotionMaster()->MovePoint(0, 3737.374756f, 3564.841309f, 477.433014f);
}
if (Creature* pTalbot = me->SummonCreature(NPC_COUNSELOR_TALBOT, 3747.23f, 3614.936f, 473.321f, 4.462012f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000))
{
uiTalbot = pTalbot->GetGUID();
- pTalbot->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pTalbot->SetWalk(true);
pTalbot->GetMotionMaster()->MovePoint(0, 3738.000977f, 3568.882080f, 477.433014f);
}
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
break;
case 4:
@@ -1118,13 +1118,13 @@ public:
if (Creature* pArlos = me->SummonCreature(NPC_GENERAL_ARLOS, 3745.527100f, 3615.655029f, 473.321533f, 4.447805f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000))
{
uiArlos = pArlos->GetGUID();
- pArlos->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pArlos->SetWalk(true);
pArlos->GetMotionMaster()->MovePoint(0, 3735.570068f, 3572.419922f, 477.441010f);
}
if (Creature* pLeryssa = me->SummonCreature(NPC_LERYSSA, 3749.654541f, 3614.959717f, 473.323486f, 4.524959f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000))
{
uiLeryssa = pLeryssa->GetGUID();
- pLeryssa->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pLeryssa->SetWalk(false);
pLeryssa->SetReactState(REACT_PASSIVE);
pLeryssa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
pLeryssa->GetMotionMaster()->MovePoint(0, 3741.969971f, 3571.439941f, 477.441010f);
@@ -1446,7 +1446,7 @@ public:
pArlos->Kill(pArlos, false);
pLeryssa->RemoveAura(SPELL_STUN);
pLeryssa->ClearUnitState(UNIT_STATE_STUNNED);
- pLeryssa->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ pLeryssa->SetWalk(false);
pLeryssa->GetMotionMaster()->MovePoint(0, 3722.114502f, 3564.201660f, 477.441437f);
if (killer->GetTypeId() == TYPEID_PLAYER)
diff --git a/src/server/scripts/Northrend/grizzly_hills.cpp b/src/server/scripts/Northrend/grizzly_hills.cpp
index ccb31c869a4..fdebe3b7ab1 100644
--- a/src/server/scripts/Northrend/grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/grizzly_hills.cpp
@@ -162,7 +162,7 @@ public:
player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me);
DoScriptText(SAY_QUEST_COMPLETE, me, player);
}
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
break;
case 25:
DoScriptText(SAY_VICTORY4, me);
diff --git a/src/server/scripts/Northrend/howling_fjord.cpp b/src/server/scripts/Northrend/howling_fjord.cpp
index 3c44fa0eb44..5e4b7dafdb4 100644
--- a/src/server/scripts/Northrend/howling_fjord.cpp
+++ b/src/server/scripts/Northrend/howling_fjord.cpp
@@ -389,7 +389,7 @@ public:
{
if (player->isAlive())
{
- summon->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ summon->SetWalk(false);
summon->GetMotionMaster()->MovePoint(0, afCenter[0], afCenter[1], afCenter[2]);
summon->AI()->AttackStart(player);
return;
diff --git a/src/server/scripts/Northrend/zuldrak.cpp b/src/server/scripts/Northrend/zuldrak.cpp
index 0af82345dce..1bf04bc624c 100644
--- a/src/server/scripts/Northrend/zuldrak.cpp
+++ b/src/server/scripts/Northrend/zuldrak.cpp
@@ -1328,7 +1328,7 @@ public:
break;
case 2:
// walk forward
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(0, me->GetPositionX() + (cos(m_heading) * 10), me->GetPositionY() + (sin(m_heading) * 10), me->GetPositionZ());
m_uiTimer = 5000;
m_uiPhase = 3;
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 58f0e10c950..b0a42614ee3 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -750,7 +750,7 @@ public:
if (!Trigger) return;
Trigger->SetSpeed(MOVE_WALK, 3);
- Trigger->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ Trigger->SetWalk(true);
Trigger->GetMotionMaster()->MovePoint(0, final.x, final.y, final.z);
// Trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -867,7 +867,7 @@ public:
Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
break;
case 9: // land
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->StopMoving();
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
for (uint8 i = 0; i < 2; ++i)
@@ -1537,7 +1537,7 @@ public:
void BeginWalk()
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->SetSpeed(MOVE_RUN, 1.0f);
me->GetMotionMaster()->MovePoint(0, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z);
}
@@ -1869,7 +1869,7 @@ void boss_illidan_stormrage::boss_illidan_stormrageAI::Reset()
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->setActive(false);
Summons.DespawnAll();
}
@@ -1932,7 +1932,7 @@ void boss_illidan_stormrage::boss_illidan_stormrageAI::HandleTalkSequence()
// Equip our warglaives!
SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_ID_OFF_HAND, EQUIP_NO_CHANGE);
me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
break;
case 9:
if (GETCRE(Akama, AkamaGUID))
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 5ca3189ebca..08b188f7301 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp
@@ -354,7 +354,7 @@ public:
if (Sorcerer)
{
CAST_AI(mob_ashtongue_sorcerer::mob_ashtongue_sorcererAI, Sorcerer->AI())->ShadeGUID = me->GetGUID();
- Sorcerer->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ Sorcerer->SetWalk(false);
Sorcerer->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
Sorcerer->SetTarget(me->GetGUID());
Sorcerers.push_back(Sorcerer->GetGUID());
@@ -369,7 +369,7 @@ public:
Creature* Spawn = me->SummonCreature(spawnEntries[i], X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
if (Spawn)
{
- Spawn->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ Spawn->SetWalk(false);
Spawn->GetMotionMaster()->MovePoint(0, AGGRO_X, AGGRO_Y, AGGRO_Z);
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
Spawn->AI()->AttackStart(target);
@@ -430,7 +430,7 @@ public:
Creature* Defender = me->SummonCreature(CREATURE_DEFENDER, SpawnLocations[ran].x, SpawnLocations[ran].y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
if (Defender)
{
- Defender->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ Defender->SetWalk(false);
bool move = true;
if (AkamaGUID)
{
@@ -760,7 +760,7 @@ public:
{
ShadeHasDied = true;
WayPointId = 0;
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[0].x, AkamaWP[0].y, AkamaWP[0].z);
}
if (Shade && Shade->isAlive())
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 33ce04e45e3..2db259744df 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
@@ -644,7 +644,7 @@ public:
if (move <= diff)
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
if (phase == 1)
me->GetMotionMaster()->MovePoint(0, x, y, z);
if (phase == 1 && me->IsWithinDist3d(x, y, z, 0.1f))
@@ -779,7 +779,7 @@ public:
void Reset()
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->setFaction(14);
movement_timer = 0;
ToxicSpore_Timer = 5000;
diff --git a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp
index ecea5e6abb4..4f422da35ad 100644
--- a/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/HellfireRamparts/boss_vazruden_the_herald.cpp
@@ -145,8 +145,8 @@ class boss_nazan : public CreatureScript
flight = false;
BellowingRoar_Timer = 6000;
ConeOfFire_Timer = 12000;
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetLevitate(false);
+ me->SetWalk(true);
me->GetMotionMaster()->Clear();
if (Unit* victim = SelectTarget(SELECT_TARGET_NEAREST, 0))
me->AI()->AttackStart(victim);
@@ -374,7 +374,7 @@ class boss_vazruden_the_herald : public CreatureScript
if (summoned->GetEntry() == ENTRY_NAZAN)
{
CAST_AI(boss_nazan::boss_nazanAI, summoned->AI())->VazrudenGUID = VazrudenGUID;
- summoned->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ summoned->SetLevitate(true);
summoned->SetSpeed(MOVE_FLIGHT, 2.5f);
if (victim)
AttackStartNoMove(victim);
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
index 3f07552441b..12e28d42a67 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp
@@ -95,7 +95,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript
removeAdds();
me->SetSpeed(MOVE_RUN, 2);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
summoned = 2;
InBlade = false;
diff --git a/src/server/scripts/Outland/nagrand.cpp b/src/server/scripts/Outland/nagrand.cpp
index 668db2efcbb..f1aaf82cb67 100644
--- a/src/server/scripts/Outland/nagrand.cpp
+++ b/src/server/scripts/Outland/nagrand.cpp
@@ -258,7 +258,7 @@ public:
if (summoned->isTotem())
return;
- summoned->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ summoned->SetWalk(false);
summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
summoned->AI()->AttackStart(me);
@@ -603,7 +603,7 @@ public:
if (summoned->isTotem())
return;
- summoned->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ summoned->SetWalk(false);
summoned->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
summoned->AI()->AttackStart(me);
}
diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp
index 19c4754c4fd..6acd9bf6c99 100644
--- a/src/server/scripts/Outland/shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/shadowmoon_valley.cpp
@@ -224,7 +224,7 @@ public:
me->setFaction(FACTION_DEFAULT);
FlyTimer = 10000;
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->SetVisible(true);
}
@@ -271,7 +271,7 @@ public:
PlayerGUID = 0;
}
me->SetVisible(false);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(false);
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
}
@@ -309,7 +309,7 @@ public:
pos.m_positionZ += 25;
}
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->GetMotionMaster()->MovePoint(1, pos);
}
}
@@ -366,7 +366,7 @@ public:
float x, y, z;
caster->GetClosePoint(x, y, z, me->GetObjectSize());
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
me->GetMotionMaster()->MovePoint(1, x, y, z);
}
}
@@ -815,7 +815,7 @@ public:
case 19: DoScriptText(LORD_ILLIDAN_SAY_7, Illi); return 5000; break;
case 20:
Illi->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- Illi->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ Illi->SetLevitate(true);
return 500; break;
case 21: DoScriptText(OVERLORD_SAY_5, me); return 500; break;
case 22:
diff --git a/src/server/scripts/Outland/terokkar_forest.cpp b/src/server/scripts/Outland/terokkar_forest.cpp
index 043b74b6924..5eb88e6bfb6 100644
--- a/src/server/scripts/Outland/terokkar_forest.cpp
+++ b/src/server/scripts/Outland/terokkar_forest.cpp
@@ -497,7 +497,8 @@ public:
me->SetInFront(player); break;
case 30: me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE); break;
case 31: DoCast(me, SPELL_CAT);
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); break;
+ me->SetWalk(false);
+ break;
}
}
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 92fae4e1299..eb42b377128 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -736,6 +736,7 @@ class spell_dk_death_coil : public SpellScriptLoader
int32 damage = GetEffectValue();
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
+ {
if (caster->IsFriendlyTo(target))
{
int32 bp = int32(damage * 1.5f);
@@ -743,6 +744,7 @@ class spell_dk_death_coil : public SpellScriptLoader
}
else
caster->CastCustomSpell(target, SPELL_DEATH_COIL_DAMAGE, &damage, NULL, NULL, true);
+ }
}
void Register()
@@ -770,9 +772,7 @@ class spell_dk_death_grip : public SpellScriptLoader
void HandleDummy(SpellEffIndex effIndex)
{
int32 damage = GetEffectValue();
- Spell* baseSpell = GetSpell();
Position pos;
- Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
{
GetSummonPosition(effIndex, pos, 0.0f, 0);
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index ec82dbc0e57..db33a9e0332 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -196,7 +196,7 @@ class spell_gen_cannibalize : public SpellScriptLoader
float max_range = GetSpellInfo()->GetMaxRange(false);
WorldObject* result = NULL;
// search for nearby enemy corpse in range
- Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_SELECT_CHECK_ENEMY);
+ Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY);
Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
if (!result)
@@ -1084,7 +1084,7 @@ class spell_gen_seaforium_blast : public SpellScriptLoader
// but in effect handling OriginalCaster can become NULL
if (Unit* originalCaster = GetOriginalCaster())
if (GameObject* go = GetHitGObj())
- if (GetHitGObj()->GetGOInfo()->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+ if (go->GetGOInfo()->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
originalCaster->CastSpell(originalCaster, SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT, true);
}
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index dd9bfd90a0b..855af75cd83 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -532,7 +532,7 @@ class spell_hun_pet_carrion_feeder : public SpellScriptLoader
float max_range = GetSpellInfo()->GetMaxRange(false);
WorldObject* result = NULL;
// search for nearby enemy corpse in range
- Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_SELECT_CHECK_ENEMY);
+ Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY);
Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
if (!result)
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 4e7b195621a..079221a97e8 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -221,10 +221,12 @@ class spell_item_gnomish_death_ray : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
+ {
if (urand(0, 99) < 15)
caster->CastSpell(caster, SPELL_GNOMISH_DEATH_RAY_SELF, true, NULL); // failure
else
caster->CastSpell(target, SPELL_GNOMISH_DEATH_RAY_TARGET, true, NULL);
+ }
}
void Register()
@@ -1290,10 +1292,12 @@ class spell_item_nigh_invulnerability : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Item* castItem = GetCastItem())
+ {
if (roll_chance_i(86)) // Nigh-Invulnerability - success
caster->CastSpell(caster, SPELL_NIGH_INVULNERABILITY, true, castItem);
else // Complete Vulnerability - backfire in 14% casts
caster->CastSpell(caster, SPELL_COMPLETE_VULNERABILITY, true, castItem);
+ }
}
void Register()
@@ -1988,6 +1992,34 @@ class spell_item_refocus : public SpellScriptLoader
}
};
+class spell_item_muisek_vessel : public SpellScriptLoader
+{
+ public:
+ spell_item_muisek_vessel() : SpellScriptLoader("spell_item_muisek_vessel") { }
+
+ class spell_item_muisek_vessel_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_item_muisek_vessel_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* target = GetHitCreature())
+ if (target->isDead())
+ target->ForcedDespawn();
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_item_muisek_vessel_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_item_muisek_vessel_SpellScript();
+ }
+};
+
void AddSC_item_spell_scripts()
{
// 23074 Arcanite Dragonling
@@ -2039,4 +2071,5 @@ void AddSC_item_spell_scripts()
new spell_item_unusual_compass();
new spell_item_uded();
new spell_item_chicken_cover();
+ new spell_item_muisek_vessel();
}
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 70027ca9fd3..b012fe5f183 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -255,7 +255,7 @@ class spell_pri_reflective_shield_trigger : public SpellScriptLoader
if (dmgInfo.GetAttacker() == target)
return;
- if (Unit* caster = GetCaster())
+ if (GetCaster())
if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(PRIEST_SPELL_REFLECTIVE_SHIELD_R1, EFFECT_0))
{
int32 bp = CalculatePctN(absorbAmount, talentAurEff->GetAmount());
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index a581980bf8e..278abcc0c0b 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1065,6 +1065,42 @@ class spell_q9452_cast_net: public SpellScriptLoader
}
};
+#define SAY_1 "Sons of Hodir! I humbly present to you..."
+#define SAY_2 "The Helm of Hodir!"
+#define NPC_KILLCREDIT 30210 // Hodir's Helm KC Bunny
+
+class spell_q12987_read_pronouncement : public SpellScriptLoader
+{
+public:
+ spell_q12987_read_pronouncement() : SpellScriptLoader("spell_q12987_read_pronouncement") { }
+
+ class spell_q12987_read_pronouncement_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_q12987_read_pronouncement_AuraScript);
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ // player must cast kill credit and do emote text, according to sniff
+ if (Player* target = GetTarget()->ToPlayer())
+ {
+ target->MonsterWhisper(SAY_1, target->GetGUID(), true);
+ target->KilledMonsterCredit(NPC_KILLCREDIT, 0);
+ target->MonsterWhisper(SAY_2, target->GetGUID(), true);
+ }
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_q12987_read_pronouncement_AuraScript::OnApply, EFFECT_0, SPELL_AURA_NONE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_q12987_read_pronouncement_AuraScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -1090,4 +1126,5 @@ void AddSC_quest_spell_scripts()
new spell_q13280_13283_plant_battle_standard();
new spell_q14112_14145_chum_the_water();
new spell_q9452_cast_net();
+ new spell_q12987_read_pronouncement();
}
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 1bb531be4c8..b1aff706db0 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -325,12 +325,14 @@ class spell_warl_soulshatter : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
+ {
if (target->CanHaveThreatList() && target->getThreatManager().getThreat(caster) > 0.0f)
{
sLog->outString("THREATREDUCTION");
caster->CastSpell(target, SPELL_SOULSHATTER, true);
} else
- sLog->outString("can have threat? %b . threat number? %f ",target->CanHaveThreatList(),target->getThreatManager().getThreat(caster));
+ sLog->outString("can have threat? %u . threat number? %f ",target->CanHaveThreatList(),target->getThreatManager().getThreat(caster));
+ }
}
void Register()
diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp
index 9f652e7a859..a844e500ce5 100644
--- a/src/server/scripts/World/boss_emerald_dragons.cpp
+++ b/src/server/scripts/World/boss_emerald_dragons.cpp
@@ -198,7 +198,7 @@ class npc_dream_fog : public CreatureScript
me->GetMotionMaster()->MoveRandom(25.0f);
}
// Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it
- me->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
me->SetSpeed(MOVE_WALK, 0.75f);
}
else
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 1e1e34431a2..8513eae5876 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -137,8 +137,8 @@ public:
if (!spawnedTemplate)
{
- SpawnAssoc = NULL;
sLog->outErrorDb("TCSR: Creature template entry %u does not exist in DB, which is required by npc_air_force_bots", SpawnAssoc->spawnedCreatureEntry);
+ SpawnAssoc = NULL;
return;
}
}
@@ -421,7 +421,7 @@ public:
float x, y, z;
me->GetPosition(x, y, z);
me->Relocate(x, y, z + 0.94f);
- me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetLevitate(true);
me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
WorldPacket data; //send update position to client
me->BuildHeartBeatMsg(&data);
@@ -764,7 +764,7 @@ public:
DoScriptText(RAND(SAY_DOC1, SAY_DOC2, SAY_DOC3), me);
uint32 mobId = me->GetEntry();
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ me->SetWalk(false);
switch (mobId)
{
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 3c8a08df3a1..ab4a8a832b8 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2539,14 +2539,14 @@ Arena.QueueAnnouncer.Enable = 0
#
# Arena.ArenaSeason.ID
-# Description: Current area season id shown in clients.
+# Description: Current arena season id shown in clients.
# Default: 8
Arena.ArenaSeason.ID = 8
#
# Arena.ArenaSeason.InProgress
-# Description: State of current area season.
+# Description: State of current arena season.
# Default: 1 - (Active)
# 0 - (Finished)