diff options
120 files changed, 3055 insertions, 733 deletions
diff --git a/.travis.yml b/.travis.yml index 80e237e4d12..cddb98492a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,15 +25,15 @@ install: - cd bin - cmake ../ -DWITH_WARNINGS=1 -DWITH_COREDEBUG=0 -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DTOOLS=1 -DSCRIPTS="dynamic" -DSERVERS=1 -DNOJEM=1 -DWITH_DYNAMIC_LINKING=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Werror" -DCMAKE_CXX_FLAGS="-Werror" -DCMAKE_INSTALL_PREFIX=check_install - cd .. - - sudo chmod +x contrib/check_updates.sh + - chmod +x contrib/check_updates.sh script: - $CXX --version - mysql -uroot < sql/create/create_mysql.sql - mysql -utrinity -ptrinity auth < sql/base/auth_database.sql - - ./contrib/check_updates.sh auth auth + - ./contrib/check_updates.sh auth 3.3.5 auth - mysql -utrinity -ptrinity characters < sql/base/characters_database.sql - - ./contrib/check_updates.sh characters characters + - ./contrib/check_updates.sh characters 3.3.5 characters - mysql -utrinity -ptrinity world < sql/base/dev/world_database.sql - cat sql/updates/world/*.sql | mysql -utrinity -ptrinity world - mysql -uroot < sql/create/drop_mysql.sql diff --git a/contrib/check_updates.sh b/contrib/check_updates.sh index 017542eb807..6c33d07ae8b 100644 --- a/contrib/check_updates.sh +++ b/contrib/check_updates.sh @@ -1,6 +1,7 @@ #!/bin/sh name=$1 -database=$2 +branch=$2 +database=$3 echo "Database Updater check script:" echo " Checking database '${name}' for missing filenames in tables..." @@ -9,7 +10,7 @@ echo # Select all entries which are in the updates table entries=$(mysql -uroot ${database} -e "SELECT name FROM updates" | grep ".sql") -cd sql/updates/${name} +cd sql/updates/${name}/${branch} error=0 updates=0 diff --git a/issue_template.md b/issue_template.md index f2ad2ef29c3..8653726f830 100644 --- a/issue_template.md +++ b/issue_template.md @@ -10,13 +10,13 @@ 2. 3. -**Branch(es)**: 335/6x +**Branch(es)**: 335/6x -**TC hash/commit**: +**TC hash/commit**: -**TDB version**: +**TDB version**: -**Operating system**: +**Operating system**: **Linking model**: static/dynamic diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 6dc81ab211e..fd47a349f01 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -486,7 +486,7 @@ CREATE TABLE `updates` ( LOCK TABLES `updates` WRITE; /*!40000 ALTER TABLE `updates` DISABLE KEYS */; -INSERT INTO `updates` VALUES ('2014_11_10_00_auth.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 21:44:12',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_21_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_00_auth.sql','E8C5B74BB45F0F35DEC182C72BACF435C7066FB0','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_01_auth.sql','862961815354DA2746F5F71FBC8155F57CBE75AB','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_02_auth.sql','33E4F94086590768EF5D4855DD43D7DE7C06ADA4','ARCHIVED','2015-03-21 21:44:51',0),('2015_08_21_00_auth.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-10-05 23:16:19',0),('2015_11_07_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 00:42:36',92),('2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-01-13 00:00:00',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','2016-04-11 03:18:17','2016-04-11 03:18:17',0); +INSERT INTO `updates` VALUES ('2014_11_10_00_auth.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 21:44:12',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 21:44:12',0),('2014_12_21_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_00_auth.sql','E8C5B74BB45F0F35DEC182C72BACF435C7066FB0','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_01_auth.sql','862961815354DA2746F5F71FBC8155F57CBE75AB','ARCHIVED','2015-03-21 21:44:12',0),('2015_03_20_02_auth.sql','33E4F94086590768EF5D4855DD43D7DE7C06ADA4','ARCHIVED','2015-03-21 21:44:51',0),('2015_08_21_00_auth.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-10-05 23:16:19',0),('2015_11_07_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2016-04-11 00:42:36',92),('2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-01-13 00:00:00',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-04-11 03:18:17',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/auth/2016_04_11_00_auth.sql b/sql/updates/auth/3.3.5/2016_04_11_00_auth.sql index be8a4d21b66..be8a4d21b66 100644 --- a/sql/updates/auth/2016_04_11_00_auth.sql +++ b/sql/updates/auth/3.3.5/2016_04_11_00_auth.sql diff --git a/sql/updates/auth/dummy b/sql/updates/auth/3.3.5/dummy index e69de29bb2d..e69de29bb2d 100644 --- a/sql/updates/auth/dummy +++ b/sql/updates/auth/3.3.5/dummy diff --git a/sql/updates/characters/2016_04_11_00_characters.sql b/sql/updates/characters/3.3.5/2016_04_11_00_characters.sql index be8a4d21b66..be8a4d21b66 100644 --- a/sql/updates/characters/2016_04_11_00_characters.sql +++ b/sql/updates/characters/3.3.5/2016_04_11_00_characters.sql diff --git a/sql/updates/characters/dummy b/sql/updates/characters/3.3.5/dummy index e69de29bb2d..e69de29bb2d 100644 --- a/sql/updates/characters/dummy +++ b/sql/updates/characters/3.3.5/dummy diff --git a/sql/updates/world/2016_04_11_00_world.sql b/sql/updates/world/3.3.5/2016_04_11_00_world.sql index 2f8d539fe43..2f8d539fe43 100644 --- a/sql/updates/world/2016_04_11_00_world.sql +++ b/sql/updates/world/3.3.5/2016_04_11_00_world.sql diff --git a/sql/updates/world/2016_04_11_01_world_335.sql b/sql/updates/world/3.3.5/2016_04_11_01_world_335.sql index a432307d0b1..a432307d0b1 100644 --- a/sql/updates/world/2016_04_11_01_world_335.sql +++ b/sql/updates/world/3.3.5/2016_04_11_01_world_335.sql diff --git a/sql/updates/world/2016_04_11_02_world_335.sql b/sql/updates/world/3.3.5/2016_04_11_02_world_335.sql index 93b6000554c..93b6000554c 100644 --- a/sql/updates/world/2016_04_11_02_world_335.sql +++ b/sql/updates/world/3.3.5/2016_04_11_02_world_335.sql diff --git a/sql/updates/world/2016_04_15_03_world_335.sql b/sql/updates/world/3.3.5/2016_04_15_03_world_335.sql index afbe3b3ab63..afbe3b3ab63 100644 --- a/sql/updates/world/2016_04_15_03_world_335.sql +++ b/sql/updates/world/3.3.5/2016_04_15_03_world_335.sql diff --git a/sql/updates/world/3.3.5/2016_04_16_00_world.sql b/sql/updates/world/3.3.5/2016_04_16_00_world.sql new file mode 100644 index 00000000000..9219a4ef316 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_16_00_world.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_baron_geddon_inferno'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(19695, 'spell_baron_geddon_inferno'); diff --git a/sql/updates/world/3.3.5/2016_04_16_01_world.sql b/sql/updates/world/3.3.5/2016_04_16_01_world.sql new file mode 100644 index 00000000000..95a8f0934ad --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_16_01_world.sql @@ -0,0 +1,307 @@ +SET @OGUID := 78735; -- 20 free guids required +SET @CGUID := 84148; -- 9 free guids required + +SET @NPC := @CGUID+1; +SET @PATH := @NPC * 10; + +UPDATE `creature_template` SET `difficulty_entry_1`=0 WHERE `entry` IN (25740,25755,25756,25865); +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82, `mechanic_immune_mask`=617299839, `ScriptName`='boss_ahune' WHERE `entry`=25740; -- Ahune +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80, `AIName`='SmartAI' WHERE `entry`=25755; -- Ahunite Hailstone +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80, `AIName`='SmartAI' WHERE `entry`=25756; -- Ahunite Coldwave +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80, `AIName`='SmartAI' WHERE `entry`=25757; -- Ahunite Frostwind +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80, `flags_extra`=`flags_extra`|0x40000000, `mechanic_immune_mask`=617299839, `ScriptName`='npc_frozen_core' WHERE `entry`=25865; -- Frozen Core +UPDATE `creature_template` SET `ScriptName`='npc_ahune_bunny' WHERE `entry`=25745; +UPDATE `creature_template` SET `ScriptName`='npc_earthen_ring_flamecaller' WHERE `entry`=25754; +UPDATE `creature_template` SET `unit_flags`=33554432, `MovementType`=2 WHERE `entry` IN (25964,25965,25966); -- Shaman beam bunny +UPDATE `creature_template` SET `unit_flags`=33554432 WHERE `entry`=26239; -- Ghost of Ahune +UPDATE `creature_template` SET `flags_extra`=128 WHERE `entry`=25985; -- Ahune Ice Spear Bunny +UPDATE `gameobject_template` SET `ScriptName`='go_ahune_ice_stone' WHERE `entry`=187882; +UPDATE `creature` SET `orientation`=2.408554 WHERE `guid`=202734; -- Luma +UPDATE `creature` SET `orientation`=3.804818 WHERE `guid`=202737; -- Flamecaller +UPDATE `creature_template` SET `HealthModifier`=94.5, `unit_flags`=33554688 WHERE `entry`=25865; +UPDATE `creature_template` SET `HealthModifier`=18.8 WHERE `entry`=25755; +UPDATE `creature_template` SET `HealthModifier`=3.538 WHERE `entry`=25756; +UPDATE `creature_template` SET `HealthModifier`=1.5 WHERE `entry`=25757; +UPDATE `creature_template` SET `HealthModifier`=4 WHERE `entry`=40446; +UPDATE `creature_template` SET `InhabitType`=7 WHERE `entry` IN (25964,25965,25966,26190); + +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_ahune_synch_health', +'spell_ice_spear_control_aura', +'spell_slippery_floor_periodic', +'spell_summon_ice_spear_delayer', +'spell_summoning_rhyme_aura', +'spell_ahune_spanky_hands', +'spell_ahune_minion_despawner', +'spell_ice_spear_target_picker', +'spell_ice_bombardment_dest_picker'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(46430, 'spell_ahune_synch_health'), +(46371, 'spell_ice_spear_control_aura'), +(46320, 'spell_slippery_floor_periodic'), +(46878, 'spell_summon_ice_spear_delayer'), +(45926, 'spell_summoning_rhyme_aura'), +(46146, 'spell_ahune_spanky_hands'), +(46843, 'spell_ahune_minion_despawner'), +(46372, 'spell_ice_spear_target_picker'), +(46398, 'spell_ice_bombardment_dest_picker'); + +DELETE FROM `creature_text` WHERE `entry` IN (25745,25754,25697,40446); +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(25745,0,0,'The Earthen Ring\'s Assault Begins.',41,0,100,0,0,0,24930,1,'Ahune Bunny- EMOTE_EARTHEN_ASSAULT'), +(25754,0,0,'Ahune Retreats. His defenses diminish.',41,0,100,0,0,0,24931,1,'Earthen Ring Flamecaller - EMOTE_RETREAT'), +(25754,1,0,'Ahune will soon resurface.',41,0,100,0,0,0,24932,1,'Earthen Ring Flamecaller - EMOTE_RESURFACE'), +(40446,0,0,'How DARE you! You will not stop the coming of Lord Ahune!',14,0,100,0,0,0,40437,0,'Skar\'this the Summoner'), +(25697,0,0,'The Ice Stone has melted!',14,0,100,0,0,0,24895,0,'Luma Skymother - SAY_PLAYER_1'), +(25697,1,0,'Ahune, your strength grows no more!',14,0,100,0,0,0,24893,0,'Luma Skymother - SAY_PLAYER_2'), +(25697,2,0,'Your frozen reign will not come to pass!',14,0,100,0,0,0,24894,0,'Luma Skymother - SAY_PLAYER_3'); + +DELETE FROM `gossip_menu` WHERE `entry`=11389; +INSERT INTO `gossip_menu` VALUES +(11389,15864); + +DELETE FROM `gossip_menu_option` WHERE `menu_id`=11389; +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES +(11389,1,0,'Disturb the stone and summon Lord Ahune.',40443,1,1,0,0,0,0,NULL,0); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (25740,25755,25865,25985,25952); +INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES +(25740, 0, 0, 9, 1, 61976), +(25755, 0, 0, 0, 0, 46542), +(25865, 0, 0, 0, 0, '46810 61976'), +(25985, 0, 0, 0, 0, '75498 46878'), +(25952, 0, 0, 0, 0, 46314); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (46603,46593,46735,45930,45941,46809,46843,46396,46398,46236); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,46603,0,0,31,0,3,26121,0,0,0,0,'',"Spell 'Force Wisp Flight Missile' can hit 'Wisp Source Bunny'"), +(13,1,46593,0,0,31,0,3,26120,0,0,0,0,'',"Spell 'Wisp Flight Missile and Beam' can hit 'Wisp Dest Bunny'"), +(13,1,46735,0,0,31,0,3,26190,0,0,0,0,'',"Spell 'Spank - Force Bunny To Knock You To' can hit '[PH] Spank Target Bunny'"), +(13,1,45930,0,1,31,0,3,25971,0,0,0,0,'',"Spell 'Ahune - Summoning Rhyme Spell, make bonfire' can hit 'Shaman Bonfire Bunny 000'"), +(13,1,45930,0,2,31,0,3,25972,0,0,0,0,'',"Spell 'Ahune - Summoning Rhyme Spell, make bonfire' can hit 'Shaman Bonfire Bunny 001'"), +(13,1,45930,0,3,31,0,3,25973,0,0,0,0,'',"Spell 'Ahune - Summoning Rhyme Spell, make bonfire' can hit 'Shaman Bonfire Bunny 002'"), +(13,1,45941,0,0,31,0,3,25746,0,0,0,0,'',"Spell 'Summon Ahune's Loot Missile' can hit '[PH] Ahune Loot Loc Bunny'"), +(13,1,46809,0,0,31,0,3,26239,0,0,0,0,'',"Spell 'Make Ahune's Ghost Burst' can hit 'Ghost of Ahune"), +(13,1,46843,0,1,31,0,3,25756,0,0,0,0,'',"Spell 'Minion Despawner' can hit 'Ahunite Coldwave'"), +(13,1,46843,0,2,31,0,3,25757,0,0,0,0,'',"Spell 'Minion Despawner' can hit 'Ahunite Frostwind'"), +(13,1,46843,0,3,31,0,3,25755,0,0,0,0,'',"Spell 'Minion Despawner' can hit 'Ahunite Hailstone'"), +(13,1,46398,0,0,31,0,3,25972,0,0,0,0,'',"Spell 'Ice Bombardment Dest Picker' can hit 'Shaman Bonfire Bunny'"), +(13,1,46396,0,0,31,0,3,25972,0,0,0,0,'',"Spell 'Ice Bombardment' can hit 'Shaman Bonfire Bunny'"), +(13,1,46236,0,1,31,0,3,25971,0,0,0,0,'',"Spell 'Close opening Visual' can hit 'Shaman Bonfire Bunny 000'"), +(13,1,46236,0,2,31,0,3,25972,0,0,0,0,'',"Spell 'Close opening Visual' can hit 'Shaman Bonfire Bunny 001'"), +(13,1,46236,0,3,31,0,3,25973,0,0,0,0,'',"Spell 'Close opening Visual' can hit 'Shaman Bonfire Bunny 002'"); + +DELETE FROM `disables` WHERE `sourceType`=0 AND `entry` IN (46314,46603,46593,46422); +INSERT INTO `disables` (`sourceType`, `entry`, `flags`, `params_0`, `params_1`, `comment`) VALUES +(0,46314,64,0,0,'Disable LOS for spell Ahune - Slippery Floor Ambient'), +(0,46603,64,0,0,'Disable LOS for spell Force Whisp to Flight'), +(0,46593,64,0,0,'Disable LOS for spell Whisp Flight Missile and Beam'), +(0,46422,64,0,0,'Disable LOS for spell Shamans Look for Opening'); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (45947,-45964,45964); +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(45947,45946,2,''), +(-45964,-46333,0,''), +(45964,46333,0,''); + +-- Skar'this the Summoner +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=40446; +DELETE FROM `smart_scripts` WHERE `entryorguid`=40446 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 +(40446,0,0,0,1,0,100,1,0,0,0,0,11,75427,0,0,0,0,0,1,0,0,0,0,0,0,0,'Skar\'this the Summoner - OOC - Cast \'Frost Channelling\''), +(40446,0,1,0,4,0,100,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Skar\'this the Summoner - On agro - say'), +(40446,0,2,0,0,0,100,0,5000,5000,15000,15000,11,55909,1,0,0,0,0,2,0,0,0,0,0,0,0,'Skar\'this the Summoner - IC - Cast Crashing Wave'), +(40446,0,3,0,0,0,100,0,10000,10000,20000,20000,11,11831,1,0,0,0,0,2,0,0,0,0,0,0,0,'Skar\'this the Summoner - IC - Cast Frost Nova'), +(40446,0,4,0,0,0,100,0,7000,7000,9000,9000,11,15043,0,0,0,0,0,2,0,0,0,0,0,0,0,'Skar\'this the Summoner - IC - Cast Frostbolt'); + +-- Summon Loot Bunny SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=25746; +DELETE FROM `smart_scripts` WHERE `entryorguid`=25746 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 +(25746,0,0,0,8,0,100,0,45941,0,0,0,11,46891,0,0,0,0,0,1,0,0,0,0,0,0,0,'[PH] Ahune Loot Loc Bunny - On SpellHit - Cast \'Summon Loot\''); + +-- [PH] Spank Target Bunny SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=26190; +DELETE FROM `smart_scripts` WHERE `entryorguid`=26190 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 +(26190,0,0,0,8,0,100,0,46735,0,0,0,11,46734,0,0,0,0,0,7,0,0,0,0,0,0,0,'[PH] Spank Target Bunny - On SpellHit \'Spank - Force Bunny To Knock You To\' - Cast \'Knock To\''); + +-- Ghost of Ahune +UPDATE `creature_template` SET `AIName`='SmartAI', `flags_extra`='2' WHERE `entry`=26239; +DELETE FROM `smart_scripts` WHERE `entryorguid`=26239 AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid`=2623900 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 +(26239,0,0,0,25,0,100,0,0,0,0,0,3,0,11686,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - On Reset - Morph to Model 11686'), +(26239,0,1,0,8,0,100,0,46809,0,4000,4000,80,2623900,2,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - On SpellHit \'Make Ahune\'s Ghost Burst\' - Call Timed ActionList'), +(2623900,9,0,0,0,0,100,0,0,0,0,0,3,0,23707,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - Timed ActionList - Morph to Model 23707'), +(2623900,9,1,0,0,0,100,0,0,0,0,0,11,46786,0,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - Timed ActionList - Cast \'Ahune\'s Ghost Disguise\''), +(2623900,9,2,0,0,0,100,0,2400,2400,0,0,47,0,0,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - Timed ActionList - Set Visibility Off'), +(2623900,9,3,0,0,0,100,0,500,500,0,0,3,0,11686,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - Timed ActionList - Morph to Model 11686'), +(2623900,9,4,0,0,0,100,0,0,0,0,0,47,1,0,0,0,0,0,1,0,0,0,0,0,0,0,'Ghost of Ahune - Timed ActionList - Set Visibility On'); + +-- Wisp Source Bunny SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=26121; +DELETE FROM `smart_scripts` WHERE `entryorguid`=26121 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 +(26121,0,0,1,8,0,100,0,46603,0,0,0,11,46593,0,0,0,0,0,11,26120,100,0,0,0,0,0,'Wisp Source Bunny - On SpellHit \'Force Wisp Flight Missile\' - Cast \'Wisp Flight Missile and Beam\''), +(26121,0,1,0,61,0,100,0,0,0,0,0,41,9000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Wisp Source Bunny - On SpellHit \'Force Wisp Flight Missile\' - Despawn in 9s'); + +-- Wisp Dest Bunny SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=26120; +DELETE FROM `smart_scripts` WHERE `entryorguid`=26120 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 +(26120,0,0,0,8,0,100,0,46593,0,0,0,41,9000,0,0,0,0,0,1,0,0,0,0,0,0,0,'Wisp Dest Bunny - On SpellHit \'Wisp Flight Missile and Beam\' - Despawn in 9s'); + +-- Shaman Beam Bunny SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (25971,25972,25973); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (25971,25972,25973) 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 +(25971,0,0,0,8,0,100,0,45930,0,0,0,11,46339,0,0,0,0,0,1,0,0,0,0,0,0,0,'Shaman Beam Bunny 000 - On SpellHit - Cast \'Bonfire Disguise\''), +(25972,0,0,0,8,0,100,0,45930,0,0,0,11,46339,0,0,0,0,0,1,0,0,0,0,0,0,0,'Shaman Beam Bunny 001 - On SpellHit - Cast \'Bonfire Disguise\''), +(25973,0,0,0,8,0,100,0,45930,0,0,0,11,46339,0,0,0,0,0,1,0,0,0,0,0,0,0,'Shaman Beam Bunny 002 - On SpellHit - Cast \'Bonfire Disguise\''); + +-- Ahunite Hailstone SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=25755; +DELETE FROM `smart_scripts` WHERE `entryorguid`=25755 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 +(25755,0,0,0,0,0,100,0,6000,8000,6000,8000,11,2676,0,0,0,0,0,2,0,0,0,0,0,0,0,'Ahunite Hailstone - In Combat - Cast \'Pulverize\''); + +-- Ahunite Coldwave SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=25756; +DELETE FROM `smart_scripts` WHERE `entryorguid`=25756 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 +(25756,0,0,0,0,0,100,0,5000,7000,6000,8000,11,46406,0,0,0,0,0,2,0,0,0,0,0,0,0,'Ahunite Coldwave - In Combat - Cast \'Bitter Blast\''); + +-- Ahunite Frostwind SAI +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=25757; +DELETE FROM `smart_scripts` WHERE `entryorguid`=25757 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 +(25757,0,0,0,54,0,100,0,0,0,0,0,11,12550,0,0,0,0,0,1,0,0,0,0,0,0,0,'Ahunite Frostwind - On Just Summoned - Cast \'Lightning Shield\''), +(25757,0,1,0,0,0,100,0,2000,2000,5000,7000,11,46568,0,0,0,0,0,18,120,0,0,0,0,0,0,'Ahunite Frostwind - In Combat - Cast \'Wind Buffet\''); + +DELETE FROM `item_loot_template` WHERE `entry`=35512; +INSERT INTO `item_loot_template` (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(35512,17202,0,100,0,1,0,2,5,NULL); + +DELETE FROM `item_loot_template` WHERE `Entry`=54536; +INSERT INTO `item_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES +(54536, 54806, 0, 3, 0, 1, 0, 1, 1), +(54536, 23247, 0, 100, 0, 1, 1, 5, 10), +(54536, 53641, 0, 3, 0, 1, 0, 1, 1); + +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID AND @CGUID+8; +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 +(@CGUID,25745,547,1,1,0,0,-96.64146,-230.8864,4.780959,1.413717,300,0,0,1,1,0,0,0,0), -- [PH] Ahune Summon Loc Bunny +(@CGUID+1,25964,547,1,1,0,0,-90.00211,-224.9285,-1.378754,2.956095,300,0,0,1,1,2,0,0,0), -- Shaman Beam Bunny 000 +(@CGUID+2,25965,547,1,1,0,0,-97.39627,-223.761,-1.494899,0.9130945,300,0,0,1,1,2,0,0,0), -- Shaman Beam Bunny 001 +(@CGUID+3,25966,547,1,1,0,0,-103.3054,-224.0149,0.5259815,5.676991,300,0,0,1,1,2,0,0,0), -- Shaman Beam Bunny 002 +(@CGUID+4,26190,547,1,1,0,0,-95.33572,-207.4834,16.28742,4.904375,300,0,0,1,1,0,0,0,0), -- [PH] Spank Target Bunny +(@CGUID+5,25952,547,1,1,0,0,-96.64146,-230.8864,4.780959,1.413717,300,0,0,1,1,0,0,0,0), -- Slippery Floor Bunny +(@CGUID+6,25952,547,1,1,0,0,-69.83901,-162.474,-2.303646,2.513274,300,0,0,1,1,0,0,0,0), -- Slippery Floor Bunny +(@CGUID+7,26239,547,1,1,0,0,-99.10214,-233.1872,-1.22297,1.466077,300,0,0,1,1,0,0,0,0), -- Ghost of Ahune +(@CGUID+8,25746,547,1,1,0,0,-96.8723,-212.8425,-1.149142,4.153883,300,0,0,1,1,0,0,0,0); -- [PH] Ahune Loot Loc Bunny + +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID AND @OGUID+19; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `VerifiedBuild`) VALUES +(@OGUID+0, 187882, 547, 0, 0, 1, 1, -69.90455, -162.2449, -2.366563, 2.426008, 0, 0, 0.9366722, 0.3502074, 120, 255, 1,0), -- Icestone +(@OGUID+1, 188067, 547, 0, 0, 1, 1,-79.397, -219.7025, -4.042892, -2.199115, 0, 0, -0.8910065, 0.4539906, 120, 255, 1, 0), -- Ice Block +(@OGUID+2, 188067, 547, 0, 0, 1, 1, -115.5985, -162.7724, -1.924025, -0.5585039, 0, 0, -0.2756367, 0.9612619, 120, 255, 1, 0), -- Ice Block +(@OGUID+3, 188067, 547, 0, 0, 1, 1, -71.89625, -145.4974, -1.551813, -1.954766, 0, 0, -0.8290367, 0.5591941, 120, 255, 1, 0), -- Ice Block +(@OGUID+4, 188067, 547, 0, 0, 1, 1, -49.27251, -168.9859, -1.898811, 2.007128, 0, 0, 0.8433914, 0.5372996, 120, 255, 1, 0), -- Ice Block +(@OGUID+5, 188067, 547, 0, 0, 1, 1, -75.95139, -182.771, -4.882017, -1.151916, 0, 0, -0.5446386, 0.8386708, 120, 255, 1, 0), -- Ice Block +(@OGUID+6, 188067, 547, 0, 0, 1, 1, -83.52528, -172.1806, -3.816522, 0.01745246, 0, 0, 0.00872612, 0.9999619, 120, 255, 1, 0), -- Ice Block +(@OGUID+7, 188067, 547, 0, 0, 1, 1, -83.52528, -217.3293, -3.0728, -0.4886912, 0, 0, -0.2419214, 0.9702958, 120, 255, 1, 0), -- Ice Block +(@OGUID+8, 188072, 547, 0, 0, 1, 1, -71.48915, -160.7316, -4.18569, -0.4188786, 0, 0, -0.2079115, 0.9781476, 120, 255, 1, 0), -- Ice Stone Mount +(@OGUID+9, 188072, 547, 0, 0, 1, 1, -69.21773, -163.491, -2.044773, 2.967041, 0, 0, 0.9961939, 0.08716504, 120, 255, 1, 0), -- Ice Stone Mount +(@OGUID+10, 188072, 547, 0, 0, 1, 1, -71.82486, -164.475, -3.962982, -0.9250239, 0, 0, -0.4461975, 0.8949345, 120, 255, 1, 0), -- Ice Stone Mount +(@OGUID+11, 188072, 547, 0, 0, 1, 1, -69.20837, -160.345, -4.25643, 1.850049, 0, 0, 0.7986355, 0.601815, 120, 255, 1, 0), -- Ice Stone Mount +(@OGUID+12, 188073, 547, 0, 0, 1, 1, -89.75205, -113.5002, -2.709442, 0.453785, 0, 0, 0.2249508, 0.9743701, 120, 255, 1, 0), -- Ahune Bonfire +(@OGUID+13, 188073, 547, 0, 0, 1, 1,-114.9574, -117.3017, -2.71, 2.007128, 0, 0, 0.8433914, 0.5372996, 120, 255, 1, 0), -- Ahune Bonfire +(@OGUID+14, 188142, 547, 0, 0, 1, 1, -74.65959, -243.8125, -2.735999, 2.216565, 0, 0, 0.8949337, 0.4461992, 120, 255, 1, 0), -- Ice Block, Big +(@OGUID+15, 188142, 547, 0, 0, 1, 1, -72.75314, -185.1547, -4.930593, 0.157079, 0, 0, 0.07845879, 0.9969174, 120, 255, 1, 0), -- Ice Block, Big +(@OGUID+16, 188142, 547, 0, 0, 1, 1, -103.7134, -245.5041, -1.377881, -1.291542, 0, 0, -0.6018143, 0.7986361, 120, 255, 1, 0), -- Ice Block, Big +(@OGUID+17, 188142, 547, 0, 0, 1, 1, -118.9196, -204.8023, -1.504161, 1.919862, 0, 0, 0.8191519, 0.5735767, 120, 255, 1, 0), -- Ice Block, Big +(@OGUID+18, 188142, 547, 0, 0, 1, 1, -117.3857, -165.9649, -2.018646, 0.5585039, 0, 0, 0.2756367, 0.9612619, 120, 255, 1, 0), -- Ice Block, Big +(@OGUID+19, 188142, 547, 0, 0, 1, 1, -75.42784, -221.16, -2.882941, 0.4886912, 0, 0, 0.2419214, 0.9702958, 120, 255, 1, 0); -- Ice Block, Big + +DELETE FROM `creature_addon` WHERE `guid` IN (@NPC,@NPC+1,@NPC+2); +INSERT INTO `creature_addon` (`guid`,`path_id`) VALUES +(@NPC,@PATH), +(@NPC+1,@PATH+10), +(@NPC+2,@PATH+20); + +DELETE FROM `waypoint_data` WHERE `id` IN (@PATH,@PATH+10,@PATH+20); +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,-107.1537,-233.7247,27.1834,0,0,0,100,0), +(@PATH,2,-109.4618,-232.0907,25.12787,0,0,0,100,0), +(@PATH,3,-109.4792,-229.4328,20.98899,0,0,0,100,0), +(@PATH,4,-105.9522,-226.8887,17.26674,0,0,0,100,0), +(@PATH,5,-101.0044,-224.8914,16.04452,0,0,0,100,0), +(@PATH,6,-96.82773,-225.9608,15.73896,0,0,0,100,0), +(@PATH,7,-92.59879,-227.0505,15.54452,0,0,0,100,0), +(@PATH,8,-90.07465,-229.0938,16.58224,0,0,0,100,0), +(@PATH,9,-88.24558,-231.7715,22.47455,0,0,0,100,0), +(@PATH,10,-91.0969,-232.6422,24.65563,0,0,0,100,0), +(@PATH,11,-97.20647,-234.4709,28.46118,0,0,0,100,0), +(@PATH,12,-101.5825,-234.9054,29.35008,0,0,0,100,0), + +(@PATH+10,1,-109.4618,-232.0907,25.12787,0,0,0,100,0), +(@PATH+10,2,-109.4792,-229.4328,20.98899,0,0,0,100,0), +(@PATH+10,3,-105.9522,-226.8887,17.26674,0,0,0,100,0), +(@PATH+10,4,-101.0044,-224.8914,16.04452,0,0,0,100,0), +(@PATH+10,5,-96.82773,-225.9608,15.73896,0,0,0,100,0), +(@PATH+10,6,-92.59879,-227.0505,15.54452,0,0,0,100,0), +(@PATH+10,7,-90.07465,-229.0938,16.58224,0,0,0,100,0), +(@PATH+10,8,-88.24558,-231.7715,22.47455,0,0,0,100,0), +(@PATH+10,9,-91.0969,-232.6422,24.65563,0,0,0,100,0), +(@PATH+10,10,-97.20647,-234.4709,28.46118,0,0,0,100,0), +(@PATH+10,11,-101.5825,-234.9054,29.35008,0,0,0,100,0), +(@PATH+10,12,-107.1537,-233.7247,27.1834,0,0,0,100,0), + +(@PATH+20,1,-97.20647,-234.4709,28.46118,0,0,0,100,0), +(@PATH+20,2,-101.5825,-234.9054,29.35008,0,0,0,100,0), +(@PATH+20,3,-107.1537,-233.7247,27.1834,0,0,0,100,0), +(@PATH+20,4,-109.4618,-232.0907,25.12787,0,0,0,100,0), +(@PATH+20,5,-109.4792,-229.4328,20.98899,0,0,0,100,0), +(@PATH+20,6,-105.9522,-226.8887,17.26674,0,0,0,100,0), +(@PATH+20,7,-101.0044,-224.8914,16.04452,0,0,0,100,0), +(@PATH+20,8,-96.82773,-225.9608,15.73896,0,0,0,100,0), +(@PATH+20,9,-92.59879,-227.0505,15.54452,0,0,0,100,0), +(@PATH+20,10,-90.07465,-229.0938,16.58224,0,0,0,100,0), +(@PATH+20,11,-88.24558,-231.7715,22.47455,0,0,0,100,0), +(@PATH+20,12,-91.0969,-232.6422,24.65563,0,0,0,100,0); + +DELETE FROM `game_event_creature` WHERE `guid` BETWEEN @CGUID AND @CGUID+8 AND `eventEntry`=1; +INSERT INTO `game_event_creature` (`eventEntry`,`guid`) VALUES +(1,@CGUID), +(1,@CGUID+1), +(1,@CGUID+2), +(1,@CGUID+3), +(1,@CGUID+4), +(1,@CGUID+5), +(1,@CGUID+6), +(1,@CGUID+7), +(1,@CGUID+8); + +DELETE FROM `game_event_gameobject` WHERE `guid` BETWEEN @OGUID AND @OGUID+19 AND `eventEntry`=1; +INSERT INTO `game_event_gameobject` (`eventEntry`,`guid`) VALUES +(1,@OGUID), +(1,@OGUID+1), +(1,@OGUID+2), +(1,@OGUID+3), +(1,@OGUID+4), +(1,@OGUID+5), +(1,@OGUID+6), +(1,@OGUID+7), +(1,@OGUID+8), +(1,@OGUID+9), +(1,@OGUID+10), +(1,@OGUID+11), +(1,@OGUID+12), +(1,@OGUID+13), +(1,@OGUID+14), +(1,@OGUID+15), +(1,@OGUID+16), +(1,@OGUID+17), +(1,@OGUID+18), +(1,@OGUID+19); diff --git a/sql/updates/world/3.3.5/2016_04_16_02_world.sql b/sql/updates/world/3.3.5/2016_04_16_02_world.sql new file mode 100644 index 00000000000..82982753067 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_16_02_world.sql @@ -0,0 +1,39 @@ +-- The column `spell1` was misused for this NPC. This NPC is undead. He cannot be MCed. The spell 29307 should be cast using SmartAI or by Script. +-- Also, link the zombies chows to the custom ScriptedAI defined in boss_gluth.cpp. +UPDATE `creature_template` SET `spell1`=0, `ScriptName`='npc_zombie_chow' WHERE `entry`=16360; +UPDATE `creature_template` SET `spell1`=0 WHERE `entry`=30303; + +-- connect the decimate spell (effect 0) used by Gluth (in both 10 man & 25) to the spell script defined in boss_gluth.cpp. +-- and connect the 2 zombie chow's search spells to a unique spell script used by both. +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_gluth_decimate', 'spell_gluth_zombiechow_search'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(28374, 'spell_gluth_decimate'), +(54426, 'spell_gluth_decimate'), +(28239, 'spell_gluth_zombiechow_search'), +(28404, 'spell_gluth_zombiechow_search'); + +-- add the condition to the multi-target insta-kill spell 28404 which is that only zombies are eligible targets to the spell. +-- add a condition to the decimate spell (28374/54426). It's damage component should only affect players and zombies. +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 13 AND `SourceEntry` IN (28374, 28404, 54426); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 28404, 0, 0, 31, 0, 3, 16360, 0, 0, 0, 0, '', 'Zombie Chow Search targets zombies only'), +(13, 1, 28374, 0, 0, 31, 0, 3, 16360, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'), +(13, 1, 28374, 0, 1, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'), +(13, 1, 54426, 0, 0, 31, 0, 3, 16360, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'), +(13, 1, 54426, 0, 1, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Decimate damage should only hit zombie or player'); + +-- adds Gluth's 5 emotes into the DB. +DELETE FROM `creature_text` WHERE `entry`=15932 AND `groupid` IN(0,1,2,3,4) AND `id`=0; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(15932, 0, 0, '%s spots a zombie to devour!', 16, 0, 100, 0, 0, 0, 12242, 2/3, 'Gluth - spots one'), +(15932, 1, 0, '%s decimates all nearby flesh!', 41, 0, 100, 0, 0, 0, 32321, 2/3, 'Gluth - decimate'), +(15932, 2, 0, '%s becomes enraged!', 41, 0, 100, 0, 0, 0, 24144, 2/3, 'Gluth - enrage'), +(15932, 3, 0, '%s devours all nearby zombies!', 16, 0, 100, 0, 0, 0, 12348, 2/3, 'Gluth - devours all'), +(15932, 4, 0, '%s goes into a berserker rage!', 41, 0, 100, 0, 0, 0, 34057, 2/3, 'Gluth - berserker'); + +-- move zombie chows to summon groups (gets rid of hardcoded spawn coords) +DELETE FROM `creature_summon_groups` WHERE `summonerId`=15932; +INSERT INTO `creature_summon_groups` (`summonerId`,`summonerType`,`groupId`,`entry`,`position_x`,`position_y`,`position_z`,`orientation`,`summonType`,`summonTime`) VALUES +(15932,0,1,16360,3270.132,-3169.948,297.5891,5.88176,6,10000), +(15932,0,2,16360,3307.298,-3183.449,297.5891,5.74213,6,10000), +(15932,0,2,16360,3255.708,-3135.677,297.5891,1.86750,6,10000); diff --git a/sql/updates/world/3.3.5/2016_04_16_03_world.sql b/sql/updates/world/3.3.5/2016_04_16_03_world.sql new file mode 100644 index 00000000000..c6a6e1b07de --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_16_03_world.sql @@ -0,0 +1,2 @@ +UPDATE `npc_spellclick_spells` SET `spell_id`=46598 WHERE `npc_entry`=31583 and`spell_id`=59319; +UPDATE `smart_scripts` SET `action_param2`=2 WHERE `entryorguid`=31578 and`source_type`=0 and`id`=3; diff --git a/sql/updates/world/3.3.5/2016_04_16_04_world.sql b/sql/updates/world/3.3.5/2016_04_16_04_world.sql new file mode 100644 index 00000000000..75d241b62f4 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_16_04_world.sql @@ -0,0 +1,33 @@ +-- new gossip_menu_option and creature text entries for: +-- NPC ID 18538 Ishanah, High Priestess of the Aldor +-- NPC ID 18584 Sal'salabim, quest giver +-- NPC ID 18585 Raliq the Drunk, target +-- NPC ID 25967 Zephyr, portal provider + +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (7725,7729,7735,9205); +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`OptionBroadcastTextID`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`,`BoxBroadcastTextID`) VALUES +(7725,0,0,'Altruis sent me. He said that you could help me.', 15552,1,1, 0,0,0,0,'',0), +(7729,0,0,"I have been sent by Sal'salabim to collect a debt that you owe. Pay up or I'm going to have to hurt you.",15560,1,1,0,0,0,0,'',0), +(7735,0,0,"Who are the Sha'tar?", 15642,1,1,7736,0,0,0,'',0), +(7735,1,0,"Isn't Shattrath a draenei city? Why do you allow others here?",15644,1,1,7737,0,0,0,'',0), +(9205,0,0,'Take me to the Caverns of Time.', 25111,1,1, 0,0,0,0,'',0); + +-- conditions for the gossip menu options as a preparation for future SAI scripts +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 15 AND `SourceGroup` IN (7725,7729); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15, 7725,0, 0,0, 9,0, 10004,0,0,0,0,0,'', 'Show gossip menu option 7725 only if Quest 10004 is taken (active)'), +(15, 7729,0, 0,0, 9,0, 10009,0,0,0,0,0,'', 'Show gossip menu option 7729 only if Quest 10009 is taken (active)'); + +-- insert missing creature text (say lines) for Sal'salabim and Raliq the Drunk +DELETE FROM `creature_text` WHERE `entry` IN (18584,18585) AND `groupid`= 0; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(18584,0,0,'[Demonic] Ka kalix!', 12,0,100,0,0,0,15551,0,"Sal'salabim SAY_DEMONIC_AGGRO"), +(18585,0,0,'Raliq teach you lesson now!',12,0,100,0,0,0,15567,0,'Raliq the Drunk SAY_RALIQ_ATTACK'); + +-- insert missing quest Progress gossip, quest 10004 +DELETE FROM `quest_request_items` WHERE `ID` = 10004; +INSERT INTO `quest_request_items` (`ID`,`EmoteOnComplete`,`EmoteOnIncomplete`,`CompletionText`,`VerifiedBuild`) VALUES +(10004,0,0,"<Sal'salabim rubs his head.>$B$B[Demonic] Ik il romath sardon.",0); + +-- remove core script for Ishanah, High Priestess of the Aldor +UPDATE `creature_template` SET `ScriptName`= '' WHERE `entry`= 18538; diff --git a/sql/updates/world/3.3.5/2016_04_17_00_world.sql b/sql/updates/world/3.3.5/2016_04_17_00_world.sql new file mode 100644 index 00000000000..ebfbdb1d008 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_17_00_world.sql @@ -0,0 +1,2 @@ +-- +UPDATE `creature_template` SET `exp`=0 WHERE `entry` IN (33432, 34106); diff --git a/sql/updates/world/3.3.5/2016_04_17_01_world.sql b/sql/updates/world/3.3.5/2016_04_17_01_world.sql new file mode 100644 index 00000000000..f57f73c925d --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_17_01_world.sql @@ -0,0 +1,3 @@ +-- +UPDATE `gameobject` SET `spawntimesecs` = 10 WHERE `id` IN (148499, 178084, 178085, 176785); +UPDATE `gameobject` SET `spawntimesecs` = 2 WHERE `id` IN (190447, 759); diff --git a/sql/updates/world/3.3.5/2016_04_17_02_world.sql b/sql/updates/world/3.3.5/2016_04_17_02_world.sql new file mode 100644 index 00000000000..e63928925df --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_17_02_world.sql @@ -0,0 +1,7 @@ +-- +-- Rework Scourge Deathspeaker SAI +DELETE FROM `smart_scripts` WHERE `entryorguid`=27615 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 +(27615, 0, 0, 0, 1, 0, 100, 0, 1000, 1000, 0, 0, 11, 49119, 2, 0, 0, 0, 0, 10, 101497, 27452, 0, 0, 0, 0, 0, 'Scourge Deathspeaker - Out of Combat - Cast \'Fire Beam\' (Triggered)'), +(27615, 0, 1, 0, 4, 0, 100, 0, 0, 0, 0, 0, 11, 52281, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Scourge Deathspeaker - On Aggro - Cast \'Flame of the Seer\' (No Repeat)'), +(27615, 0, 2, 0, 0, 0, 100, 0, 1000, 2000, 5000, 6000, 11, 52282, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Scourge Deathspeaker - In Combat - Cast \'Fireball\''); diff --git a/sql/updates/world/3.3.5/2016_04_17_03_world.sql b/sql/updates/world/3.3.5/2016_04_17_03_world.sql new file mode 100644 index 00000000000..3dc63f55637 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_17_03_world.sql @@ -0,0 +1,6 @@ +-- +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=27547; +DELETE FROM `smart_scripts` WHERE `entryorguid`=27547 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 +(27547, 0, 0, 1, 2, 0, 100, 0, 0, 40, 9000, 9000, 11, 32714, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vladek - In HPCT - Cast \'Enrage\''), +(27547, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 11, 47457, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Vladek - In HPCT - Cast Worgen Transform - Male'); diff --git a/sql/updates/world/3.3.5/2016_04_17_04_world.sql b/sql/updates/world/3.3.5/2016_04_17_04_world.sql new file mode 100644 index 00000000000..c03969b14b3 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_17_04_world.sql @@ -0,0 +1,27 @@ +-- +-- Quest Bring 'Em Back Alive +UPDATE `creature_template_addon` SET `auras`=45771 WHERE `entry`=25596; +UPDATE `creature_template` SET `spell1`=45876, `spell2`=45877 WHERE `entry`=25596; +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=25607; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (25596, 25607) AND `source_type`=0; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (22560700) 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 +(25596, 0, 0, 0, 0, 0, 100, 0, 10000, 12000, 20000, 22000, 11, 45876, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - In Combat - Cast \'Stampede\''), +(25596, 0, 1, 0, 4, 0, 100, 0, 0, 0, 0, 0, 91, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Aggro - Remove Flag Standstate Dead'), +(25596, 0, 2, 3, 27, 0, 100, 0, 0, 0, 0, 0, 91, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Passenger Boarded - Remove Flag Standstate Dead'), +(25596, 0, 3, 4, 61, 0, 100, 1, 0, 0, 0, 0, 28, 45771, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Link - Remove Aura \'Scourge Infection\' (No Repeat)'), +(25596, 0, 4, 0, 61, 0, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Link - Remove Aura \'Scourge Infection\' (No Repeat)'), +(25596, 0, 5, 6, 31, 0, 100, 0, 45877, 0, 0, 0, 11, 50630, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Target Spell Hit \'Deliver Kodo\' - Eject passenger'), +(25596, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 19, 25607, 20, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Target Spell Hit \'Deliver Kodo\' - Set data'), +(25596, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Infected Kodo Beast - On Target Spell Hit \'Deliver Kodo\' - Despawn Instant'), +(25607, 0, 0, 0, 38, 0, 100, 0, 0, 1, 3000, 3000, 80, 2560700, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Farmer Torp - In Data set - Action list'), +(2560700, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 21, 20, 0, 0, 0, 0, 0, 0, 'Farmer Torp - Action list - Player talk'), +(2560700, 9, 1, 0, 0, 0, 100, 0, 3000, 3000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Farmer Torp - Action list - Say text'); + +DELETE FROM `creature_text` WHERE `entry` IN (25607, 25596); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`probability`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(25607,0,0,"Here's your kodo, Torp!",12,100,24881,0,"Farmer Torp"), +(25607,0,1,"Door-to-door kodo delivery!",12,100,24882,0,"Farmer Torp"), +(25607,1,0,"YES! It worked!",12,100,24883,0,"Farmer Torp"), +(25607,1,1,"Great job!",12,100,24884,0,"Farmer Torp"), +(25596,0,0,"%s is cured!",16,100,24885,0,"Infected Kodo Beast"); diff --git a/sql/updates/world/3.3.5/2016_04_20_00_world.sql b/sql/updates/world/3.3.5/2016_04_20_00_world.sql new file mode 100644 index 00000000000..776254b8fb9 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_20_00_world.sql @@ -0,0 +1,7 @@ +-- +-- Add missing Gnomeregan Conjuror/Silvermoon Magister SAI (Cosmetic) +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (19006, 19007); +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (19006, 19007) 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 +(19006, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 11, 32783, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Silvermoon Magister - On Reset - Cast \'Arcane Channeling\''), +(19007, 0, 0, 0, 25, 0, 100, 0, 0, 0, 0, 0, 11, 32783, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gnomeregan Conjuror - On Reset - Cast \'Arcane Channeling\''); diff --git a/sql/updates/world/3.3.5/2016_04_20_01_world.sql b/sql/updates/world/3.3.5/2016_04_20_01_world.sql new file mode 100644 index 00000000000..19bd02a91f5 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_20_01_world.sql @@ -0,0 +1,5 @@ +-- +-- Hairy Herring Heads, Withered Batwings, Wasp's Wings, Muddy Mire Maggots, Knotroot, Spekled Guano, Seasoned Slider Cider, Pickled Eagle Egg, Prismatic Mojo, Raptor Claw +-- Pulverized Gargoyle Teeth, Icerown Bottled Water, Putrid Pirate Perspiration, Spiky Spider Eggs, Abomination Guts, Amberseed, Shrunken Dragom's Claw, Crystallized Hogsnot +-- Ancient Ectoplasm, Chrushed Basilisk Crystals, Blight Crystal, Frozen Spider Ichor, Trollbane, Ghoul Drool, +UPDATE `gameobject` SET `spawntimesecs` = 0 WHERE `id` IN (190459,190461,190462,190463,190464,190465,190466,190467,190468,190469,190470,190471,190472,190473,190474,190476,190477,190478,190479,190480,190481,190482,191180,191181,191182); diff --git a/sql/updates/world/3.3.5/2016_04_20_02_world.sql b/sql/updates/world/3.3.5/2016_04_20_02_world.sql new file mode 100644 index 00000000000..743f1fdab50 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_20_02_world.sql @@ -0,0 +1,89 @@ +-- +DELETE FROM `creature_addon` WHERE `guid` IN (202936, 202878, 202950, 202931, 202875, 202884, 202914, 202925, 202934, 202944, 202879, 202945, 202898, 202910, 202912, 202909, 202870, 202949, 202903, 202920, 202922, 202924, 202926, 202939, 202888, 202940, 202882, 202947, 202897, 202937, 202915, 202929, 202935, 202872, 202887, 202942, 202948, 202896, 202900, 202916, 202886, 202923, 202894, 202927, 202913, 202906, 202876, 202941, 202881, 202890, 202907, 202904, 202874, 202880, 202877, 202905, 202873, 202908, 202946, 202917, 202928, 202932, 202943, 202883, 202895, 202951, 202901, 202911, 202885, 202899, 202933, 202868, 202938, 202919, 202921, 202918, 202893, 202891, 202889, 202866, 202871, 202892, 202930, 202902, 202869, 202867); +INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES +(202936, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202878, 0, 0, 0, 1, 0, '66321 55944 66370'), -- Tauren Coliseum Spectator +(202950, 0, 0, 0, 1, 0, '66321 55944 66361'), -- Argent Crusade Spectator, 66361 - Argent Crusade Pennant +(202931, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Draenei +(202875, 0, 0, 0, 1, 0, '66321 55944'), -- Troll Coliseum Spectator +(202884, 0, 0, 0, 1, 0, '66321 55944 66369'), -- Orcish Coliseum Spectator +(202914, 0, 0, 0, 1, 0, '66321 55944'), -- Human Coliseum Spectator +(202925, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Orc +(202934, 0, 0, 0, 1, 0, '66321 55944 66361'), -- Argent Crusade Spectator +(202944, 0, 0, 0, 1, 0, '66321 55944 66361'), -- Argent Crusade Spectator +(202879, 0, 0, 0, 1, 0, '66321 55944 66370'), -- Tauren Coliseum Spectator +(202945, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202898, 0, 0, 0, 1, 0, '66321 55944'), -- Blood Elf Coliseum Spectator +(202910, 0, 0, 0, 1, 0, '66321 55944 66366'), -- Gnomish Coliseum Spectator +(202912, 0, 0, 0, 1, 0, '66321 55944'), -- Human Coliseum Spectator +(202909, 0, 0, 0, 1, 0, '66321 55944'), -- Gnomish Coliseum Spectator +(202870, 0, 0, 0, 1, 0, '66321 55944'), -- Dwarven Coliseum Spectator +(202949, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202903, 0, 0, 0, 1, 0, '66321 55944 66362'), -- Draenei Coliseum Spectator +(202920, 0, 0, 0, 1, 0, '66321 55944'), -- Night Elf Coliseum Spectator +(202922, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Horde +(202924, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Human +(202926, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Troll +(202939, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202888, 0, 0, 0, 1, 0, '66321 55944'), -- Orcish Coliseum Spectator +(202940, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202882, 0, 0, 0, 1, 0, '66321 55944'), -- Tauren Coliseum Spectator +(202947, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202897, 0, 0, 0, 1, 0, '66321 55944 66360'), -- Blood Elf Coliseum Spectator, 66360 - Silvermoon Pennant +(202937, 0, 0, 0, 1, 0, '66321 55944 66361'), -- Argent Crusade Spectator +(202915, 0, 0, 0, 1, 0, '66321 55944 66367'), -- Human Coliseum Spectator +(202929, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Undead +(202935, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202872, 0, 0, 0, 1, 0, '66321 55944 66371'), -- Troll Coliseum Spectator +(202887, 0, 0, 0, 1, 0, '66321 55944'), -- Orcish Coliseum Spectator +(202942, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202948, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202896, 0, 0, 0, 1, 0, '66321 55944'), -- Blood Elf Coliseum Spectator +(202900, 0, 0, 0, 1, 0, '66321 55944'), -- Draenei Coliseum Spectator +(202916, 0, 0, 0, 1, 0, '66321 55944 66367'), -- Human Coliseum Spectator +(202886, 0, 0, 0, 1, 0, '66321 55944'), -- Orcish Coliseum Spectator +(202923, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Alliance +(202894, 0, 0, 0, 1, 0, '66321 55944 66360'), -- Blood Elf Coliseum Spectator +(202927, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Tauren +(202913, 0, 0, 0, 1, 0, '66321 55944'), -- Human Coliseum Spectator +(202906, 0, 0, 0, 1, 0, '66321 55944'), -- Gnomish Coliseum Spectator +(202876, 0, 0, 0, 1, 0, '66321 55944'), -- Troll Coliseum Spectator +(202941, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202881, 0, 0, 0, 1, 0, '66321 55944'), -- Tauren Coliseum Spectator +(202890, 0, 0, 0, 1, 0, '66321 55944 66365'), -- Forsaken Coliseum Spectator +(202907, 0, 0, 0, 1, 0, '66321 55944 66366'), -- Gnomish Coliseum Spectator +(202904, 0, 0, 0, 1, 0, '66321 55944 66362'), -- Draenei Coliseum Spectator +(202874, 0, 0, 0, 1, 0, '66321 55944'), -- Troll Coliseum Spectator +(202880, 0, 0, 0, 1, 0, '66321 55944'), -- Tauren Coliseum Spectator +(202877, 0, 0, 0, 1, 0, '66321 55944 66371'), -- Troll Coliseum Spectator, 66371 - Sen'jin Pennant +(202905, 0, 0, 0, 1, 0, '66321 55944'), -- Gnomish Coliseum Spectator +(202873, 0, 0, 0, 1, 0, '66321 55944 66371'), -- Troll Coliseum Spectator +(202908, 0, 0, 0, 1, 0, '66321 55944 66366'), -- Gnomish Coliseum Spectator +(202946, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202917, 0, 0, 0, 1, 0, '66321 55944'), -- Night Elf Coliseum Spectator +(202928, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Blood Elf +(202932, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Night Elf +(202943, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202883, 0, 0, 0, 1, 0, '66321 55944 66369'), -- Orcish Coliseum Spectator +(202895, 0, 0, 0, 1, 0, '66321 55944 66360'), -- Blood Elf Coliseum Spectator +(202951, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202901, 0, 0, 0, 1, 0, '66321 55944 66362'), -- Draenei Coliseum Spectator +(202911, 0, 0, 0, 1, 0, '66321 55944'), -- Human Coliseum Spectator +(202885, 0, 0, 0, 1, 0, '66321 55944'), -- Orcish Coliseum Spectator +(202899, 0, 0, 0, 1, 0, '66321 55944'), -- Blood Elf Coliseum Spectator +(202933, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Gnome +(202868, 0, 0, 0, 1, 0, '66321 55944 66363'), -- Dwarven Coliseum Spectator, 66363 - Ironforge Pennant +(202938, 0, 0, 0, 1, 0, '66321 55944'), -- Argent Crusade Spectator +(202919, 0, 0, 0, 1, 0, '66321 55944 66368'), -- Night Elf Coliseum Spectator, 66368 - Darnassus Pennant +(202921, 0, 0, 0, 1, 0, '66321 55944 66368'), -- Night Elf Coliseum Spectator +(202918, 0, 0, 0, 1, 0, '66321 55944'), -- Night Elf Coliseum Spectator +(202893, 0, 0, 0, 1, 0, '66321 55944'), -- Forsaken Coliseum Spectator +(202891, 0, 0, 0, 1, 0, '66321 55944'), -- Forsaken Coliseum Spectator +(202889, 0, 0, 0, 1, 0, '66321 55944 66365'), -- Forsaken Coliseum Spectator +(202866, 0, 0, 0, 1, 0, '66321 55944 66363'), -- Dwarven Coliseum Spectator, 66363 - Ironforge Pennant +(202871, 0, 0, 0, 1, 0, '66321 55944 66363'), -- Dwarven Coliseum Spectator +(202892, 0, 0, 0, 1, 0, '66321 55944 66365'), -- Forsaken Coliseum Spectator, 66365 - Undercity Pennant +(202930, 0, 0, 0, 1, 0, '66321 55944'), -- [ph] Argent Raid Spectator - FX - Dwarf +(202902, 0, 0, 0, 1, 0, '66321 55944'), -- Draenei Coliseum Spectator +(202869, 0, 0, 0, 1, 0, '66321 55944'), -- Dwarven Coliseum Spectator +(202867, 0, 0, 0, 1, 0, '66321 55944'); -- Dwarven Coliseum Spectator diff --git a/sql/updates/world/3.3.5/2016_04_20_03_world.sql b/sql/updates/world/3.3.5/2016_04_20_03_world.sql new file mode 100644 index 00000000000..11fc8de7329 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_20_03_world.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (27435) AND `source_type`=0 AND `id`=2; +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 +(27435, 0, 2, 0, 63, 0, 100, 0, 0, 0, 0, 0, 18, 512, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Wintergarde Mine Bomb - Just created - Set immune to NPC'); diff --git a/sql/updates/world/3.3.5/2016_04_22_00_world.sql b/sql/updates/world/3.3.5/2016_04_22_00_world.sql new file mode 100644 index 00000000000..e98ef9cf7e6 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_22_00_world.sql @@ -0,0 +1,20 @@ +DELETE FROM `smart_scripts` WHERE `entryorguid`=2964700 AND `source_type`=9; +DELETE FROM `smart_scripts` WHERE `entryorguid`IN(29647,29884) 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 +(29647, 0, 0, 1, 62, 0, 100, 0, 9852, 2, 0, 0, 72, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Gossip Option 2 Selected - Close Gossip'), -- 21:50:33.764 +(29647, 0, 1, 2, 61, 0, 100, 0, 0, 0, 0, 0, 11, 55568, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Gossip Option 2 Selected - Cast Summon Gymer (Force)'), -- 21:50:33.967 +(29647, 0, 4, 0, 1, 0, 100, 0, 10000, 20000, 30000, 40000, 1, 1, 5000, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - Out of Combat - Say Line 1'), +(29647, 0, 5, 0, 20, 0, 100, 0, 12916, 0, 0, 0, 1, 7, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Quest reward - Say Line 7'), +(29884, 0, 0, 1, 54, 0, 100, 0, 0, 0, 0, 0, 86, 55430, 2, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Just Summoned - Cast Gymers Buddy'), -- 21:50:35.090 +(29884, 0, 1, 0, 61, 0, 100, 1, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Just Summoned - Set Passive'), +(29884, 0, 2, 3, 27, 0, 100, 1, 0, 0, 0, 0, 44, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Passenger Boarded - Set Phase 256'), +(29884, 0, 3, 0, 61, 0, 100, 1, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Passenger Boarded - Say Line 8 (No Repeat)'), +(29884, 0, 4, 0, 61, 0, 100, 1, 0, 0, 0, 0, 11, 55461, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Passenger Boarded - Cast Storms Fury'), +(29884, 0, 5, 6, 28, 0, 100, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Passenger Removed - Set Phase 1'), +(29884, 0, 6, 7, 61, 0, 100, 0, 0, 0, 0, 0, 1, 10, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Passenger Removed - Say Line 10'), +(29884, 0, 7, 0, 61, 0, 100, 0, 0, 0, 0, 0, 41, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 'Gymer - On Passenger Removed - Despawn after 5 seconds'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceEntry`=29884; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 6, 29884, 0, 0, 31, 0, 4, 0, 0, 0, 0, 0, '', 'Gymer only despawns if player leaves vehicle (not if mob thrown)'); diff --git a/sql/updates/world/3.3.5/2016_04_23_00_world.sql b/sql/updates/world/3.3.5/2016_04_23_00_world.sql new file mode 100644 index 00000000000..fe5d5c7ccb6 --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_23_00_world.sql @@ -0,0 +1,7 @@ +-- +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=19 AND (`SourceEntry`=11586 OR `SourceEntry`=11585); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceEntry`,`ConditionTypeOrReference`,`ConditionValue1`,`Comment`) VALUES +(19, 11585, 14, 10172, "Accept quest 11585 - Quest 10172 needs to be incomplete"), +(19, 11586, 8, 10172, "Accept quest 11586 - Quest 10172 needs to be rewarded"); + +UPDATE `quest_template_addon` SET `ExclusiveGroup`=11585 WHERE `ID`IN(11585,11586); diff --git a/sql/updates/world/3.3.5/2016_04_23_01_world.sql b/sql/updates/world/3.3.5/2016_04_23_01_world.sql new file mode 100644 index 00000000000..d1be7adacfc --- /dev/null +++ b/sql/updates/world/3.3.5/2016_04_23_01_world.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_item_decahedral_dwarven_dice', 'spell_item_worn_troll_dice'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(47770, 'spell_item_decahedral_dwarven_dice'), +(47776, 'spell_item_worn_troll_dice'); diff --git a/sql/updates/world/dummy b/sql/updates/world/3.3.5/dummy index e69de29bb2d..e69de29bb2d 100644 --- a/sql/updates/world/dummy +++ b/sql/updates/world/3.3.5/dummy diff --git a/src/common/Configuration/Config.cpp b/src/common/Configuration/Config.cpp index ddaab7dee61..888aa6ecef3 100644 --- a/src/common/Configuration/Config.cpp +++ b/src/common/Configuration/Config.cpp @@ -25,11 +25,13 @@ using namespace boost::property_tree; -bool ConfigMgr::LoadInitial(std::string const& file, std::string& error) +bool ConfigMgr::LoadInitial(std::string const& file, std::vector<std::string> args, + std::string& error) { std::lock_guard<std::mutex> lock(_configLock); _filename = file; + _args = args; try { @@ -65,7 +67,7 @@ ConfigMgr* ConfigMgr::instance() bool ConfigMgr::Reload(std::string& error) { - return LoadInitial(_filename, error); + return LoadInitial(_filename, std::move(_args), error); } template<class T> diff --git a/src/common/Configuration/Config.h b/src/common/Configuration/Config.h index 10113cd88d3..573bc7b4a15 100644 --- a/src/common/Configuration/Config.h +++ b/src/common/Configuration/Config.h @@ -23,6 +23,7 @@ #include <string> #include <list> +#include <vector> #include <mutex> #include <boost/property_tree/ptree.hpp> @@ -35,7 +36,8 @@ class TC_COMMON_API ConfigMgr public: /// Method used only for loading main configuration files (authserver.conf and worldserver.conf) - bool LoadInitial(std::string const& file, std::string& error); + bool LoadInitial(std::string const& file, std::vector<std::string> args, + std::string& error); static ConfigMgr* instance(); @@ -47,10 +49,12 @@ public: float GetFloatDefault(std::string const& name, float def) const; std::string const& GetFilename(); + std::vector<std::string> const& GetArguments() const { return _args; } std::list<std::string> GetKeysByString(std::string const& name); private: std::string _filename; + std::vector<std::string> _args; boost::property_tree::ptree _config; std::mutex _configLock; diff --git a/src/common/Cryptography/SHA1.cpp b/src/common/Cryptography/SHA1.cpp index a01bd7844ee..aed4a069827 100644 --- a/src/common/Cryptography/SHA1.cpp +++ b/src/common/Cryptography/SHA1.cpp @@ -18,6 +18,7 @@ #include "SHA1.h" #include "BigNumber.h" +#include "Util.h" #include <cstring> #include <stdarg.h> @@ -67,3 +68,10 @@ void SHA1Hash::Finalize(void) SHA1_Final(mDigest, &mC); } +std::string CalculateSHA1Hash(std::string const& content) +{ + unsigned char digest[SHA_DIGEST_LENGTH]; + SHA1((unsigned char*)content.c_str(), content.length(), (unsigned char*)&digest); + + return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); +} diff --git a/src/common/Cryptography/SHA1.h b/src/common/Cryptography/SHA1.h index 970ab5c0cb9..37ac2cc0166 100644 --- a/src/common/Cryptography/SHA1.h +++ b/src/common/Cryptography/SHA1.h @@ -46,5 +46,8 @@ class TC_COMMON_API SHA1Hash SHA_CTX mC; uint8 mDigest[SHA_DIGEST_LENGTH]; }; -#endif +/// Returns the SHA1 hash of the given content as hex string. +TC_COMMON_API std::string CalculateSHA1Hash(std::string const& content); + +#endif diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index a53187ad737..1392900fb9a 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -36,12 +36,14 @@ #include "GitRevision.h" #include "Util.h" #include <iostream> +#include <boost/filesystem/path.hpp> #include <boost/program_options.hpp> #include <openssl/opensslv.h> #include <openssl/crypto.h> using boost::asio::ip::tcp; using namespace boost::program_options; +namespace fs = boost::filesystem; #ifndef _TRINITY_REALM_CONFIG # define _TRINITY_REALM_CONFIG "authserver.conf" @@ -69,7 +71,7 @@ void StopDB(); void SignalHandler(const boost::system::error_code& error, int signalNumber); void KeepDatabaseAliveHandler(const boost::system::error_code& error); void BanExpiryHandler(boost::system::error_code const& error); -variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService); +variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, std::string& configService); boost::asio::io_service* _ioService; boost::asio::deadline_timer* _dbPingTimer; @@ -81,7 +83,7 @@ int main(int argc, char** argv) { signal(SIGABRT, &Trinity::AbortHandler); - std::string configFile = _TRINITY_REALM_CONFIG; + auto configFile = fs::absolute(_TRINITY_REALM_CONFIG); std::string configService; auto vm = GetConsoleArguments(argc, argv, configFile, configService); // exit if help or version is enabled @@ -98,7 +100,9 @@ int main(int argc, char** argv) #endif std::string configError; - if (!sConfigMgr->LoadInitial(configFile, configError)) + if (!sConfigMgr->LoadInitial(configFile.generic_string(), + std::vector<std::string>(argv, argv + argc), + configError)) { printf("Error in config file: %s\n", configError.c_str()); return 1; @@ -109,7 +113,7 @@ int main(int argc, char** argv) TC_LOG_INFO("server.authserver", "%s (authserver)", GitRevision::GetFullVersion()); TC_LOG_INFO("server.authserver", "<Ctrl-C> to stop.\n"); - TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile.c_str()); + TC_LOG_INFO("server.authserver", "Using configuration file %s.", sConfigMgr->GetFilename().c_str()); TC_LOG_INFO("server.authserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); TC_LOG_INFO("server.authserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); @@ -286,13 +290,14 @@ void ServiceStatusWatcher(boost::system::error_code const& error) } #endif -variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService) +variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, std::string& configService) { options_description all("Allowed options"); all.add_options() ("help,h", "print usage message") ("version,v", "print version build info") - ("config,c", value<std::string>(&configFile)->default_value(_TRINITY_REALM_CONFIG), "use <arg> as configuration file") + ("config,c", value<fs::path>(&configFile)->default_value(fs::absolute(_TRINITY_REALM_CONFIG)), + "use <arg> as configuration file") ; #if PLATFORM == PLATFORM_WINDOWS options_description win("Windows platform specific options"); diff --git a/src/server/authserver/Server/AuthSession.cpp b/src/server/authserver/Server/AuthSession.cpp index f044e0cea94..43c327ffda1 100644 --- a/src/server/authserver/Server/AuthSession.cpp +++ b/src/server/authserver/Server/AuthSession.cpp @@ -820,41 +820,6 @@ bool AuthSession::HandleReconnectProof() } } -tcp::endpoint const GetAddressForClient(Realm const& realm, ip::address const& clientAddr) -{ - ip::address realmIp; - - // Attempt to send best address for client - if (clientAddr.is_loopback()) - { - // Try guessing if realm is also connected locally - if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback()) - realmIp = clientAddr; - else - { - // Assume that user connecting from the machine that authserver is located on - // has all realms available in his local network - realmIp = realm.LocalAddress; - } - } - else - { - if (clientAddr.is_v4() && - (clientAddr.to_v4().to_ulong() & realm.LocalSubnetMask.to_v4().to_ulong()) == - (realm.LocalAddress.to_v4().to_ulong() & realm.LocalSubnetMask.to_v4().to_ulong())) - { - realmIp = realm.LocalAddress; - } - else - realmIp = realm.ExternalAddress; - } - - tcp::endpoint endpoint(realmIp, realm.Port); - - // Return external IP - return endpoint; -} - bool AuthSession::HandleRealmList() { TC_LOG_DEBUG("server.authserver", "Entering _HandleRealmList"); diff --git a/src/server/database/Updater/UpdateFetcher.cpp b/src/server/database/Updater/UpdateFetcher.cpp index 6f67867c52b..7dc0a307ca2 100644 --- a/src/server/database/Updater/UpdateFetcher.cpp +++ b/src/server/database/Updater/UpdateFetcher.cpp @@ -18,6 +18,7 @@ #include "UpdateFetcher.h" #include "Log.h" #include "Util.h" +#include "SHA1.h" #include <fstream> #include <chrono> @@ -25,7 +26,6 @@ #include <sstream> #include <exception> #include <unordered_map> -#include <openssl/sha.h> using namespace boost::filesystem; @@ -209,9 +209,8 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks, } } - // Calculate hash - std::string const hash = - CalculateHash(ReadSQLUpdate(availableQuery.first)); + // Calculate a Sha1 hash based on query content. + std::string const hash = CalculateSHA1Hash(ReadSQLUpdate(availableQuery.first)); UpdateMode mode = MODE_APPLY; @@ -334,15 +333,6 @@ UpdateResult UpdateFetcher::Update(bool const redundancyChecks, return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates); } -std::string UpdateFetcher::CalculateHash(std::string const& query) const -{ - // Calculate a Sha1 hash based on query content. - unsigned char digest[SHA_DIGEST_LENGTH]; - SHA1((unsigned char*)query.c_str(), query.length(), (unsigned char*)&digest); - - return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); -} - uint32 UpdateFetcher::Apply(Path const& path) const { using Time = std::chrono::high_resolution_clock; diff --git a/src/server/database/Updater/UpdateFetcher.h b/src/server/database/Updater/UpdateFetcher.h index a17658818ce..cabc3c2fce3 100644 --- a/src/server/database/Updater/UpdateFetcher.h +++ b/src/server/database/Updater/UpdateFetcher.h @@ -112,7 +112,6 @@ private: AppliedFileStorage ReceiveAppliedFiles() const; std::string ReadSQLUpdate(Path const& file) const; - std::string CalculateHash(std::string const& query) const; uint32 Apply(Path const& path) const; diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index bbf4f4e02ce..68554722db6 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -245,9 +245,9 @@ void PetAI::UpdateAI(uint32 diff) } // Update speed as needed to prevent dropping too far behind and despawning - me->UpdateSpeed(MOVE_RUN, true); - me->UpdateSpeed(MOVE_WALK, true); - me->UpdateSpeed(MOVE_FLIGHT, true); + me->UpdateSpeed(MOVE_RUN); + me->UpdateSpeed(MOVE_WALK); + me->UpdateSpeed(MOVE_FLIGHT); } diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp index 5acb56b5173..17b104eb388 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -582,13 +582,13 @@ void AuctionBotSeller::LoadSellerValues(SellerConfiguration& config) break; } - config.SetPriceRatioPerQuality(AUCTION_QUALITY_GRAY, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO) / 100); - config.SetPriceRatioPerQuality(AUCTION_QUALITY_WHITE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO) / 100); - config.SetPriceRatioPerQuality(AUCTION_QUALITY_GREEN, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO) / 100); - config.SetPriceRatioPerQuality(AUCTION_QUALITY_BLUE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO) / 100); - config.SetPriceRatioPerQuality(AUCTION_QUALITY_PURPLE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO) / 100); - config.SetPriceRatioPerQuality(AUCTION_QUALITY_ORANGE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO) / 100); - config.SetPriceRatioPerQuality(AUCTION_QUALITY_YELLOW, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_GRAY, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO)); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_WHITE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO)); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_GREEN, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO)); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_BLUE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO)); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_PURPLE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO)); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_ORANGE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO)); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_YELLOW, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO)); config.SetPriceRatioPerClass(ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO)); config.SetPriceRatioPerClass(ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO)); @@ -701,10 +701,10 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf { uint32 classRatio = config.GetPriceRatioPerClass(ItemClass(itemProto->Class)); uint32 qualityRatio = config.GetPriceRatioPerQuality(AuctionQuality(itemProto->Quality)); - uint32 priceRatio = (classRatio * qualityRatio) / 100; + float priceRatio = (classRatio * qualityRatio) / 10000.0f; - uint32 buyPrice = itemProto->BuyPrice; - uint32 sellPrice = itemProto->SellPrice; + float buyPrice = itemProto->BuyPrice; + float sellPrice = itemProto->SellPrice; if (buyPrice == 0) { @@ -712,11 +712,11 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf buyPrice = sellPrice * GetSellModifier(itemProto); else { - uint32 divisor = ((itemProto->Class == 2 || itemProto->Class == 4) ? 284 : 80); - uint32 tempLevel = (itemProto->ItemLevel == 0 ? 1 : itemProto->ItemLevel); - uint32 tempQuality = (itemProto->Quality == 0 ? 1 : itemProto->Quality); + float divisor = ((itemProto->Class == ITEM_CLASS_WEAPON || itemProto->Class == ITEM_CLASS_ARMOR) ? 284.0f : 80.0f); + float tempLevel = (itemProto->ItemLevel == 0 ? 1.0f : itemProto->ItemLevel); + float tempQuality = (itemProto->Quality == 0 ? 1.0f : itemProto->Quality); - buyPrice = tempLevel * tempQuality * GetBuyModifier(itemProto)* tempLevel / divisor; + buyPrice = tempLevel * tempQuality * static_cast<float>(GetBuyModifier(itemProto))* tempLevel / divisor; } } @@ -726,14 +726,15 @@ void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConf if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_SELLER)) buyPrice = sellPrice; - uint32 basePrice = (buyPrice * stackCount * priceRatio) / (itemProto->Class == 6 ? 200 : itemProto->BuyCount) / 100; - uint32 range = basePrice * 0.04; + float basePriceFloat = (buyPrice * stackCount * priceRatio) / (itemProto->Class == 6 ? 200.0f : static_cast<float>(itemProto->BuyCount)) / 100.0f; + float range = basePriceFloat * 0.04f; - buyp = urand(basePrice - range, basePrice + range) + 1; - - basePrice = buyp * .5; + buyp = static_cast<uint32>(frand(basePriceFloat - range, basePriceFloat + range) + 0.5f); + if (buyp == 0) + buyp = 1; + uint32 basePrice = buyp * .5; range = buyp * .4; - bidp = urand(basePrice - range, basePrice + range) + 1; + bidp = urand(static_cast<uint32>(basePrice - range + 0.5f), static_cast<uint32>(basePrice + range + 0.5f)) + 1; } // Determines the stack size to use for the item diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d5e1e0956b1..d3843c86aa4 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -379,10 +379,10 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); - SetSpeed(MOVE_WALK, cinfo->speed_walk); - SetSpeed(MOVE_RUN, cinfo->speed_run); - SetSpeed(MOVE_SWIM, 1.0f); // using 1.0 rate - SetSpeed(MOVE_FLIGHT, 1.0f); // using 1.0 rate + SetSpeedRate(MOVE_WALK, cinfo->speed_walk); + SetSpeedRate(MOVE_RUN, cinfo->speed_run); + SetSpeedRate(MOVE_SWIM, 1.0f); // using 1.0 rate + SetSpeedRate(MOVE_FLIGHT, 1.0f); // using 1.0 rate // Will set UNIT_FIELD_BOUNDINGRADIUS and UNIT_FIELD_COMBATREACH SetObjectScale(cinfo->scale); @@ -780,7 +780,7 @@ void Creature::DoFleeToGetAssistance() cell.Visit(p, grid_creature_searcher, *GetMap(), *this, radius); SetNoSearchAssistance(true); - UpdateSpeed(MOVE_RUN, false); + UpdateSpeed(MOVE_RUN); if (!creature) //SetFeared(true, EnsureVictim()->GetGUID(), 0, sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY)); @@ -1636,7 +1636,7 @@ void Creature::setDeathState(DeathState s) if (HasSearchedAssistance()) { SetNoSearchAssistance(false); - UpdateSpeed(MOVE_RUN, false); + UpdateSpeed(MOVE_RUN); } //Dismiss group if is leader diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 773d5a05772..a8dad0b2fbc 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -519,41 +519,11 @@ Player* Item::GetOwner()const return ObjectAccessor::FindPlayer(GetOwnerGUID()); } +// Just a "legacy shortcut" for proto->GetSkill() uint32 Item::GetSkill() { - const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] = - { - SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES, - SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0, - SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0, - SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS, - SKILL_FISHING - }; - - const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] = - { - 0, SKILL_CLOTH, SKILL_LEATHER, SKILL_MAIL, SKILL_PLATE_MAIL, 0, SKILL_SHIELD, 0, 0, 0, 0 - }; - ItemTemplate const* proto = GetTemplate(); - - switch (proto->Class) - { - case ITEM_CLASS_WEAPON: - if (proto->SubClass >= MAX_ITEM_SUBCLASS_WEAPON) - return 0; - else - return item_weapon_skills[proto->SubClass]; - - case ITEM_CLASS_ARMOR: - if (proto->SubClass >= MAX_ITEM_SUBCLASS_ARMOR) - return 0; - else - return item_armor_skills[proto->SubClass]; - - default: - return 0; - } + return proto->GetSkill(); } uint32 Item::GetSpell() diff --git a/src/server/game/Entities/Item/ItemPrototype.cpp b/src/server/game/Entities/Item/ItemPrototype.cpp new file mode 100644 index 00000000000..3bb7b128b08 --- /dev/null +++ b/src/server/game/Entities/Item/ItemPrototype.cpp @@ -0,0 +1,121 @@ +/* +* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> +* +* 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/>. +*/ + +#include "ItemPrototype.h" + +bool ItemTemplate::CanChangeEquipStateInCombat() const +{ + switch (InventoryType) + { + case INVTYPE_RELIC: + case INVTYPE_SHIELD: + case INVTYPE_HOLDABLE: + return true; + } + + switch (Class) + { + case ITEM_CLASS_WEAPON: + case ITEM_CLASS_PROJECTILE: + return true; + } + + return false; +} + + +float ItemTemplate::getDPS() const +{ + if (Delay == 0) + return 0; + float temp = 0; + for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) + temp += Damage[i].DamageMin + Damage[i].DamageMax; + return temp * 500 / Delay; +} + + +int32 ItemTemplate::getFeralBonus(int32 extraDPS /*= 0*/) const +{ + // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc + if (Class == ITEM_CLASS_WEAPON && (1 << SubClass) & 0x02A5F3) + { + int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767; + if (bonus < 0) + return 0; + return bonus; + } + return 0; +} + +float ItemTemplate::GetItemLevelIncludingQuality() const +{ + float itemLevel = (float)ItemLevel; + switch (Quality) + { + case ITEM_QUALITY_POOR: + case ITEM_QUALITY_NORMAL: + case ITEM_QUALITY_UNCOMMON: + case ITEM_QUALITY_ARTIFACT: + case ITEM_QUALITY_HEIRLOOM: + itemLevel -= 13; // leaving this as a separate statement since we do not know the real behavior in this case + break; + case ITEM_QUALITY_RARE: + itemLevel -= 13; + break; + case ITEM_QUALITY_EPIC: + case ITEM_QUALITY_LEGENDARY: + default: + break; + } + return std::max<float>(0.f, itemLevel); +} + +uint32 ItemTemplate::GetSkill() const +{ + const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] = + { + SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES, + SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0, + SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0, + SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS, + SKILL_FISHING + }; + + const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] = + { + 0, SKILL_CLOTH, SKILL_LEATHER, SKILL_MAIL, SKILL_PLATE_MAIL, 0, SKILL_SHIELD, 0, 0, 0, 0 + }; + + switch (Class) + { + case ITEM_CLASS_WEAPON: + if (SubClass >= MAX_ITEM_SUBCLASS_WEAPON) + return 0; + else + return item_weapon_skills[SubClass]; + + case ITEM_CLASS_ARMOR: + if (SubClass >= MAX_ITEM_SUBCLASS_ARMOR) + return 0; + else + return item_armor_skills[SubClass]; + + default: + return 0; + } +} diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 48ef9e81016..9b0f4628364 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -664,25 +664,7 @@ struct ItemTemplate uint32 FlagsCu; // helpers - bool CanChangeEquipStateInCombat() const - { - switch (InventoryType) - { - case INVTYPE_RELIC: - case INVTYPE_SHIELD: - case INVTYPE_HOLDABLE: - return true; - } - - switch (Class) - { - case ITEM_CLASS_WEAPON: - case ITEM_CLASS_PROJECTILE: - return true; - } - - return false; - } + bool CanChangeEquipStateInCombat() const; bool IsCurrencyToken() const { return (BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) != 0; } @@ -691,51 +673,13 @@ struct ItemTemplate return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable); } - float getDPS() const - { - if (Delay == 0) - return 0; - float temp = 0; - for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) - temp+=Damage[i].DamageMin + Damage[i].DamageMax; - return temp*500/Delay; - } + float getDPS() const; - int32 getFeralBonus(int32 extraDPS = 0) const - { - // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc - if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3) - { - int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767; - if (bonus < 0) - return 0; - return bonus; - } - return 0; - } + int32 getFeralBonus(int32 extraDPS = 0) const; - float GetItemLevelIncludingQuality() const - { - float itemLevel = (float)ItemLevel; - switch (Quality) - { - case ITEM_QUALITY_POOR: - case ITEM_QUALITY_NORMAL: - case ITEM_QUALITY_UNCOMMON: - case ITEM_QUALITY_ARTIFACT: - case ITEM_QUALITY_HEIRLOOM: - itemLevel -= 13; // leaving this as a separate statement since we do not know the real behavior in this case - break; - case ITEM_QUALITY_RARE: - itemLevel -= 13; - break; - case ITEM_QUALITY_EPIC: - case ITEM_QUALITY_LEGENDARY: - default: - break; - } - return std::max<float>(0.f, itemLevel); - } + float GetItemLevelIncludingQuality() const; + + uint32 GetSkill() const; bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; } bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c58f2c940fc..503b6277963 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -20328,6 +20328,11 @@ void Player::Say(std::string const& text, Language language, WorldObject const* SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } +void Player::Say(uint32 textId, WorldObject const* target /*= nullptr*/) +{ + Talk(textId, CHAT_MSG_SAY, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target); +} + void Player::Yell(std::string const& text, Language language, WorldObject const* /*= nullptr*/) { std::string _text(text); @@ -20338,6 +20343,11 @@ void Player::Yell(std::string const& text, Language language, WorldObject const* SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); } +void Player::Yell(uint32 textId, WorldObject const* target /*= nullptr*/) +{ + Talk(textId, CHAT_MSG_YELL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target); +} + void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/, bool /*= false*/) { std::string _text(text); @@ -20348,6 +20358,11 @@ void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/ SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); } +void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool /*isBossEmote = false*/) +{ + Talk(textId, CHAT_MSG_EMOTE, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target); +} + void Player::Whisper(std::string const& text, Language language, Player* target, bool /*= false*/) { ASSERT(target); @@ -20384,6 +20399,24 @@ void Player::Whisper(std::string const& text, Language language, Player* target, ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, target->GetName().c_str(), target->autoReplyMsg.c_str()); } +void Player::Whisper(uint32 textId, Player* target, bool /*isBossWhisper = false*/) +{ + if (!target) + return; + + BroadcastText const* bct = sObjectMgr->GetBroadcastText(textId); + if (!bct) + { + TC_LOG_ERROR("entities.unit", "WorldObject::MonsterWhisper: `broadcast_text` was not %u found", textId); + return; + } + + LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); + WorldPacket data; + ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale); + target->SendDirectMessage(&data); +} + Item* Player::GetMItem(uint32 id) { ItemMap::const_iterator itr = mMitems.find(id); @@ -26561,3 +26594,22 @@ void Player::RemoveRestFlag(RestFlag restFlag) RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); } } + +uint32 Player::DoRandomRoll(uint32 minimum, uint32 maximum) +{ + ASSERT(maximum <= 10000); + + uint32 roll = urand(minimum, maximum); + + WorldPacket data(MSG_RANDOM_ROLL, 4 + 4 + 4 + 8); + data << uint32(minimum); + data << uint32(maximum); + data << uint32(roll); + data << GetGUID(); + if (Group* group = GetGroup()) + group->BroadcastPacket(&data, false); + else + SendDirectMessage(&data); + + return roll; +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index fd0fac69674..51443ce8939 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1148,12 +1148,16 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> /// Handles said message in regular chat based on declared language and in config pre-defined Range. void Say(std::string const& text, Language language, WorldObject const* = nullptr) override; + void Say(uint32 textId, WorldObject const* target = nullptr) override; /// Handles yelled message in regular chat based on declared language and in config pre-defined Range. void Yell(std::string const& text, Language language, WorldObject const* = nullptr) override; + void Yell(uint32 textId, WorldObject const* target = nullptr) override; /// Outputs an universal text which is supposed to be an action. void TextEmote(std::string const& text, WorldObject const* = nullptr, bool = false) override; + void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false) override; /// Handles whispers from Addons and players based on sender, receiver's guid and language. void Whisper(std::string const& text, Language language, Player* receiver, bool = false) override; + void Whisper(uint32 textId, Player* target, bool isBossWhisper = false) override; /*********************************************************/ /*** STORAGE SYSTEM ***/ @@ -2132,6 +2136,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendCinematicStart(uint32 CinematicSequenceId); void SendMovieStart(uint32 MovieId) const; + uint32 DoRandomRoll(uint32 minimum, uint32 maximum); + /*********************************************************/ /*** INSTANCE SYSTEM ***/ /*********************************************************/ diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 28a5a1b2587..ee8a0b093e7 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -9106,7 +9106,7 @@ bool Unit::AttackStop() if (creature->HasSearchedAssistance()) { creature->SetNoSearchAssistance(false); - UpdateSpeed(MOVE_RUN, false); + UpdateSpeed(MOVE_RUN); } } @@ -9440,7 +9440,7 @@ void Unit::SetMinion(Minion *minion, bool apply) // FIXME: hack, speed must be set only at follow if (GetTypeId() == TYPEID_PLAYER && minion->IsPet()) for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) - minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true); + minion->SetSpeedRate(UnitMoveType(i), m_speed_rate[i]); // Ghoul pets have energy instead of mana (is anywhere better place for this code?) if (minion->IsPetGhoul() || minion->IsRisenAlly()) @@ -11870,9 +11870,9 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy) if (IsPet()) { - UpdateSpeed(MOVE_RUN, true); - UpdateSpeed(MOVE_SWIM, true); - UpdateSpeed(MOVE_FLIGHT, true); + UpdateSpeed(MOVE_RUN); + UpdateSpeed(MOVE_SWIM); + UpdateSpeed(MOVE_FLIGHT); } if (!(creature->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_MOUNTED_COMBAT)) @@ -11916,7 +11916,7 @@ void Unit::ClearInCombat() if (Unit* owner = GetOwner()) for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) if (owner->GetSpeedRate(UnitMoveType(i)) > GetSpeedRate(UnitMoveType(i))) - SetSpeed(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i)), true); + SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); } else if (!IsCharmed()) return; @@ -12003,25 +12003,26 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo || target->GetReactionTo(this) > REP_NEUTRAL) return false; + Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? GetAffectingPlayer() : nullptr; + Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? target->GetAffectingPlayer() : nullptr; + // Not all neutral creatures can be attacked (even some unfriendly faction does not react aggresive to you, like Sporaggar) - if (GetReactionTo(target) == REP_NEUTRAL && - target->GetReactionTo(this) <= REP_NEUTRAL) + if ( + (playerAffectingAttacker && !playerAffectingTarget) || + (!playerAffectingAttacker && playerAffectingTarget) + ) { - if (!(target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER) && - !(target->GetTypeId() == TYPEID_UNIT && GetTypeId() == TYPEID_UNIT)) - { - Player const* player = target->GetTypeId() == TYPEID_PLAYER ? target->ToPlayer() : ToPlayer(); - Unit const* creature = target->GetTypeId() == TYPEID_UNIT ? target : this; + Player const* player = playerAffectingAttacker ? playerAffectingAttacker : playerAffectingTarget; + Unit const* creature = playerAffectingAttacker ? target : this; - if (FactionTemplateEntry const* factionTemplate = creature->GetFactionTemplateEntry()) - { - if (!(player->GetReputationMgr().GetForcedRankIfAny(factionTemplate))) - if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction)) - if (FactionState const* repState = player->GetReputationMgr().GetState(factionEntry)) - if (!(repState->Flags & FACTION_FLAG_AT_WAR)) - return false; + if (FactionTemplateEntry const* factionTemplate = creature->GetFactionTemplateEntry()) + { + if (!(player->GetReputationMgr().GetForcedRankIfAny(factionTemplate))) + if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplate->faction)) + if (FactionState const* repState = player->GetReputationMgr().GetState(factionEntry)) + if (!(repState->Flags & FACTION_FLAG_AT_WAR)) + return false; - } } } @@ -12029,9 +12030,6 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo if (creatureAttacker && creatureAttacker->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PARTY_MEMBER) return false; - Player const* playerAffectingAttacker = HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? GetAffectingPlayer() : NULL; - Player const* playerAffectingTarget = target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) ? target->GetAffectingPlayer() : NULL; - // check duel - before sanctuary checks if (playerAffectingAttacker && playerAffectingTarget) if (playerAffectingAttacker->duel && playerAffectingAttacker->duel->opponent == playerAffectingTarget && playerAffectingAttacker->duel->startTime != 0) @@ -12302,7 +12300,7 @@ void Unit::SetVisible(bool x) UpdateObjectVisibility(); } -void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) +void Unit::UpdateSpeed(UnitMoveType mtype) { int32 main_speed_mod = 0; float stack_bonus = 1.0f; @@ -12365,7 +12363,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) // Update speed for vehicle if available if (GetTypeId() == TYPEID_PLAYER && GetVehicle()) - GetVehicleBase()->UpdateSpeed(MOVE_FLIGHT, true); + GetVehicleBase()->UpdateSpeed(MOVE_FLIGHT); break; } default: @@ -12447,7 +12445,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) speed = min_speed; } - SetSpeed(mtype, speed, forced); + SetSpeedRate(mtype, speed); } float Unit::GetSpeed(UnitMoveType mtype) const @@ -12455,7 +12453,12 @@ float Unit::GetSpeed(UnitMoveType mtype) const return m_speed_rate[mtype]*(IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype]); } -void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) +void Unit::SetSpeed(UnitMoveType mtype, float newValue) +{ + SetSpeedRate(mtype, newValue / (IsControlledByPlayer() ? playerBaseMoveSpeed[mtype] : baseMoveSpeed[mtype])); +} + +void Unit::SetSpeedRate(UnitMoveType mtype, float rate) { if (rate < 0) rate = 0.0f; @@ -12468,100 +12471,59 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced) propagateSpeedChange(); - WorldPacket data; - if (!forced) + // Spline packets are for units controlled by AI. "Force speed change" (wrongly named opcodes) and "move set speed" packets are for units controlled by a player. + static Opcodes const moveTypeToOpcode[MAX_MOVE_TYPE][3] = + { + {SMSG_SPLINE_SET_WALK_SPEED, SMSG_FORCE_WALK_SPEED_CHANGE, MSG_MOVE_SET_WALK_SPEED }, + {SMSG_SPLINE_SET_RUN_SPEED, SMSG_FORCE_RUN_SPEED_CHANGE, MSG_MOVE_SET_RUN_SPEED }, + {SMSG_SPLINE_SET_RUN_BACK_SPEED, SMSG_FORCE_RUN_BACK_SPEED_CHANGE, MSG_MOVE_SET_RUN_BACK_SPEED }, + {SMSG_SPLINE_SET_SWIM_SPEED, SMSG_FORCE_SWIM_SPEED_CHANGE, MSG_MOVE_SET_SWIM_SPEED }, + {SMSG_SPLINE_SET_SWIM_BACK_SPEED, SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, MSG_MOVE_SET_SWIM_BACK_SPEED }, + {SMSG_SPLINE_SET_TURN_RATE, SMSG_FORCE_TURN_RATE_CHANGE, MSG_MOVE_SET_TURN_RATE }, + {SMSG_SPLINE_SET_FLIGHT_SPEED, SMSG_FORCE_FLIGHT_SPEED_CHANGE, MSG_MOVE_SET_FLIGHT_SPEED }, + {SMSG_SPLINE_SET_FLIGHT_BACK_SPEED, SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, MSG_MOVE_SET_FLIGHT_BACK_SPEED }, + {SMSG_SPLINE_SET_PITCH_RATE, SMSG_FORCE_PITCH_RATE_CHANGE, MSG_MOVE_SET_PITCH_RATE }, + }; + + if (GetTypeId() == TYPEID_PLAYER) { - switch (mtype) - { - case MOVE_WALK: - data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_RUN: - data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_RUN_BACK: - data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_SWIM: - data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_SWIM_BACK: - data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_TURN_RATE: - data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_FLIGHT: - data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_FLIGHT_BACK: - data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); - break; - case MOVE_PITCH_RATE: - data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4); - break; - default: - TC_LOG_ERROR("entities.unit", "Unit::SetSpeed: Unsupported move type (%d), data not sent to client.", mtype); - return; - } + // register forced speed changes for WorldSession::HandleForceSpeedChangeAck + // and do it only for real sent packets and use run for run/mounted as client expected + ++ToPlayer()->m_forced_speed_changes[mtype]; + + if (!IsInCombat()) + if (Pet* pet = ToPlayer()->GetPet()) + pet->SetSpeedRate(mtype, m_speed_rate[mtype]); + } + if (m_movedPlayer) // unit controlled by a player. + { + // Send notification to self. this packet is only sent to one client (the client of the player concerned by the change). + WorldPacket self; + self.Initialize(moveTypeToOpcode[mtype][1], mtype != MOVE_RUN ? 8 + 4 + 4 : 8 + 4 + 1 + 4); + self << GetPackGUID(); + self << (uint32)0; // Movement counter. Unimplemented at the moment! NUM_PMOVE_EVTS = 0x39Z. + if (mtype == MOVE_RUN) + self << uint8(1); // unknown byte added in 2.1.0 + self << float(GetSpeed(mtype)); + m_movedPlayer->GetSession()->SendPacket(&self); + + // Send notification to other players. sent to every clients (if in range) except one: the client of the player concerned by the change. + WorldPacket data; + data.Initialize(moveTypeToOpcode[mtype][2], 8 + 30 + 4); data << GetPackGUID(); BuildMovementPacket(&data); data << float(GetSpeed(mtype)); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } - else + else // unit controlled by AI. { - if (GetTypeId() == TYPEID_PLAYER) - { - // register forced speed changes for WorldSession::HandleForceSpeedChangeAck - // and do it only for real sent packets and use run for run/mounted as client expected - ++ToPlayer()->m_forced_speed_changes[mtype]; - - if (!IsInCombat()) - if (Pet* pet = ToPlayer()->GetPet()) - pet->SetSpeed(mtype, m_speed_rate[mtype], forced); - } - - switch (mtype) - { - case MOVE_WALK: - data.Initialize(SMSG_FORCE_WALK_SPEED_CHANGE, 16); - break; - case MOVE_RUN: - data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE, 17); - break; - case MOVE_RUN_BACK: - data.Initialize(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, 16); - break; - case MOVE_SWIM: - data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, 16); - break; - case MOVE_SWIM_BACK: - data.Initialize(SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, 16); - break; - case MOVE_TURN_RATE: - data.Initialize(SMSG_FORCE_TURN_RATE_CHANGE, 16); - break; - case MOVE_FLIGHT: - data.Initialize(SMSG_FORCE_FLIGHT_SPEED_CHANGE, 16); - break; - case MOVE_FLIGHT_BACK: - data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16); - break; - case MOVE_PITCH_RATE: - data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16); - break; - default: - TC_LOG_ERROR("entities.unit", "Unit::SetSpeed: Unsupported move type (%d), data not sent to client.", mtype); - return; - } + // send notification to every clients. + WorldPacket data; + data.Initialize(moveTypeToOpcode[mtype][0], 8 + 4); data << GetPackGUID(); - data << (uint32)0; // moveEvent, NUM_PMOVE_EVTS = 0x39 - if (mtype == MOVE_RUN) - data << uint8(0); // new 2.1.0 data << float(GetSpeed(mtype)); - SendMessageToSet(&data, true); + SendMessageToSet(&data, false); } } @@ -12827,7 +12789,7 @@ Unit* Creature::SelectVictim() if (target && _IsTargetAcceptable(target) && CanCreatureAttack(target)) { - if(!IsFocusing()) + if (!IsFocusing()) SetInFront(target); return target; } @@ -15625,12 +15587,19 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) Player* creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself(); /// @todo do instance binding anyway if the charmer/owner is offline - if (instanceMap->IsDungeon() && creditedPlayer) + if (instanceMap->IsDungeon() && (creditedPlayer || this == victim)) { if (instanceMap->IsRaidOrHeroicDungeon()) { if (creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) - ((InstanceMap*)instanceMap)->PermBindAllPlayers(creditedPlayer); + { + // if the boss killed itself we still need to bind players to the instance + if (!creditedPlayer && instanceMap->HavePlayers()) + creditedPlayer = instanceMap->GetPlayers().getFirst()->GetSource(); + + if (creditedPlayer) + ((InstanceMap*)instanceMap)->PermBindAllPlayers(creditedPlayer); + } } else { @@ -15638,7 +15607,8 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) // until the players leave the instance time_t resettime = creature->GetRespawnTimeEx() + 2 * HOUR; if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(creature->GetInstanceId())) - if (save->GetResetTime() < resettime) save->SetResetTime(resettime); + if (save->GetResetTime() < resettime) + save->SetResetTime(resettime); } } } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 9255ce039f3..59d3bd2b25f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2018,10 +2018,11 @@ class TC_GAME_API Unit : public WorldObject void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo = NULL); void CalcHealAbsorb(Unit* victim, SpellInfo const* spellInfo, uint32& healAmount, uint32& absorb); - void UpdateSpeed(UnitMoveType mtype, bool forced); + void UpdateSpeed(UnitMoveType mtype); float GetSpeed(UnitMoveType mtype) const; float GetSpeedRate(UnitMoveType mtype) const { return m_speed_rate[mtype]; } - void SetSpeed(UnitMoveType mtype, float rate, bool forced = false); + void SetSpeed(UnitMoveType mtype, float newValue); + void SetSpeedRate(UnitMoveType mtype, float rate); float ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index, float value) const; int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = NULL) const; @@ -2165,11 +2166,11 @@ class TC_GAME_API Unit : public WorldObject virtual void Yell(std::string const& text, Language language, WorldObject const* target = nullptr); virtual void TextEmote(std::string const& text, WorldObject const* target = nullptr, bool isBossEmote = false); virtual void Whisper(std::string const& text, Language language, Player* target, bool isBossWhisper = false); - void Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target); - void Say(uint32 textId, WorldObject const* target = nullptr); - void Yell(uint32 textId, WorldObject const* target = nullptr); - void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false); - void Whisper(uint32 textId, Player* target, bool isBossWhisper = false); + virtual void Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target); + virtual void Say(uint32 textId, WorldObject const* target = nullptr); + virtual void Yell(uint32 textId, WorldObject const* target = nullptr); + virtual void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false); + virtual void Whisper(uint32 textId, Player* target, bool isBossWhisper = false); protected: explicit Unit (bool isWorldObject); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 84cbb86345d..1c1982600ca 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -488,9 +488,7 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) void WorldSession::HandleRandomRollOpcode(WorldPacket& recvData) { - TC_LOG_DEBUG("network", "WORLD: Received MSG_RANDOM_ROLL"); - - uint32 minimum, maximum, roll; + uint32 minimum, maximum; recvData >> minimum; recvData >> maximum; @@ -499,20 +497,7 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recvData) return; /********************/ - // everything's fine, do it - roll = urand(minimum, maximum); - - //TC_LOG_DEBUG("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll); - - WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8); - data << uint32(minimum); - data << uint32(maximum); - data << uint32(roll); - data << uint64(GetPlayer()->GetGUID()); - if (GetPlayer()->GetGroup()) - GetPlayer()->GetGroup()->BroadcastPacket(&data, false); - else - SendPacket(&data); + GetPlayer()->DoRandomRoll(minimum, maximum); } void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 02702fc5622..64f927a987f 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -473,7 +473,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) { TC_LOG_ERROR("network", "%sSpeedChange player %s is NOT correct (must be %f instead %f), force set to correct value", move_type_name[move_type], _player->GetName().c_str(), _player->GetSpeed(move_type), newspeed); - _player->SetSpeed(move_type, _player->GetSpeedRate(move_type), true); + _player->SetSpeedRate(move_type, _player->GetSpeedRate(move_type)); } else // must be lesser - cheating { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 664ed3dc8ec..794be12ee7c 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2345,9 +2345,9 @@ float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float { // we have mapheight and vmapheight and must select more appropriate - // we are already under the surface or vmap height above map heigt + // vmap height above map height // or if the distance of the vmap height is less the land height distance - if (z < mapHeight || vmapHeight > mapHeight || std::fabs(mapHeight - z) > std::fabs(vmapHeight - z)) + if (vmapHeight > mapHeight || std::fabs(mapHeight - z) > std::fabs(vmapHeight - z)) return vmapHeight; else return mapHeight; // better use .map surface height diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index aa45c5024e6..f9a98cffd0e 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -828,7 +828,7 @@ enum SpellEffects SPELL_EFFECT_CREATE_ITEM_2 = 157, SPELL_EFFECT_MILLING = 158, SPELL_EFFECT_ALLOW_RENAME_PET = 159, - SPELL_EFFECT_160 = 160, + SPELL_EFFECT_FORCE_CAST_2 = 160, SPELL_EFFECT_TALENT_SPEC_COUNT = 161, SPELL_EFFECT_TALENT_SPEC_SELECT = 162, SPELL_EFFECT_163 = 163, diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index b01ddcb060d..f27e47fba21 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -312,7 +312,7 @@ void MotionMaster::MoveCloserAndStop(uint32 id, Unit* target, float distance) float desty = _owner->GetPositionY() + distanceToTravel * std::sin(angle); MovePoint(id, destx, desty, target->GetPositionZ()); } - else + else { // we are already close enough. We just need to turn toward the target without changing position. Movement::MoveSplineInit init(_owner); diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 7d6d512e88d..005f10b44af 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -173,7 +173,7 @@ class TC_GAME_API MotionMaster //: private std::stack<MovementGenerator *> { MovePoint(id, pos.m_positionX, pos.m_positionY, pos.m_positionZ, generatePath); } void MovePoint(uint32 id, float x, float y, float z, bool generatePath = true); - /* Makes the unit move toward the target until it is at a certain distance from it. The unit then stops. + /* Makes the unit move toward the target until it is at a certain distance from it. The unit then stops. Only works in 2D. This method doesn't account for any movement done by the target. in other words, it only works if the target is stationary. */ diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index a57bdae7f52..94c37a8d6a3 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -268,9 +268,9 @@ void FollowMovementGenerator<Creature>::_updateSpeed(Creature* owner) if (!owner->IsPet() || !owner->IsInWorld() || !i_target.isValid() || i_target->GetGUID() != owner->GetOwnerGUID()) return; - owner->UpdateSpeed(MOVE_RUN, true); - owner->UpdateSpeed(MOVE_WALK, true); - owner->UpdateSpeed(MOVE_SWIM, true); + owner->UpdateSpeed(MOVE_RUN); + owner->UpdateSpeed(MOVE_WALK); + owner->UpdateSpeed(MOVE_SWIM); } template<> diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp index aac0e26f02b..d13fa9c30f0 100644 --- a/src/server/game/Scripting/ScriptReloadMgr.cpp +++ b/src/server/game/Scripting/ScriptReloadMgr.cpp @@ -56,6 +56,7 @@ ScriptReloadMgr* ScriptReloadMgr::instance() #include "Config.h" #include "BuiltInConfig.h" #include "ScriptMgr.h" +#include "SHA1.h" #include "StartProcess.h" #include "MPSCQueue.h" #include "GitRevision.h" @@ -64,8 +65,10 @@ namespace fs = boost::filesystem; #ifdef _WIN32 #include <windows.h> + #define HOTSWAP_PLATFORM_REQUIRES_CACHING #else // Posix #include <dlfcn.h> + // #define HOTSWAP_PLATFORM_REQUIRES_CACHING #endif // Promote the sScriptReloadMgr to a HotSwapScriptReloadMgr @@ -99,13 +102,25 @@ typedef HMODULE HandleType; typedef void* HandleType; #endif +static fs::path GetDirectoryOfExecutable() +{ + ASSERT((!sConfigMgr->GetArguments().empty()), + "Expected the arguments to contain at least 1 element!"); + + fs::path path(sConfigMgr->GetArguments()[0]); + if (path.is_absolute()) + return path.parent_path(); + else + return fs::absolute(path).parent_path(); +} + class SharedLibraryUnloader { public: - SharedLibraryUnloader() - : _path() { } - explicit SharedLibraryUnloader(fs::path const& path) - : _path(path) { } + explicit SharedLibraryUnloader(fs::path path) + : path_(std::move(path)) { } + SharedLibraryUnloader(fs::path path, Optional<fs::path> cache_path) + : path_(std::move(path)), cache_path_(std::move(cache_path)) { } void operator() (HandleType handle) const { @@ -119,26 +134,37 @@ public: if (!success) { TC_LOG_ERROR("scripts.hotswap", "Failed to unload (syscall) the shared library \"%s\".", - _path.generic_string().c_str()); + path_.generic_string().c_str()); return; } - boost::system::error_code error; - if (fs::remove(_path, error)) + /// When the shared library was cached delete it's shared version + if (cache_path_) { - TC_LOG_TRACE("scripts.hotswap", "Lazy unloaded and deleted the shared library \"%s\".", - _path.generic_string().c_str()); + boost::system::error_code error; + if (!fs::remove(*cache_path_, error)) + { + TC_LOG_ERROR("scripts.hotswap", "Failed to delete the cached shared library \"%s\" (%s).", + cache_path_->generic_string().c_str(), error.message().c_str()); + + return; + } + + TC_LOG_TRACE("scripts.hotswap", "Lazy unloaded the shared library \"%s\" " + "and deleted it's cached version at \"%s\"", + path_.generic_string().c_str(), cache_path_->generic_string().c_str()); } else { - TC_LOG_ERROR("scripts.hotswap", "Failed to delete the shared library \"%s\" (%s).", - _path.generic_string().c_str(), error.message().c_str()); + TC_LOG_TRACE("scripts.hotswap", "Lazy unloaded the shared library \"%s\".", + path_.generic_string().c_str()); } } private: - fs::path _path; + fs::path const path_; + Optional<fs::path> const cache_path_; }; typedef std::unique_ptr<typename std::remove_pointer<HandleType>::type, SharedLibraryUnloader> HandleHolder; @@ -165,7 +191,8 @@ public: ScriptModule& operator= (ScriptModule const&) = delete; ScriptModule& operator= (ScriptModule&& right) = delete; - static Optional<std::shared_ptr<ScriptModule>> CreateFromPath(fs::path const& path); + static Optional<std::shared_ptr<ScriptModule>> + CreateFromPath(fs::path const& path, Optional<fs::path> cache_path); char const* GetScriptModuleRevisionHash() const override { @@ -215,23 +242,41 @@ static bool GetFunctionFromSharedLibrary(HandleType handle, std::string const& n } // Load a shared library from the given path. -Optional<std::shared_ptr<ScriptModule>> ScriptModule::CreateFromPath(fs::path const& path) +Optional<std::shared_ptr<ScriptModule>> + ScriptModule::CreateFromPath(fs::path const& path, Optional<fs::path> cache_path) { + auto const load_path = [&] () -> fs::path { + if (cache_path) + return *cache_path; + else + return path; + }(); + #ifdef _WIN32 - HandleType handle = LoadLibrary(path.generic_string().c_str()); + HandleType handle = LoadLibrary(load_path.generic_string().c_str()); #else // Posix - HandleType handle = dlopen(path.c_str(), RTLD_LAZY); + HandleType handle = dlopen(load_path.generic_string().c_str(), RTLD_LAZY); #endif if (!handle) { - TC_LOG_ERROR("scripts.hotswap", "Could not load the shared library \"%s\" for reading.", - path.generic_string().c_str()); + if (cache_path) + { + TC_LOG_ERROR("scripts.hotswap", "Could not dynamic load the shared library \"%s\" " + "(the library is cached at %s)", + path.generic_string().c_str(), cache_path->generic_string().c_str()); + } + else + { + TC_LOG_ERROR("scripts.hotswap", "Could not dynamic load the shared library \"%s\".", + path.generic_string().c_str()); + } + return boost::none; } // Use RAII to release the library on failure. - HandleHolder holder(handle, SharedLibraryUnloader(path)); + HandleHolder holder(handle, SharedLibraryUnloader(path, std::move(cache_path))); GetScriptModuleRevisionHashType getScriptModuleRevisionHash; AddScriptsType addScripts; @@ -357,7 +402,7 @@ static bool IsDebuggerBlockingRebuild() /// /// This class manages shared library loading/unloading through watching /// the script module directory. Loaded shared libraries are mirrored -/// into a .cache subdirectory to allow lazy unloading as long as +/// into a cache subdirectory to allow lazy unloading as long as /// the shared library is still used which is useful for scripts /// which can't be instantly replaced like spells or instances. /// Several modules which reference different versions can be kept loaded @@ -400,6 +445,8 @@ class HotSwapScriptReloadMgr final // like "Release" or "Debug". The build directive from the // previous same module is used if there was any. std::string script_module_build_directive_; + // The time where the build job started + uint32 start_time_; // Type of the current running job BuildJobType type_; @@ -412,7 +459,7 @@ class HotSwapScriptReloadMgr final : script_module_name_(std::move(script_module_name)), script_module_project_name_(std::move(script_module_project_name)), script_module_build_directive_(std::move(script_module_build_directive)), - type_(BuildJobType::BUILD_JOB_NONE) { } + start_time_(getMSTime()), type_(BuildJobType::BUILD_JOB_NONE) { } bool IsValid() const { @@ -425,6 +472,8 @@ class HotSwapScriptReloadMgr final std::string const& GetBuildDirective() const { return script_module_build_directive_; } + uint32 GetTimeFromStart() const { return GetMSTimeDiffToNow(start_time_); } + BuildJobType GetType() const { return type_; } std::shared_ptr<Trinity::AsyncProcessResult> const& GetProcess() const @@ -500,7 +549,13 @@ public: /// Returns the absolute path to the script module directory static fs::path GetLibraryDirectory() { - return fs::absolute(sConfigMgr->GetStringDefault("HotSwap.ScriptDir", "scripts")); + // When an absolute path is given in the config use it, + // otherwise interpret paths relative to the executable. + fs::path path(sConfigMgr->GetStringDefault("HotSwap.ScriptDir", "scripts")); + if (path.is_absolute()) + return path; + else + return fs::absolute(path, GetDirectoryOfExecutable()); } /// Returns the absolute path to the scripts directory in the source tree. @@ -541,28 +596,28 @@ public: } } - // Get the cache directory path - fs::path const cache_path = [] - { - auto path = fs::absolute(sScriptReloadMgr->GetLibraryDirectory()); - path /= ".cache"; - return path; - }(); + #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING + + temporary_cache_path_ = CalculateTemporaryCachePath(); // We use the boost filesystem function versions which accept // an error code to prevent it from throwing exceptions. boost::system::error_code code; - if ((!fs::exists(cache_path, code) || (fs::remove_all(cache_path, code) > 0)) && - !fs::create_directory(cache_path, code)) + if ((!fs::exists(temporary_cache_path_, code) + || (fs::remove_all(temporary_cache_path_, code) > 0)) && + !fs::create_directory(temporary_cache_path_, code)) { - TC_LOG_ERROR("scripts.hotswap", "Couldn't create the cache directory \"%s\".", - cache_path.generic_string().c_str()); + TC_LOG_ERROR("scripts.hotswap", "Couldn't create the cache directory at \"%s\".", + temporary_cache_path_.generic_string().c_str()); + return; } // Used to silent compiler warnings (void)code; + #endif // #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING + // Correct the CMake prefix when needed if (sWorld->getBoolConfig(CONFIG_HOTSWAP_PREFIX_CORRECTION_ENABLED)) DoCMakePrefixCorrectionIfNeeded(); @@ -694,6 +749,31 @@ private: _fileWatcher.watch(); } + static fs::path CalculateTemporaryCachePath() + { + auto path = fs::temp_directory_path(); + path /= Trinity::StringFormat("tc_script_cache_%s_%s", + GitRevision::GetBranch(), + CalculateSHA1Hash(sConfigMgr->GetFilename()).c_str()); + + return path; + } + + fs::path GenerateUniquePathForLibraryInCache(fs::path path) + { + ASSERT(!temporary_cache_path_.empty(), + "The temporary cache path wasn't set!"); + + // Create the cache path and increment the library counter to use an unique name for each library + auto cache_path = temporary_cache_path_; + cache_path /= Trinity::StringFormat("%s.%u%s", + path.stem().generic_string().c_str(), + _unique_library_name_counter++, + path.extension().generic_string().c_str()); + + return cache_path; + } + /// Updates the current state of the given source path void UpdateSourceChangeRequest(std::string const& module_name, fs::path const& path, @@ -774,32 +854,37 @@ private: ASSERT(_running_script_module_names.find(path) == _running_script_module_names.end(), "Can't load a module which is running already!"); - // Create the cache path and increment the library counter to use an unique name for each library - fs::path cache_path = fs::absolute(sScriptReloadMgr->GetLibraryDirectory()); - cache_path /= ".cache"; - cache_path /= Trinity::StringFormat("%s.%u%s", - path.stem().generic_string().c_str(), - _unique_library_name_counter++, - path.extension().generic_string().c_str()); + Optional<fs::path> cache_path; + + #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING + + // Copy the shared library into a cache on platforms which lock files on use (windows). + cache_path = GenerateUniquePathForLibraryInCache(path); - if ([&] - { - boost::system::error_code code; - fs::copy_file(path, cache_path, fs::copy_option::fail_if_exists, code); - return code; - }()) { - TC_LOG_FATAL("scripts.hotswap", ">> Failed to create cache entry for module \"%s\"!", - path.filename().generic_string().c_str()); + boost::system::error_code code; + fs::copy_file(path, *cache_path, fs::copy_option::fail_if_exists, code); + if (code) + { + TC_LOG_FATAL("scripts.hotswap", ">> Failed to create cache entry for module " + "\"%s\" at \"%s\" with reason (\"%s\")!", + path.filename().generic_string().c_str(), cache_path->generic_string().c_str(), + code.message().c_str()); + + // Find a better solution for this but it's much better + // to start the core without scripts + std::this_thread::sleep_for(std::chrono::seconds(5)); + ABORT(); + return; + } - // Find a better solution for this but it's much better - // to start the core without scripts - std::this_thread::sleep_for(std::chrono::seconds(5)); - ABORT(); - return; + TC_LOG_TRACE("scripts.hotswap", ">> Copied the shared library \"%s\" to \"%s\" for caching.", + path.filename().generic_string().c_str(), cache_path->generic_string().c_str()); } - auto module = ScriptModule::CreateFromPath(cache_path); + #endif // #ifdef HOTSWAP_PLATFORM_REQUIRES_CACHING + + auto module = ScriptModule::CreateFromPath(path, cache_path); if (!module) { TC_LOG_FATAL("scripts.hotswap", ">> Failed to load script module \"%s\"!", @@ -984,7 +1069,7 @@ private: return; } - + // Find all source files of a changed script module and removes // it from the changed source list, invoke the build afterwards. bool rebuild_buildfiles; @@ -1056,7 +1141,7 @@ private: ASSERT(_build_job->IsValid(), "Invalid build job!"); // Retrieve the result - auto const error = _build_job->GetProcess()->GetFutureResult().get(); + auto const error = _build_job->GetProcess()->GetFutureResult().get(); if (terminate_early) { @@ -1117,8 +1202,9 @@ private: if (!error) { // Installation was successful - TC_LOG_INFO("scripts.hotswap", ">> Successfully installed module %s.", - _build_job->GetModuleName().c_str()); + TC_LOG_INFO("scripts.hotswap", ">> Successfully installed module %s in %us", + _build_job->GetModuleName().c_str(), + _build_job->GetTimeFromStart() / IN_MILLISECONDS); } else { @@ -1144,7 +1230,7 @@ private: TC_LOG_INFO("scripts.hotswap", "Rerunning CMake because there were sources added or removed..."); - _build_job->UpdateCurrentJob(BuildJobType::BUILD_JOB_RERUN_CMAKE, + _build_job->UpdateCurrentJob(BuildJobType::BUILD_JOB_RERUN_CMAKE, InvokeAsyncCMakeCommand(BuiltInConfig::GetBuildDirectory())); } @@ -1247,7 +1333,7 @@ private: #ifndef _WIN32 // The worldserver location is ${CMAKE_INSTALL_PREFIX}/bin // on all other platforms then windows - current_path = current_path.remove_leaf(); + current_path = current_path.parent_path(); #endif if (value != current_path) @@ -1263,7 +1349,7 @@ private: if (base == branch) return true; - branch = branch.remove_leaf(); + branch = branch.parent_path(); } return false; @@ -1344,6 +1430,9 @@ private: // Is true when the build job dispatcher should stop after // the current job has finished bool terminate_early; + + // The path to the tc_scripts temporary cache + fs::path temporary_cache_path_; }; /// Maps efsw actions to strings diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index e3c6179a34a..1c77283d812 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -344,11 +344,12 @@ WorldSocket::ReadDataHandlerResult WorldSocket::ReadDataHandler() default: { sessionGuard.lock(); + LogOpcodeText(opcode, sessionGuard); + if (!_worldSession) { TC_LOG_ERROR("network.opcode", "ProcessIncoming: Client not authed opcode = %u", uint32(opcode)); - CloseSocket(); return ReadDataHandlerResult::Error; } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 5585dc8762b..a8adda3ad58 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2915,7 +2915,7 @@ void AuraEffect::HandleAuraModIncreaseSpeed(AuraApplication const* aurApp, uint8 Unit* target = aurApp->GetTarget(); - target->UpdateSpeed(MOVE_RUN, true); + target->UpdateSpeed(MOVE_RUN); } void AuraEffect::HandleAuraModIncreaseMountedSpeed(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -2930,7 +2930,7 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp, Unit* target = aurApp->GetTarget(); if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK) - target->UpdateSpeed(MOVE_FLIGHT, true); + target->UpdateSpeed(MOVE_FLIGHT); //! Update ability to fly if (GetAuraType() == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) @@ -2965,7 +2965,7 @@ void AuraEffect::HandleAuraModIncreaseSwimSpeed(AuraApplication const* aurApp, u Unit* target = aurApp->GetTarget(); - target->UpdateSpeed(MOVE_SWIM, true); + target->UpdateSpeed(MOVE_SWIM); } void AuraEffect::HandleAuraModDecreaseSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const @@ -2975,12 +2975,12 @@ void AuraEffect::HandleAuraModDecreaseSpeed(AuraApplication const* aurApp, uint8 Unit* target = aurApp->GetTarget(); - target->UpdateSpeed(MOVE_RUN, true); - target->UpdateSpeed(MOVE_SWIM, true); - target->UpdateSpeed(MOVE_FLIGHT, true); - target->UpdateSpeed(MOVE_RUN_BACK, true); - target->UpdateSpeed(MOVE_SWIM_BACK, true); - target->UpdateSpeed(MOVE_FLIGHT_BACK, true); + target->UpdateSpeed(MOVE_RUN); + target->UpdateSpeed(MOVE_SWIM); + target->UpdateSpeed(MOVE_FLIGHT); + target->UpdateSpeed(MOVE_RUN_BACK); + target->UpdateSpeed(MOVE_SWIM_BACK); + target->UpdateSpeed(MOVE_FLIGHT_BACK); } void AuraEffect::HandleAuraModUseNormalSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const @@ -2990,9 +2990,9 @@ void AuraEffect::HandleAuraModUseNormalSpeed(AuraApplication const* aurApp, uint Unit* target = aurApp->GetTarget(); - target->UpdateSpeed(MOVE_RUN, true); - target->UpdateSpeed(MOVE_SWIM, true); - target->UpdateSpeed(MOVE_FLIGHT, true); + target->UpdateSpeed(MOVE_RUN); + target->UpdateSpeed(MOVE_SWIM); + target->UpdateSpeed(MOVE_FLIGHT); } /*********************************************************/ diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3f0ff9a0f19..1c2b2743a6d 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -217,7 +217,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectCreateItem2, //157 SPELL_EFFECT_CREATE_ITEM_2 create item or create item template and replace by some randon spell loot item &Spell::EffectMilling, //158 SPELL_EFFECT_MILLING milling &Spell::EffectRenamePet, //159 SPELL_EFFECT_ALLOW_RENAME_PET allow rename pet once again - &Spell::EffectNULL, //160 SPELL_EFFECT_160 1 spell - 45534 + &Spell::EffectForceCast, //160 SPELL_EFFECT_FORCE_CAST_2 &Spell::EffectSpecCount, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert) &Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec &Spell::EffectNULL, //163 unused @@ -3661,16 +3661,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) m_caster->CastSpell(unitTarget, 22682, true); return; } - // Decimate - case 28374: - case 54426: - if (unitTarget) - { - int32 decimateDamage = int32(unitTarget->GetHealth()) - int32(unitTarget->CountPctFromMaxHealth(5)); - if (decimateDamage > 0) - m_caster->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, decimateDamage, unitTarget); - } - return; // Mirren's Drinking Hat case 29830: { @@ -3781,28 +3771,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) break; } - // Roll Dice - Decahedral Dwarven Dice - case 47770: - { - char buf[128]; - const char *gender = "his"; - if (m_caster->getGender() > 0) - gender = "her"; - sprintf(buf, "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10)); - m_caster->TextEmote(buf); - break; - } - // Roll 'dem Bones - Worn Troll Dice - case 47776: - { - char buf[128]; - const char *gender = "his"; - if (m_caster->getGender() > 0) - gender = "her"; - sprintf(buf, "%s causually tosses %s [Worn Troll Dice]. One %u and one %u.", m_caster->GetName().c_str(), gender, urand(1, 6), urand(1, 6)); - m_caster->TextEmote(buf); - break; - } // Death Knight Initiate Visual case 51519: { diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 069c794ca8b..ccb1d78b8bc 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -754,7 +754,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_ITEM_2 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET - {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_160 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_FORCE_CAST_2 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 163 SPELL_EFFECT_163 diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 861b45efa95..f1ddb448b35 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -477,11 +477,11 @@ public: if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, handler->GetNameLink().c_str(), ASpeed); - target->SetSpeed(MOVE_WALK, ASpeed, true); - target->SetSpeed(MOVE_RUN, ASpeed, true); - target->SetSpeed(MOVE_SWIM, ASpeed, true); - //target->SetSpeed(MOVE_TURN, ASpeed, true); - target->SetSpeed(MOVE_FLIGHT, ASpeed, true); + target->SetSpeedRate(MOVE_WALK, ASpeed); + target->SetSpeedRate(MOVE_RUN, ASpeed); + target->SetSpeedRate(MOVE_SWIM, ASpeed); + //target->SetSpeedRate(MOVE_TURN, ASpeed); + target->SetSpeedRate(MOVE_FLIGHT, ASpeed); return true; } @@ -525,7 +525,7 @@ public: if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, handler->GetNameLink().c_str(), Speed); - target->SetSpeed(MOVE_RUN, Speed, true); + target->SetSpeedRate(MOVE_RUN, Speed); return true; } @@ -570,7 +570,7 @@ public: if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, handler->GetNameLink().c_str(), Swim); - target->SetSpeed(MOVE_SWIM, Swim, true); + target->SetSpeedRate(MOVE_SWIM, Swim); return true; } @@ -615,7 +615,7 @@ public: if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, handler->GetNameLink().c_str(), BSpeed); - target->SetSpeed(MOVE_RUN_BACK, BSpeed, true); + target->SetSpeedRate(MOVE_RUN_BACK, BSpeed); return true; } @@ -651,7 +651,7 @@ public: if (handler->needReportToTarget(target)) ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, handler->GetNameLink().c_str(), FSpeed); - target->SetSpeed(MOVE_FLIGHT, FSpeed, true); + target->SetSpeedRate(MOVE_FLIGHT, FSpeed); return true; } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp index 51bb314968d..ffec32c0619 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_baron_geddon.cpp @@ -27,6 +27,8 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "molten_core.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" enum Emotes { @@ -36,9 +38,10 @@ enum Emotes enum Spells { SPELL_INFERNO = 19695, + SPELL_INFERNO_DMG = 19698, SPELL_IGNITE_MANA = 19659, SPELL_LIVING_BOMB = 20475, - SPELL_ARMAGEDDON = 20479, + SPELL_ARMAGEDDON = 20478, }; enum Events @@ -119,7 +122,36 @@ class boss_baron_geddon : public CreatureScript } }; +class spell_baron_geddon_inferno : public SpellScriptLoader +{ + public: + spell_baron_geddon_inferno() : SpellScriptLoader("spell_baron_geddon_inferno") { } + + class spell_baron_geddon_inferno_AuraScript : public AuraScript + { + PrepareAuraScript(spell_baron_geddon_inferno_AuraScript); + + void OnPeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + int32 damageForTick[8] = { 500, 500, 1000, 1000, 2000, 2000, 3000, 5000 }; + GetTarget()->CastCustomSpell(SPELL_INFERNO_DMG, SPELLVALUE_BASE_POINT0, damageForTick[aurEff->GetTickNumber() - 1], (Unit*)nullptr, TRIGGERED_FULL_MASK, nullptr, aurEff); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_baron_geddon_inferno_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_baron_geddon_inferno_AuraScript(); + } +}; + void AddSC_boss_baron_geddon() { new boss_baron_geddon(); + new spell_baron_geddon_inferno(); } diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp index 7d7c60ac419..6ff20e66f7f 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp @@ -138,7 +138,7 @@ public: { Initialize(); - me->SetSpeed(MOVE_RUN, 2.0f); + me->SetSpeedRate(MOVE_RUN, 2.0f); me->SetDisableGravity(true); me->SetWalk(false); me->setActive(true); diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp index 4aef3c8d4a3..ace15cc2a7e 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp @@ -562,7 +562,7 @@ public: arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f); arca->setActive(true); arca->InterruptNonMeleeSpells(true); - arca->SetSpeed(MOVE_FLIGHT, 2.0f); + arca->SetSpeedRate(MOVE_FLIGHT, 2.0f); } return 10000; case 13: diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index b809128e731..ebe406c8909 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -405,7 +405,7 @@ public: Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000); if (Orb && target) { - Orb->SetSpeed(MOVE_RUN, 0.5f); + Orb->SetSpeedRate(MOVE_RUN, 0.5f); Orb->AddThreat(target, 1000000.0f); Orb->AI()->AttackStart(target); } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp index 81044a0dbb1..3cf78b79f67 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp @@ -396,7 +396,7 @@ class npc_eye_of_acherus : public CreatureScript if (Player* owner = me->GetCharmerOrOwner()->ToPlayer()) { for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) - me->SetSpeed(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i)), true); + me->SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); Talk(TALK_MOVE_START, owner); } me->GetMotionMaster()->MovePath(me->GetEntry() * 100, false); @@ -419,7 +419,7 @@ class npc_eye_of_acherus : public CreatureScript { owner->RemoveAura(SPELL_EYE_FLIGHT_BOOST); for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) - me->SetSpeed(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i)), true); + me->SetSpeedRate(UnitMoveType(i), owner->GetSpeedRate(UnitMoveType(i))); Talk(TALK_CONTROL, owner); } @@ -703,7 +703,7 @@ class npc_dark_rider_of_acherus : public CreatureScript TargetGUID = who->GetGUID(); me->SetWalk(true); - me->SetSpeed(MOVE_RUN, 0.4f); + me->SetSpeedRate(MOVE_RUN, 0.4f); me->GetMotionMaster()->MoveChase(who); me->SetTarget(TargetGUID); Intro = true; @@ -1050,7 +1050,7 @@ class npc_scarlet_miner_cart : public CreatureScript // Not 100% correct, but movement is smooth. Sometimes miner walks faster // than normal, this speed is fast enough to keep up at those times. - me->SetSpeed(MOVE_RUN, 1.25f); + me->SetSpeedRate(MOVE_RUN, 1.25f); me->GetMotionMaster()->MoveFollow(miner, 1.0f, 0); } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index e336ff24382..d25a225717a 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -923,7 +923,7 @@ public: if (ObjectAccessor::GetCreature(*me, uiLichKingGUID)) 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->SetSpeedRate(MOVE_RUN, 3.0f); me->SetWalk(false); SetHoldState(false); JumpToNextStep(0); @@ -935,7 +935,7 @@ public: temp->HandleEmoteCommand(EMOTE_ONESHOT_KICK); temp->AI()->Talk(SAY_LIGHT_OF_DAWN46); } - me->SetSpeed(MOVE_RUN, 6.0f); + me->SetSpeedRate(MOVE_RUN, 6.0f); me->SetStandState(UNIT_STAND_STATE_DEAD); SetHoldState(false); // Darion got kicked by lich king JumpToNextStep(0); @@ -997,7 +997,7 @@ public: Unit* temp = me->SummonCreature(NPC_DEFENDER_OF_THE_LIGHT, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->setFaction(me->getFaction()); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); uiDefenderGUID[0] = temp->GetGUID(); @@ -1005,7 +1005,7 @@ public: temp = me->SummonCreature(NPC_RIMBLAT_EARTHSHATTER, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f }), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->setFaction(me->getFaction()); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); uiEarthshatterGUID[0] = temp->GetGUID(); @@ -1014,7 +1014,7 @@ public: { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); temp->AI()->Talk(SAY_LIGHT_OF_DAWN50); } @@ -1022,7 +1022,7 @@ public: { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->HandleEmoteCommand(EMOTE_STATE_ATTACK_UNARMED); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); } @@ -1030,7 +1030,7 @@ public: { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_ATTACK_UNARMED); temp->SetWalk(false); - temp->SetSpeed(MOVE_RUN, 2.0f); + temp->SetSpeedRate(MOVE_RUN, 2.0f); temp->GetMotionMaster()->MovePoint(0, fLichPositionX, fLichPositionY, fLichPositionZ); } } @@ -1044,33 +1044,33 @@ public: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiMaxwellGUID)) { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[14]); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiKorfaxGUID)) { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[11]); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiEligorGUID)) { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[17]); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiDefenderGUID[0])) { - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f })); } if (Creature* temp = ObjectAccessor::GetCreature(*me, uiEarthshatterGUID[0])) { - temp->SetSpeed(MOVE_RUN, 6.0f); + temp->SetSpeedRate(MOVE_RUN, 6.0f); temp->SetStandState(UNIT_STAND_STATE_DEAD); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[0].GetPositionWithOffset({ float(rand32() % 10), float(rand32() % 10), 0.0f, 0.0f })); } @@ -1093,7 +1093,7 @@ public: break; case 46: // Darion stand up, "not today" - me->SetSpeed(MOVE_RUN, 1.0f); + me->SetSpeedRate(MOVE_RUN, 1.0f); me->SetWalk(true); me->SetStandState(UNIT_STAND_STATE_STAND); Talk(SAY_LIGHT_OF_DAWN53); @@ -1153,7 +1153,7 @@ public: temp->AI()->Talk(EMOTE_LIGHT_OF_DAWN16); 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->SetSpeedRate(MOVE_RUN, 3.0f); // workarounds, make Tirion still running temp->SetWalk(false); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[2]); if (Creature* lktemp = ObjectAccessor::GetCreature(*me, uiLichKingGUID)) @@ -1171,7 +1171,7 @@ public: case 54: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiLichKingGUID)) { - temp->SetSpeed(MOVE_RUN, 1.0f); + temp->SetSpeedRate(MOVE_RUN, 1.0f); me->SetWalk(true); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[29]); // 26 } @@ -1208,7 +1208,7 @@ public: if (Creature* temp = ObjectAccessor::GetCreature(*me, uiTirionGUID)) // Tirion runs to Darion { temp->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - temp->SetSpeed(MOVE_RUN, 1.0f); + temp->SetSpeedRate(MOVE_RUN, 1.0f); temp->GetMotionMaster()->MovePoint(0, LightofDawnLoc[6]); } JumpToNextStep(2500); diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp index 74b300919d8..f7a1c18c234 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp @@ -450,7 +450,7 @@ public: me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->SetDisableGravity(true); - me->SetSpeed(MOVE_WALK, 5.0f, true); + me->SetSpeedRate(MOVE_WALK, 5.0f); wp_reached = false; count = 0; say_timer = 3000; diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp index d9b481d7b6d..fded249f9ca 100644 --- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp +++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp @@ -249,7 +249,7 @@ public: me->CastStop(SPELL_FOG_BREATH); me->RemoveAurasDueToSpell(SPELL_FOG_BREATH); me->StopMoving(); - me->SetSpeed(MOVE_RUN, 2.0f); + me->SetSpeedRate(MOVE_RUN, 2.0f); events.ScheduleEvent(EVENT_CLEAVE, urand(5000, 10000)); events.ScheduleEvent(EVENT_CORROSION, urand(10000, 20000)); @@ -530,7 +530,7 @@ public: npc_felmyst_vaporAI(Creature* creature) : ScriptedAI(creature) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetSpeed(MOVE_RUN, 0.8f); + me->SetSpeedRate(MOVE_RUN, 0.8f); } void Reset() override { } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 791f68bae31..72e76ba52bf 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -425,7 +425,7 @@ class npc_akilzon_eagle : public CreatureScript if (Unit* target = ObjectAccessor::GetUnit(*me, TargetGUID)) DoCast(target, SPELL_EAGLE_SWOOP, true); TargetGUID.Clear(); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); EagleSwoop_Timer = urand(5000, 10000); } } @@ -454,7 +454,7 @@ class npc_akilzon_eagle : public CreatureScript { target->GetContactPoint(me, x, y, z); z += 2; - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); TargetGUID = target->GetGUID(); } me->GetMotionMaster()->MovePoint(0, x, y, z); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index 0407cb6cd7c..188f9d0cc03 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -142,7 +142,7 @@ class boss_nalorakk : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); inMove = false; waitTimer = 0; - me->SetSpeed(MOVE_RUN, 2); + me->SetSpeedRate(MOVE_RUN, 2); me->SetWalk(false); }else { diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp index 96c0798ae05..a1c2369cf66 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp @@ -347,7 +347,7 @@ class boss_zuljin : public CreatureScript Vortex->CastSpell(Vortex, SPELL_CYCLONE_PASSIVE, true); Vortex->CastSpell(Vortex, SPELL_CYCLONE_VISUAL, true); Vortex->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Vortex->SetSpeed(MOVE_RUN, 1.0f); + Vortex->SetSpeedRate(MOVE_RUN, 1.0f); Vortex->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); DoZoneInCombat(Vortex); } @@ -438,7 +438,7 @@ class boss_zuljin : public CreatureScript { if (me->GetVictim()) TankGUID = me->EnsureVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); AttackStart(target); // change victim Claw_Rage_Timer = 0; Claw_Loop_Timer = 500; @@ -462,7 +462,7 @@ class boss_zuljin : public CreatureScript if (Claw_Counter == 12) { Claw_Rage_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); AttackStart(ObjectAccessor::GetUnit(*me, TankGUID)); TankGUID.Clear(); return; @@ -487,7 +487,7 @@ class boss_zuljin : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { TankGUID = me->EnsureVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); AttackStart(target); // change victim Lynx_Rush_Timer = 0; Claw_Counter = 0; @@ -510,7 +510,7 @@ class boss_zuljin : public CreatureScript if (Claw_Counter == 9) { Lynx_Rush_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); AttackStart(ObjectAccessor::GetUnit(*me, TankGUID)); TankGUID.Clear(); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 44cbdec2cb5..0526dcfa630 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -479,12 +479,12 @@ public: void DoMount() { me->Mount(SKARLOC_MOUNT_MODEL); - me->SetSpeed(MOVE_RUN, SPEED_MOUNT); + me->SetSpeedRate(MOVE_RUN, SPEED_MOUNT); } void DoUnmount() { me->Dismount(); - me->SetSpeed(MOVE_RUN, SPEED_RUN); + me->SetSpeedRate(MOVE_RUN, SPEED_RUN); } void EnterCombat(Unit* /*who*/) override { diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp index 7da15b1fdce..71ebe870e3d 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp @@ -205,7 +205,7 @@ public: PointData = GetMoveData(); MovePoint = PointData->LocIdEnd; - me->SetSpeed(MOVE_FLIGHT, 1.5f); + me->SetSpeedRate(MOVE_FLIGHT, 1.5f); me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation); } } @@ -220,7 +220,7 @@ public: PointData = GetMoveData(); if (PointData) { - me->SetSpeed(MOVE_FLIGHT, 1.0f); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ); } break; @@ -250,7 +250,7 @@ public: if (Creature * trigger = me->SummonCreature(NPC_TRIGGER, MiddleRoomLocation, TEMPSUMMON_CORPSE_DESPAWN)) triggerGUID = trigger->GetGUID(); me->GetMotionMaster()->MoveTakeoff(11, Phase2Floating); - me->SetSpeed(MOVE_FLIGHT, 1.0f); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); Talk(SAY_PHASE_2_TRANS); instance->SetData(DATA_ONYXIA_PHASE, Phase); events.ScheduleEvent(EVENT_WHELP_SPAWN, 5000); diff --git a/src/server/scripts/Kalimdor/zone_azshara.cpp b/src/server/scripts/Kalimdor/zone_azshara.cpp index 1ed95c16a0d..4847ac46542 100644 --- a/src/server/scripts/Kalimdor/zone_azshara.cpp +++ b/src/server/scripts/Kalimdor/zone_azshara.cpp @@ -404,7 +404,7 @@ public: DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE); me->SetHover(true); me->SetSwim(true); - me->SetSpeed(MOVE_RUN, 0.85f, true); + me->SetSpeedRate(MOVE_RUN, 0.85f); me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]); Escape = true; diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index 6880d8ee38f..3f4a905147f 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -89,7 +89,7 @@ public: me->UpdateEntry(NPC_TAMED_KODO); me->CombatStop(); me->DeleteThreatList(); - me->SetSpeed(MOVE_RUN, 0.6f, true); + me->SetSpeedRate(MOVE_RUN, 0.6f); me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); me->setActive(true); } diff --git a/src/server/scripts/Kalimdor/zone_durotar.cpp b/src/server/scripts/Kalimdor/zone_durotar.cpp index 05caf9cca3a..62a041e7798 100644 --- a/src/server/scripts/Kalimdor/zone_durotar.cpp +++ b/src/server/scripts/Kalimdor/zone_durotar.cpp @@ -483,8 +483,8 @@ class spell_mount_check : public SpellScriptLoader else if (!owner->IsMounted() && target->IsMounted()) target->Dismount(); - target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); - target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); + target->SetSpeedRate(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); + target->SetSpeedRate(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); } void Register() override diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp index ab09dd45710..3c11fd5d9a6 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp @@ -454,11 +454,11 @@ public: float distance = me->GetDistance(JedogaPosition[1]); if (distance < 9.0f) - me->SetSpeed(MOVE_WALK, 0.5f, true); + me->SetSpeedRate(MOVE_WALK, 0.5f); else if (distance < 15.0f) - me->SetSpeed(MOVE_WALK, 0.75f, true); + me->SetSpeedRate(MOVE_WALK, 0.75f); else if (distance < 20.0f) - me->SetSpeed(MOVE_WALK, 1.0f, true); + me->SetSpeedRate(MOVE_WALK, 1.0f); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MovePoint(1, JedogaPosition[1]); 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 e25f64f61aa..04b62f77e9a 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp @@ -178,7 +178,7 @@ class boss_prince_taldaram : public CreatureScript if (Unit* embraceTarget = GetEmbraceTarget()) { me->GetMotionMaster()->Clear(); - me->SetSpeed(MOVE_WALK, 2.0f, true); + me->SetSpeedRate(MOVE_WALK, 2.0f); me->GetMotionMaster()->MoveChase(embraceTarget); } events.ScheduleEvent(EVENT_VANISHED, 1300); @@ -188,7 +188,7 @@ class boss_prince_taldaram : public CreatureScript DoCast(embraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR); Talk(SAY_FEED); me->GetMotionMaster()->Clear(); - me->SetSpeed(MOVE_WALK, 1.0f, true); + me->SetSpeedRate(MOVE_WALK, 1.0f); me->GetMotionMaster()->MoveChase(me->GetVictim()); events.ScheduleEvent(EVENT_FEEDING, 20000); break; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp index c89510211b9..7440984d7c5 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp @@ -804,7 +804,7 @@ class npc_anubarak_spike : public CreatureScript void StartChase(Unit* who) { DoCast(who, SPELL_MARK); - me->SetSpeed(MOVE_RUN, 0.5f); + me->SetSpeedRate(MOVE_RUN, 0.5f); // make sure the Spine will really follow the one he should me->getThreatManager().clearReferences(); me->SetInCombatWithZone(); diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 4c2b92da0ea..3ac85809fa2 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -2580,7 +2580,7 @@ class npc_quel_delar_sword : public CreatureScript void Reset() override { _events.Reset(); - me->SetSpeed(MOVE_FLIGHT, 4.5f, true); + me->SetSpeedRate(MOVE_FLIGHT, 4.5f); DoCast(SPELL_WHIRLWIND_VISUAL); if (_intro) _events.ScheduleEvent(EVENT_QUEL_DELAR_INIT, 0); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp index 03f12e46bc3..b24a36da3fb 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp @@ -418,7 +418,7 @@ class boss_krick : public CreatureScript case EVENT_OUTRO_6: if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _instanceScript->GetGuidData(DATA_TYRANNUS_EVENT))) { - tyrannus->SetSpeed(MOVE_FLIGHT, 3.5f, true); + tyrannus->SetSpeedRate(MOVE_FLIGHT, 3.5f); tyrannus->GetMotionMaster()->MovePoint(1, outroPos[4]); _tyrannusGUID = tyrannus->GetGUID(); } 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 166e9739a95..51711f9ded5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -1069,7 +1069,7 @@ class npc_blood_queen_lana_thel : public CreatureScript if (Creature* summon = DoSummon(NPC_FLOATING_TRIGGER, triggerPos, 15000, TEMPSUMMON_TIMED_DESPAWN)) { summon->CastSpell(summon, SPELL_OOC_INVOCATION_VISUAL, true); - summon->SetSpeed(MOVE_FLIGHT, 0.15f, true); // todo: creature is swimming, check if this is blizzlike or not. + summon->SetSpeedRate(MOVE_FLIGHT, 0.15f); // todo: creature is swimming, check if this is blizzlike or not. summon->GetMotionMaster()->MovePoint(0, triggerEndPos); } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 056231285e2..9f20799df82 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -142,7 +142,7 @@ class boss_lord_marrowgar : public CreatureScript void Reset() override { _Reset(); - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); me->RemoveAurasDueToSpell(SPELL_BONE_STORM); me->RemoveAurasDueToSpell(SPELL_BERSERK); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); @@ -224,7 +224,7 @@ class boss_lord_marrowgar : public CreatureScript case EVENT_BONE_STORM_BEGIN: if (Aura* pStorm = me->GetAura(SPELL_BONE_STORM)) pStorm->SetDuration(int32(_boneStormDuration)); - me->SetSpeed(MOVE_RUN, _baseSpeed*3.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*3.0f); Talk(SAY_BONE_STORM); events.ScheduleEvent(EVENT_BONE_STORM_END, _boneStormDuration+1); // no break here @@ -242,7 +242,7 @@ class boss_lord_marrowgar : public CreatureScript if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MoveChase(me->GetVictim()); - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); events.CancelEvent(EVENT_BONE_STORM_MOVE); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); if (!IsHeroic()) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 280a0aaa13a..fe6e4081326 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -369,21 +369,21 @@ class boss_professor_putricide : public CreatureScript { case POINT_FESTERGUT: instance->SetBossState(DATA_FESTERGUT, IN_PROGRESS); // needed here for delayed gate close - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); DoAction(ACTION_FESTERGUT_GAS); if (Creature* festergut = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FESTERGUT))) festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, false, NULL, NULL, festergut->GetGUID()); break; case POINT_ROTFACE: instance->SetBossState(DATA_ROTFACE, IN_PROGRESS); // needed here for delayed gate close - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); DoAction(ACTION_ROTFACE_OOZE); events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE); break; case POINT_TABLE: // stop attack me->GetMotionMaster()->MoveIdle(); - me->SetSpeed(MOVE_RUN, _baseSpeed, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed); if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_PUTRICIDE_TABLE))) me->SetFacingToObject(table); // operating on new phase already @@ -418,7 +418,7 @@ class boss_professor_putricide : public CreatureScript { case ACTION_FESTERGUT_COMBAT: SetPhase(PHASE_FESTERGUT); - me->SetSpeed(MOVE_RUN, _baseSpeed*2.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); me->GetMotionMaster()->MovePoint(POINT_FESTERGUT, festergutWatchPos); me->SetReactState(REACT_PASSIVE); DoZoneInCombat(me); @@ -435,7 +435,7 @@ class boss_professor_putricide : public CreatureScript case ACTION_ROTFACE_COMBAT: { SetPhase(PHASE_ROTFACE); - me->SetSpeed(MOVE_RUN, _baseSpeed*2.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); me->GetMotionMaster()->MovePoint(POINT_ROTFACE, rotfaceWatchPos); me->SetReactState(REACT_PASSIVE); _oozeFloodStage = 0; @@ -477,7 +477,7 @@ class boss_professor_putricide : public CreatureScript events.ScheduleEvent(EVENT_ROTFACE_DIES, 4500, 0, PHASE_ROTFACE); break; case ACTION_CHANGE_PHASE: - me->SetSpeed(MOVE_RUN, _baseSpeed*2.0f, true); + me->SetSpeedRate(MOVE_RUN, _baseSpeed*2.0f); events.DelayEvents(30000); me->AttackStop(); if (!IsHeroic()) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 0b129f3aa89..caa37465165 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -315,7 +315,7 @@ class boss_sindragosa : public CreatureScript me->SetCanFly(true); me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); - me->SetSpeed(MOVE_FLIGHT, 4.0f); + me->SetSpeedRate(MOVE_FLIGHT, 4.0f); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); float moveTime = me->GetExactDist(&SindragosaFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SindragosaLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); @@ -351,7 +351,7 @@ class boss_sindragosa : public CreatureScript me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); me->SetHomePosition(SindragosaLandPos); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetSpeed(MOVE_FLIGHT, 2.5f); + me->SetSpeedRate(MOVE_FLIGHT, 2.5f); // Sindragosa enters combat as soon as she lands DoZoneInCombat(); @@ -697,7 +697,7 @@ class npc_spinestalker : public CreatureScript return; me->setActive(true); - me->SetSpeed(MOVE_FLIGHT, 2.0f); + me->SetSpeedRate(MOVE_FLIGHT, 2.0f); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); float moveTime = me->GetExactDist(&SpinestalkerFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SpinestalkerLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); @@ -834,7 +834,7 @@ class npc_rimefang : public CreatureScript return; me->setActive(true); - me->SetSpeed(MOVE_FLIGHT, 2.0f); + me->SetSpeedRate(MOVE_FLIGHT, 2.0f); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); float moveTime = me->GetExactDist(&RimefangFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f); me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, RimefangLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250)); 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 4675989228a..4a0a8217af8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -763,7 +763,7 @@ class boss_the_lich_king : public CreatureScript { summons.Summon(summon); summon->SetReactState(REACT_PASSIVE); - summon->SetSpeed(MOVE_FLIGHT, 0.5f); + summon->SetSpeedRate(MOVE_FLIGHT, 0.5f); summon->GetMotionMaster()->MoveRandom(10.0f); if (!events.IsInPhase(PHASE_FROSTMOURNE)) summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000)); @@ -1448,7 +1448,7 @@ class npc_valkyr_shadowguard : public CreatureScript _events.Reset(); me->SetReactState(REACT_PASSIVE); DoCast(me, SPELL_WINGS_OF_THE_DAMNED, false); - me->SetSpeed(MOVE_FLIGHT, 0.642857f, true); + me->SetSpeedRate(MOVE_FLIGHT, 0.642857f); } void IsSummonedBy(Unit* /*summoner*/) override diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp index ec47b0db101..32054b67915 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gluth.cpp @@ -18,38 +18,74 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "naxxramas.h" +#include "SpellScript.h" +#include <math.h> -enum Spells +enum Texts { - SPELL_MORTAL_WOUND = 25646, - SPELL_ENRAGE = 28371, - SPELL_DECIMATE = 28374, - SPELL_BERSERK = 26662, - SPELL_INFECTED_WOUND = 29306 + EMOTE_SPOTS_ONE = 0, + EMOTE_DECIMATE = 1, + EMOTE_ENRAGE = 2, + EMOTE_DEVOURS_ALL = 3, + EMOTE_BERSERKER = 4 }; -enum Creatures +enum Spells { - NPC_ZOMBIE = 16360 + // Gluth + SPELL_MORTAL_WOUND = 54378, // spell effect dummy unused. what its supposed to do is unkown. + SPELL_ENRAGE = 28371, // 54427 in 25 man. + SPELL_DECIMATE = 28374, // 54426 in 25 man. Effect0 is handled by SpellScript (see below) and 2 rows in conditions table. Effect2 is handled by SpellScript (see below). + SPELL_DECIMATE_DMG = 28375, + SPELL_BERSERK = 26662, + SPELL_ZOMBIE_CHOW_SEARCH_SINGLE = 28239, // Insta kill spell. Single target. See spell script below. + SPELL_ZOMBIE_CHOW_SEARCH_MULTI = 28404, // Insta kill spell. Affect all zombies 10 yards around Gluth's center. See one row conditions table + spell script below. + + // Zombies + SPELL_INFECTED_WOUND = 29307 // Used by the zombies on self. }; Position const PosSummon[3] = { - {3267.9f, -3172.1f, 297.42f, 0.94f}, - {3253.2f, -3132.3f, 297.42f, 0}, - {3308.3f, -3185.8f, 297.42f, 1.58f}, + { 3270.132f, -3169.948f, 297.5891f, 5.88176f }, + { 3307.298f, -3183.449f, 297.5891f, 5.742133f }, + { 3255.708f, -3135.677f, 297.5891f, 1.867502f } }; enum Events { - EVENT_WOUND = 1, + EVENT_WOUND = 1, EVENT_ENRAGE, EVENT_DECIMATE, EVENT_BERSERK, EVENT_SUMMON, + EVENT_SEARCH_ZOMBIE_SINGLE, + EVENT_KILL_ZOMBIE_SINGLE, + EVENT_SEARCH_ZOMBIE_MULTI }; -#define EMOTE_NEARBY " spots a nearby zombie to devour!" +enum States +{ + STATE_GLUTH_NORMAL = 1, + STATE_GLUTH_EATING = 2, + + STATE_ZOMBIE_NORMAL = 1, + STATE_ZOMBIE_DECIMATED = 2, + STATE_ZOMBIE_TOBE_EATEN = 3 +}; + +enum SummonGroups +{ + SUMMON_GROUP_CHOW_10MAN = 1, + SUMMON_GROUP_CHOW_25MAN = 2 +}; + +enum Misc +{ + EVENT_GLUTH_ZOMBIE_BEHAVIOR = 10495, // unused. event handled by spell_gluth_decimate_SpellScript::HandleEvent + DATA_ZOMBIE_STATE = 1, + ACTION_DECIMATE_EVENT = 2, +}; class boss_gluth : public CreatureScript { @@ -58,99 +94,387 @@ public: CreatureAI* GetAI(Creature* creature) const override { - return new boss_gluthAI(creature); + return GetInstanceAI<boss_gluthAI>(creature); } struct boss_gluthAI : public BossAI { - boss_gluthAI(Creature* creature) : BossAI(creature, BOSS_GLUTH) - { - // Do not let Gluth be affected by zombies' debuff - me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_INFECTED_WOUND, true); - } - void MoveInLineOfSight(Unit* who) override + boss_gluthAI(Creature* creature) : BossAI(creature, BOSS_GLUTH), state(STATE_GLUTH_NORMAL) {} + + void Reset() override { - if (who->GetEntry() == NPC_ZOMBIE && me->IsWithinDistInMap(who, 7)) - { - SetGazeOn(who); - /// @todo use a script text - me->TextEmote(EMOTE_NEARBY, nullptr, true); - } - else - BossAI::MoveInLineOfSight(who); + _Reset(); + zombieToBeEatenGUID.Clear(); + state = STATE_GLUTH_NORMAL; + me->SetReactState(REACT_AGGRESSIVE); + me->SetSpeed(UnitMoveType::MOVE_RUN, 12.0f); } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_WOUND, 10000); - events.ScheduleEvent(EVENT_ENRAGE, 15000); - events.ScheduleEvent(EVENT_DECIMATE, 105000); - events.ScheduleEvent(EVENT_BERSERK, 8*60000); - events.ScheduleEvent(EVENT_SUMMON, 15000); + events.ScheduleEvent(EVENT_WOUND, Seconds(10)); + events.ScheduleEvent(EVENT_ENRAGE, randtime(Seconds(16), Seconds(22))); + events.ScheduleEvent(EVENT_DECIMATE, randtime(Minutes(1)+Seconds(50), Minutes(2))); + events.ScheduleEvent(EVENT_BERSERK, Minutes(8)); + events.ScheduleEvent(EVENT_SUMMON, Seconds(15)); + events.ScheduleEvent(EVENT_SEARCH_ZOMBIE_SINGLE, Seconds(12)); } - void JustSummoned(Creature* summon) override + void SummonedCreatureDies(Creature* summoned, Unit* /* who */) override { - if (summon->GetEntry() == NPC_ZOMBIE) - summon->AI()->AttackStart(me); - summons.Summon(summon); + summons.Despawn(summoned); // needed or else dead zombies not despawned yet will still be in the list } void UpdateAI(uint32 diff) override { - if (!UpdateVictimWithGaze()) + if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_WOUND: + if (state == STATE_GLUTH_EATING) + { + events.Repeat(Seconds(3)); + break; + } + DoCastVictim(SPELL_MORTAL_WOUND); - events.ScheduleEvent(EVENT_WOUND, 10000); + events.Repeat(Seconds(10)); break; case EVENT_ENRAGE: - /// @todo Add missing text + if (state == STATE_GLUTH_EATING) + { + events.Repeat(Seconds(5)); + break; + } + + Talk(EMOTE_ENRAGE); DoCast(me, SPELL_ENRAGE); - events.ScheduleEvent(EVENT_ENRAGE, 15000); + events.Repeat(randtime(Seconds(16), Seconds(22))); break; case EVENT_DECIMATE: - /// @todo Add missing text + if (state == STATE_GLUTH_EATING) + { + events.Repeat(Seconds(4)); + break; + } + + Talk(EMOTE_DECIMATE); DoCastAOE(SPELL_DECIMATE); - events.ScheduleEvent(EVENT_DECIMATE, 105000); + for (int i = 1; i <= 20; i++) + events.ScheduleEvent(EVENT_SEARCH_ZOMBIE_MULTI, Seconds(3*i)); + events.ScheduleEvent(EVENT_DECIMATE, randtime(Minutes(1)+Seconds(50), Minutes(2))); break; case EVENT_BERSERK: + Talk(EMOTE_BERSERKER); DoCast(me, SPELL_BERSERK); - events.ScheduleEvent(EVENT_BERSERK, 5*60000); + events.Repeat(Minutes(5)); //refresh the hard enrage buff break; case EVENT_SUMMON: - for (int32 i = 0; i < RAID_MODE(1, 2); ++i) - DoSummon(NPC_ZOMBIE, PosSummon[rand32() % RAID_MODE(1, 3)]); - events.ScheduleEvent(EVENT_SUMMON, 10000); + if (Is25ManRaid()) // one wave each 10s. one wave=1 zombie in 10man and 2 zombies in 25man. + me->SummonCreatureGroup(SUMMON_GROUP_CHOW_25MAN); + else + me->SummonCreatureGroup(SUMMON_GROUP_CHOW_10MAN); + events.Repeat(Seconds(10)); + break; + case EVENT_SEARCH_ZOMBIE_SINGLE: + { + Creature* zombie = nullptr; + for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr) + { + zombie=ObjectAccessor::GetCreature(*me, *itr); + if (!zombie || !zombie->IsAlive() || !zombie->IsWithinDistInMap(me, 10.0)) + zombie = nullptr; + } + + if (zombie) + { + zombieToBeEatenGUID = zombie->GetGUID(); // save for later use + + // the soon-to-be-eaten zombie should stop moving and stop attacking + zombie->AI()->SetData(DATA_ZOMBIE_STATE, STATE_ZOMBIE_TOBE_EATEN); + + // gluth should stop AAs on his primary target and turn toward the zombie (2 yards away). He then pauses for a few seconds. + me->SetSpeed(MOVE_RUN, 36.0f); + + me->SetReactState(ReactStates::REACT_PASSIVE); + me->AttackStop(); + + Talk(EMOTE_SPOTS_ONE); + + //me->SetTarget(ObjectGuid::Empty); + + me->GetMotionMaster()->MoveCloserAndStop(1, zombie, 2.0f); + + state = STATE_GLUTH_EATING; + } + + events.Repeat(RAID_MODE(Seconds(7), Seconds(5))); + break; + } + case EVENT_KILL_ZOMBIE_SINGLE: + { + Creature* zombieToBeEaten = ObjectAccessor::GetCreature(*me, zombieToBeEatenGUID); + if (zombieToBeEaten && zombieToBeEaten->IsAlive() && zombieToBeEaten->IsWithinDistInMap(me, 10.0)) + DoCast(zombieToBeEaten, SPELL_ZOMBIE_CHOW_SEARCH_SINGLE); // do the killing + healing in done inside by spell script see below. + + zombieToBeEatenGUID = ObjectGuid::Empty; + state = STATE_GLUTH_NORMAL; + me->SetSpeed(UnitMoveType::MOVE_RUN, 12.0f); + + // and then return on primary target + me->SetReactState(REACT_AGGRESSIVE); + + break; + } + case EVENT_SEARCH_ZOMBIE_MULTI: + { + if (state == STATE_GLUTH_EATING) // skip and simply wait for the next occurence + break; + + Creature* zombie = nullptr; + for (SummonList::const_iterator itr = summons.begin(); !zombie && itr != summons.end(); ++itr) + { + zombie = ObjectAccessor::GetCreature(*me, *itr); + if (zombie && zombie->IsAlive() && zombie->GetExactDist2d(me) > 18.0) + zombie = nullptr; + } + + if (zombie) // cast the aoe spell only if at least one zombie is found nearby + { + Talk(EMOTE_DEVOURS_ALL); + DoCastAOE(SPELL_ZOMBIE_CHOW_SEARCH_MULTI); + } break; + } } } - if (me->GetVictim() && me->EnsureVictim()->GetEntry() == NPC_ZOMBIE) + DoMeleeAttackIfReady(); + } + + void MovementInform(uint32 /*type*/, uint32 id) override + { + if (id == 1){ + me->GetMotionMaster()->MoveIdle(); + events.ScheduleEvent(EVENT_KILL_ZOMBIE_SINGLE, Seconds(1)); + } + + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_DECIMATE_EVENT: + for (ObjectGuid zombieGuid : summons) + { + Creature* zombie = ObjectAccessor::GetCreature(*me, zombieGuid); + if (zombie && zombie->IsAlive()) + zombie->AI()->SetData(DATA_ZOMBIE_STATE, STATE_ZOMBIE_DECIMATED); + } + break; + } + } + + private: + ObjectGuid zombieToBeEatenGUID; + uint8 state; + }; + +}; + +// spell 28374 (10man) / 54426 (25man) - Decimate +class spell_gluth_decimate : public SpellScriptLoader +{ +public: + spell_gluth_decimate() : SpellScriptLoader("spell_gluth_decimate") { } + + class spell_gluth_decimate_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gluth_decimate_SpellScript); + + // handles the damaging effect of the decimate spell. + void HandleScriptEffect(SpellEffIndex /* index */) + { + if (Unit *unit = GetHitUnit()) { - if (me->IsWithinMeleeRange(me->GetVictim())) + int32 damage = int32(unit->GetHealth()) - int32(unit->CountPctFromMaxHealth(5)); + if (damage > 0) + GetCaster()->CastCustomSpell(SPELL_DECIMATE_DMG, SPELLVALUE_BASE_POINT0, damage, unit); + } + } + + // handles the change of zombies behavior after the decimate spell + void HandleEvent(SpellEffIndex /* index */) + { + GetCaster()->GetAI()->DoAction(ACTION_DECIMATE_EVENT); + } + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return (sSpellMgr->GetSpellInfo(SPELL_DECIMATE_DMG) != nullptr); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + OnEffectHit += SpellEffectFn(spell_gluth_decimate_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT); + } + + bool Load() override + { + return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH; + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gluth_decimate_SpellScript(); + } + +}; + +// used by both 28239 & 28404 (single target and aoe zombie-kill spell) to heal Gluth on each target hit. + +class spell_gluth_zombiechow_search : public SpellScriptLoader +{ +public: + spell_gluth_zombiechow_search() : SpellScriptLoader("spell_gluth_zombiechow_search") { } + + class spell_gluth_zombiechow_search_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gluth_zombiechow_search_SpellScript); + + void HealForEachTargetHit() + { + GetCaster()->ModifyHealth(int32(GetCaster()->CountPctFromMaxHealth(5))); + } + + void Register() override + { + AfterHit += SpellHitFn(spell_gluth_zombiechow_search_SpellScript::HealForEachTargetHit); + } + + bool Load() override + { + return GetCaster() && GetCaster()->GetEntry() == NPC_GLUTH; + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gluth_zombiechow_search_SpellScript(); + } + +}; + +// creature 16360 (10man) / 30303 (25man) +class npc_zombie_chow : public CreatureScript +{ +public: + + npc_zombie_chow() : CreatureScript("npc_zombie_chow") { } + + struct npc_zombie_chowAI : public ScriptedAI + { + npc_zombie_chowAI(Creature* creature) : ScriptedAI(creature) + { + GluthGUID = creature->GetInstanceScript()->GetGuidData(DATA_GLUTH); + + DoCast(me, SPELL_INFECTED_WOUND); + state = STATE_ZOMBIE_NORMAL; + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (state == STATE_ZOMBIE_DECIMATED) + { + timer += diff; + Creature* gluth = ObjectAccessor::GetCreature(*me, GluthGUID); + // Putting this in the UpdateAI loop fixes an issue where death gripping a decimated zombie would make the zombie stand still until the rest of the fight. + // Also fix the issue where if one or more zombie is rooted when decimates hits (and MovePoint() is called), the zombie teleport to the boss. pretty weird behavior. + if (gluth && timer>1600 && me->GetExactDist2d(gluth) > 10.0 && me->CanFreeMove()) // it takes about 1600 ms for the animation to cycle. This way, the animation looks relatively smooth. { - me->Kill(me->GetVictim()); - me->ModifyHealth(int32(me->CountPctFromMaxHealth(5))); + me->GetMotionMaster()->MovePoint(0, gluth->GetPosition()); // isn't dynamic. So, to take into account Gluth's movement, it must be called periodicly. + timer = 0; } + + if (me->GetExactDist2d(gluth) <= 10.0) + me->StopMoving(); } - else + else if (state == STATE_ZOMBIE_NORMAL) DoMeleeAttackIfReady(); } + + void SetData(uint32 id, uint32 value) override + { + if (id == DATA_ZOMBIE_STATE) // change of state + { + state = value; + if (value == STATE_ZOMBIE_DECIMATED) + { + me->SetReactState(ReactStates::REACT_PASSIVE); + me->AttackStop(); + me->SetTarget(ObjectGuid::Empty); + // at this point, the zombie should be non attacking and non moving. + + me->SetWalk(true); // it doesnt seem to work with MoveFollow() (but it does work with MovePoint()). + + timer = 1000; + } + else if (value == STATE_ZOMBIE_TOBE_EATEN) + { + // forced to stand still + me->GetMotionMaster()->Clear(); + me->StopMoving(); + + // and loose aggro behavior + me->SetReactState(ReactStates::REACT_PASSIVE); + me->AttackStop(); + me->SetTarget(ObjectGuid::Empty); + + me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_GRIP, true); // not sure if this is blizz-like but this is very convenient + } + } + } + + uint32 GetData(uint32 index) const override + { + if (index == DATA_ZOMBIE_STATE) + return state; + return 0; + } + + private: + uint32 timer; + uint8 state; + ObjectGuid GluthGUID; }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_zombie_chowAI>(creature); + } }; void AddSC_boss_gluth() { new boss_gluth(); + new spell_gluth_decimate(); + new spell_gluth_zombiechow_search(); + new npc_zombie_chow(); } diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index 02b82d255cd..e3971248513 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -153,6 +153,9 @@ class instance_naxxramas : public InstanceMapScript case NPC_SIR: SirGUID = creature->GetGUID(); break; + case NPC_GLUTH: + GluthGUID = creature->GetGUID(); + break; case NPC_HEIGAN: HeiganGUID = creature->GetGUID(); break; @@ -327,6 +330,8 @@ class instance_naxxramas : public InstanceMapScript return SirGUID; case DATA_HEIGAN: return HeiganGUID; + case DATA_GLUTH: + return GluthGUID; case DATA_FEUGEN: return FeugenGUID; case DATA_STALAGG: @@ -582,6 +587,8 @@ class instance_naxxramas : public InstanceMapScript ObjectGuid HorsemenChestGUID; /* The Construct Quarter */ + // Gluth + ObjectGuid GluthGUID; // Thaddius ObjectGuid ThaddiusGUID; ObjectGuid FeugenGUID; diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index bece5a60bee..a3fedf5aa40 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -68,6 +68,7 @@ enum Data64 DATA_LADY, DATA_BARON, DATA_SIR, + DATA_GLUTH, DATA_THADDIUS, DATA_HEIGAN, DATA_FEUGEN, @@ -92,6 +93,7 @@ enum CreaturesIds NPC_LADY = 16065, NPC_BARON = 30549, NPC_SIR = 16063, + NPC_GLUTH = 15932, NPC_HEIGAN = 15936, NPC_THADDIUS = 15928, NPC_FEUGEN = 15930, diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 277ca793a8f..f000d7a3ef7 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -377,7 +377,7 @@ public: me->SetDisableGravity(true); me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); // TO DO: find what in core is making boss slower than in retail (when correct speed data) or find missing movement flag update or forced spline change - me->SetSpeed(MOVE_FLIGHT, _flySpeed * 0.25f); + me->SetSpeedRate(MOVE_FLIGHT, _flySpeed * 0.25f); if (_despawned) DoAction(ACTION_HANDLE_RESPAWN); @@ -603,7 +603,7 @@ public: me->SetRespawnDelay(respawnDelay); // Set speed to normal value - me->SetSpeed(MOVE_FLIGHT, _flySpeed); + me->SetSpeedRate(MOVE_FLIGHT, _flySpeed); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->RemoveAllAuras(); @@ -1165,7 +1165,7 @@ public: _instance = creature->GetInstanceScript(); me->SetReactState(REACT_PASSIVE); // TO DO: These were a bit faster than what they should be. Not sure what is the reason. - me->SetSpeed(MOVE_FLIGHT, 1.25f); + me->SetSpeedRate(MOVE_FLIGHT, 1.25f); } void Initialize() @@ -1274,7 +1274,7 @@ public: me->SetReactState(REACT_PASSIVE); // TO DO: Something is wrong with calculations for flying creatures that are on WP/Cyclic path. // They should get the same difference as to when at ground from run creature switch to walk. - me->SetSpeed(MOVE_FLIGHT, 0.45f); + me->SetSpeedRate(MOVE_FLIGHT, 0.45f); } void Reset() override @@ -1566,7 +1566,7 @@ public: { me->DespawnOrUnsummon(2050); me->SetOrientation(2.5f); - me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); Position pos = me->GetPosition(); pos.m_positionX += 10.0f; pos.m_positionY += 10.0f; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp index e1a4a6ed7b8..3d9ea97b136 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp @@ -375,7 +375,7 @@ class npc_ruby_emerald_amber_drake : public CreatureScript { me->DespawnOrUnsummon(2050); me->SetOrientation(2.5f); - me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); Talk(SAY_DRAKES_TAKEOFF); Position pos = me->GetPosition(); Position offset = { 10.0f, 10.0f, 12.0f, 0.0f }; diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp index a98da2c6e3d..8f7687d0fca 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp @@ -174,7 +174,7 @@ public: { if (pSpark->IsAlive()) { - pSpark->SetSpeed(MOVE_RUN, 2.0f); + pSpark->SetSpeedRate(MOVE_RUN, 2.0f); pSpark->GetMotionMaster()->Clear(); pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } @@ -355,7 +355,7 @@ public: { Position pos = ionar->GetPosition(); - me->SetSpeed(MOVE_RUN, 2.0f); + me->SetSpeedRate(MOVE_RUN, 2.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos); } diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp index 0714f2426bc..8aa443cba3f 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_mimiron.cpp @@ -703,7 +703,7 @@ class boss_leviathan_mk_ii : public CreatureScript if (Unit* turret = me->GetVehicleKit()->GetPassenger(3)) turret->KillSelf(); - me->SetSpeed(MOVE_RUN, 1.5f, true); + me->SetSpeedRate(MOVE_RUN, 1.5f); me->GetMotionMaster()->MovePoint(WP_MKII_P1_IDLE, VehicleRelocation[WP_MKII_P1_IDLE]); } else if (events.IsInPhase(PHASE_VOL7RON)) diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp index f5337b2dca5..363f5907048 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp @@ -366,7 +366,7 @@ class boss_razorscale : public CreatureScript _EnterCombat(); if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAZORSCALE_CONTROL))) controller->AI()->DoAction(ACTION_HARPOON_BUILD); - me->SetSpeed(MOVE_FLIGHT, 3.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 3.0f); me->SetReactState(REACT_PASSIVE); phase = PHASE_GROUND; events.SetPhase(PHASE_GROUND); @@ -550,7 +550,7 @@ class boss_razorscale : public CreatureScript me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED); me->SetReactState(REACT_AGGRESSIVE); me->RemoveAurasDueToSpell(SPELL_HARPOON_TRIGGER); - me->SetSpeed(MOVE_FLIGHT, 1.0f, true); + me->SetSpeedRate(MOVE_FLIGHT, 1.0f); PermaGround = true; DoCastAOE(SPELL_FLAMEBREATH); events.ScheduleEvent(EVENT_FLAME, 15000, 0, PHASE_PERMAGROUND); @@ -677,7 +677,7 @@ class npc_expedition_commander : public CreatureScript if (Creature* summonedEngineer = me->SummonCreature(NPC_ENGINEER, PosEngSpawn, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3000)) { summonedEngineer->SetWalk(false); - summonedEngineer->SetSpeed(MOVE_RUN, 0.5f); + summonedEngineer->SetSpeedRate(MOVE_RUN, 0.5f); summonedEngineer->SetHomePosition(PosEngRepair[n]); summonedEngineer->GetMotionMaster()->MoveTargetedHome(); Engineer[n] = summonedEngineer->GetGUID(); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp index 1af45f3031a..ee71c696d7c 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp @@ -746,7 +746,7 @@ public: //! HACK: Creature's can't have MOVEMENTFLAG_FLYING me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING); me->RemoveAurasDueToSpell(SPELL_ORB_VISUAL); - me->SetSpeed(MOVE_FLIGHT, 0.5f); + me->SetSpeedRate(MOVE_FLIGHT, 0.5f); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp index d7b65093898..7615217a794 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp @@ -209,7 +209,7 @@ public: Initialize(); Summons.DespawnAll(); - me->SetSpeed(MOVE_FLIGHT, 3.0f); + me->SetSpeedRate(MOVE_FLIGHT, 3.0f); if ((ObjectAccessor::GetCreature(*me, m_uiGraufGUID) == NULL) && !me->IsMounted()) me->SummonCreature(NPC_GRAUF, Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 3.0f); instance->SetBossState(DATA_SKADI_THE_RUTHLESS, NOT_STARTED); diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 1e020edd10a..3d801cc2fbb 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -712,7 +712,7 @@ enum BorrowedTechnologyAndVolatility SPELL_PING_BUNNY = 59375, SPELL_IMMOLATION = 54690, SPELL_EXPLOSION = 59335, - SPELL_RIDE = 56687, + SPELL_RIDE = 59319, // Points POINT_GRAB_DECOY = 1, diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 7902c585509..3c651e10a1e 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -745,7 +745,7 @@ public: if (!Trigger) return; - Trigger->SetSpeed(MOVE_WALK, 3); + Trigger->SetSpeedRate(MOVE_WALK, 3); Trigger->SetWalk(true); Trigger->GetMotionMaster()->MovePoint(0, final.x, final.y, final.z); @@ -1524,7 +1524,7 @@ public: void BeginWalk() { me->SetWalk(false); - me->SetSpeed(MOVE_RUN, 1.0f); + me->SetSpeedRate(MOVE_RUN, 1.0f); me->GetMotionMaster()->MovePoint(0, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z); } 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 7e1215488e1..1a9074c2464 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_shade_of_akama.cpp @@ -238,8 +238,8 @@ public: if (me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2) <= 3) { moveSpeed = (2.0f - (0.6f * me->GetAuraCount(SPELL_SHADE_SOUL_CHANNEL_2))); - me->SetSpeed(MOVE_WALK, moveSpeed / 2.5f); - me->SetSpeed(MOVE_RUN, (moveSpeed * 2) / 7); + me->SetSpeedRate(MOVE_WALK, moveSpeed / 2.5f); + me->SetSpeedRate(MOVE_RUN, (moveSpeed * 2) / 7); me->ClearUnitState(UNIT_STATE_ROOT); } else diff --git a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp index ae4d17bdad4..0999f1fcd6b 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_supremus.cpp @@ -117,7 +117,7 @@ public: DummyEntryCheckPredicate pred; summons.DoAction(EVENT_VOLCANO, pred); events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE); - me->SetSpeed(MOVE_RUN, 1.2f); + me->SetSpeedRate(MOVE_RUN, 1.2f); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); } @@ -126,7 +126,7 @@ public: phase = PHASE_CHASE; events.ScheduleEvent(EVENT_VOLCANO, 5000, GCD_CAST, PHASE_CHASE); events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE); - me->SetSpeed(MOVE_RUN, 0.9f); + me->SetSpeedRate(MOVE_RUN, 0.9f); me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); } 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 e24499c3aee..3ddf0fec416 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp @@ -585,8 +585,8 @@ public: void Reset() override { - me->SetSpeed(MOVE_WALK, 0.6f); // walk - me->SetSpeed(MOVE_RUN, 0.6f); // run + me->SetSpeedRate(MOVE_WALK, 0.6f); // walk + me->SetSpeedRate(MOVE_RUN, 0.6f); // run Initialize(); //search for nearest waypoint (up on stairs) diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp index 8d117f7c3ef..f72b9a8d2ca 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp @@ -244,7 +244,7 @@ public: CheckChannelers(); Initialize(); me->SetCanDualWield(true); - me->SetSpeed(MOVE_RUN, 2.0f, true); + me->SetSpeedRate(MOVE_RUN, 2.0f); me->SetDisplayId(MODEL_NIGHTELF); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID , 0); me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp new file mode 100644 index 00000000000..c5969c7b15a --- /dev/null +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp @@ -0,0 +1,1051 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * 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/>. + */ + +#include "CreatureTextMgr.h" +#include "LFGMgr.h" +#include "ScriptedGossip.h" +#include "ScriptedCreature.h" +#include "ScriptMgr.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" +#include "the_slave_pens.h" + +enum Spells +{ + // Ahune + SPELL_SYNCH_HEALTH = 46430, + SPELL_AHUNES_SHIELD = 45954, + SPELL_STAY_SUBMERGED = 46981, + SPELL_AHUNE_SELF_STUN = 46416, + SPELL_AHUNE_ACHIEVEMENT = 62043, + SPELL_AHUNE_SPANKY_HANDS = 46146, + SPELL_COLD_SLAP = 46145, + SPELL_RESURFACE = 46402, + SPELL_SUBMERGED = 37751, + SPELL_STAND = 37752, + + //Earther Ring Flamecaller + SPELL_FIND_OPENING_VISUAL = 45964, + SPELL_FIND_OPENING_BEAM_END = 46333, + SPELL_FIND_OPENING_TRIGGER = 46341, + SPELL_FIND_OPENING_CHANNEL = 46345, + SPELL_BONFIRE_VISUAL = 46339, + SPELL_FOUND_OPENING = 46421, + + //Ahune Bunny + SPELL_SUMMON_COLDWEAVE = 46143, + SPELL_SUMMON_FROSTWIND = 46382, + SPELL_SUMMON_HAILSTONE = 46176, + SPELL_SUMMONING_VISUAL_1 = 45937, + SPELL_SUMMONING_RHYME_AURA = 45926, + SPELL_SUMMONING_RHYME_BONFIRE = 45930, + SPELL_FORCE_WHISP_FLIGHT = 46603, + SPELL_SHAMANS_LOOK_FOR_OPENING = 46422, + SPELL_CLOSE_OPENING_VISUAL = 46236, + SPELL_ICE_BOMBARD = 46397, + SPELL_ICE_BOMBARDMENT_DEST_PICKER = 46398, + SPELL_ICE_BOMBARDMENT = 46396, + + // Ice Spear + SPELL_SUMMON_ICE_SPEAR_BUNNY = 46359, + SPELL_ICE_SPEAR_KNOCKBACK = 46360, + SPELL_SUMMON_ICE_SPEAR_GO = 46369, + SPELL_ICE_SPEAR_AURA = 46371, + SPELL_ICE_SPEAR_TARGET_PICKER = 46372, + SPELL_ICE_SPEAR_DELAY = 46878, + SPELL_ICE_SPEAR_VISUAL = 75498, + + // Slippery Floor + SPELL_SLIPPERY_FLOOR_AMBIENT = 46314, + SPELL_SLIPPERY_FLOOR_PERIODIC = 46320, + SPELL_SLIPPERY_FLOOR_SLIP = 45947, + + // Frozen Core + SPELL_SUICIDE = 45254, + SPELL_SUMMON_LOOT_MISSILE = 45941, + SPELL_FROZEN_CORE_GETS_HIT = 46810, + SPELL_MINION_DESPAWNER = 46843, + SPELL_GHOST_DISGUISE = 46786 +}; + +enum Emotes +{ + EMOTE_EARTHEN_ASSAULT = 0, + EMOTE_RETREAT = 0, + EMOTE_RESURFACE = 1 +}; + +enum Says +{ + SAY_PLAYER_TEXT_1 = 0, + SAY_PLAYER_TEXT_2 = 1, + SAY_PLAYER_TEXT_3 = 2 +}; + +enum Events +{ + EVENT_EMERGE = 1, + EVENT_INITIAL_EMERGE = 2, + EVENT_SYNCH_HEALTH = 3, + EVENT_FOUND_OPENING = 4, + EVENT_LOOKFOROPENING_0 = 5, + EVENT_LOOKFOROPENING_1 = 6, + EVENT_LOOKFOROPENING_2 = 7, + EVENT_SUMMON_HAILSTONE = 8, + EVENT_SUMMON_COLDWEAVE = 9, + EVENT_SUMMON_FROSTWIND = 10, + EVENT_SUMMON_AHUNE = 11, + EVENT_CLOSE_OPENING = 12, + EVENT_AHUNE_PHASE_ONE = 13, + EVENT_AHUNE_PHASE_TWO = 14, + EVENT_START_LOOKING_FOR_OPENING = 15, + EVENT_STOP_LOOKING_FOR_OPENING = 16 +}; + +enum Actions +{ + ACTION_START_EVENT = -2574500, + ACTION_AHUNE_RETREAT = -2586500, + ACTION_AHUNE_RESURFACE = -2586501, + ACTION_EMOTE_RESURFACE = -2575400 +}; + +enum Phases +{ + PHASE_ONE = 0, + PHASE_TWO = 1 +}; + +enum Points +{ + POINT_FLAMECALLER_000, + POINT_FLAMECALLER_001, + POINT_FLAMECALLER_002 +}; + +enum Misc +{ + MAX_FLAMECALLERS = 3 +}; + +Position const SummonPositions[] = +{ + { -99.1021f, -233.7526f, -1.22307f, 1.588250f }, // Ahune + { -98.0151f, -230.4555f, -1.21089f, 1.797689f }, // Frozen Core + { -143.172f, -147.6801f, -3.16113f, 4.852015f }, // Bonfire Bunny 000 + { -134.304f, -145.7803f, -1.70332f, 4.677482f }, // Bonfire Bunny 001 + { -125.036f, -144.2065f, -1.91660f, 4.991642f }, // Bonfire Bunny 002 + { -69.8121f, -162.4954f, -2.30451f, 1.710423f }, // Wisp Source Bunny + { -98.1029f, -230.7864f, -10.8085f, 1.448623f } // Wisp Dest Bunny +}; + +Position const FlameCallerSpots[] = +{ + { -145.2233f, -137.5543f, -1.59056f, 5.427049f }, + { -137.4383f, -136.4050f, -1.72384f, 5.336747f }, + { -129.0413f, -132.1494f, -2.09285f, 5.460842f } +}; + +class boss_ahune : public CreatureScript +{ +public: + boss_ahune() : CreatureScript("boss_ahune") { } + + struct boss_ahuneAI : public BossAI + { + boss_ahuneAI(Creature* creature) : BossAI(creature, DATA_AHUNE) + { + Initialize(); + } + + void Initialize() + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + events.ScheduleEvent(EVENT_INITIAL_EMERGE, 4); + events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AHUNE_BUNNY))) + ahuneBunny->AI()->EnterEvadeMode(); + summons.DespawnAll(); + me->DespawnOrUnsummon(); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + instance->DoCastSpellOnPlayers(SPELL_AHUNE_ACHIEVEMENT); + + if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_AHUNE_BUNNY))) + me->Kill(ahuneBunny); + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + me->Kill(frozenCore); + + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + if (!players.isEmpty()) + { + if (Group* group = players.begin()->GetSource()->GetGroup()) + if (group->isLFGGroup()) + sLFGMgr->FinishDungeon(group->GetGUID(), 286); + } + } + + void JustSummoned(Creature* summon) override + { + BossAI::JustSummoned(summon); + } + + void DoAction(int32 action) override + { + if (action == ACTION_AHUNE_RETREAT) + { + Submerge(); + events.ScheduleEvent(EVENT_EMERGE, 35000); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INITIAL_EMERGE: + DoCast(me, SPELL_STAND); + DoCast(me, SPELL_AHUNE_SPANKY_HANDS); + DoCast(me, SPELL_AHUNES_SHIELD); + break; + case EVENT_EMERGE: + Emerge(); + break; + case EVENT_SYNCH_HEALTH: + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + DoCast(frozenCore, SPELL_SYNCH_HEALTH); + else + DoCast(me, SPELL_SUICIDE); + events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } + + void Emerge() + { + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + frozenCore->AI()->DoAction(ACTION_AHUNE_RESURFACE); + + DoCast(me, SPELL_AHUNES_SHIELD); + me->RemoveAurasDueToSpell(SPELL_AHUNE_SELF_STUN); + me->RemoveAurasDueToSpell(SPELL_STAY_SUBMERGED); + DoCast(me, SPELL_STAND); + DoCast(me, SPELL_RESURFACE, true); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + } + + void Submerge() + { + if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE))) + frozenCore->AI()->DoAction(ACTION_AHUNE_RETREAT); + me->RemoveAurasDueToSpell(SPELL_AHUNES_SHIELD); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_SUBMERGED, true); + DoCast(me, SPELL_AHUNE_SELF_STUN, true); + DoCast(me, SPELL_STAY_SUBMERGED, true); + me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); + events.Reset(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_ahuneAI>(creature); + } +}; + +class npc_frozen_core : public CreatureScript +{ +public: + npc_frozen_core() : CreatureScript("npc_frozen_core") { } + + struct npc_frozen_coreAI : public ScriptedAI + { + npc_frozen_coreAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + Initialize(); + } + + void Initialize() + { + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + DoCast(me, SPELL_FROZEN_CORE_GETS_HIT); + DoCast(me, SPELL_ICE_SPEAR_AURA); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + DoCast(SPELL_MINION_DESPAWNER); + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + ahune->AI()->EnterEvadeMode(); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + me->Kill(ahune); + + DoCast(SPELL_SUMMON_LOOT_MISSILE); + DoCast(SPELL_MINION_DESPAWNER); + } + + void DoAction(int32 action) override + { + if (action == ACTION_AHUNE_RETREAT) + { + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC); + me->RemoveAurasDueToSpell(SPELL_ICE_SPEAR_AURA); + _events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000, 0, PHASE_TWO); + } + else if (action == ACTION_AHUNE_RESURFACE) + { + _events.Reset(); + DoCast(me, SPELL_ICE_SPEAR_AURA); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_DISABLE_MOVE); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SYNCH_HEALTH: + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + DoCast(ahune, SPELL_SYNCH_HEALTH); + else + DoCast(me, SPELL_SUICIDE); + _events.ScheduleEvent(EVENT_SYNCH_HEALTH, 3000); + break; + default: + break; + } + } + } + + private: + InstanceScript* _instance; + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_frozen_coreAI>(creature); + } +}; + +class npc_ahune_bunny : public CreatureScript +{ +public: + npc_ahune_bunny() : CreatureScript("npc_ahune_bunny") { } + + struct npc_ahune_bunnyAI : public ScriptedAI + { + npc_ahune_bunnyAI(Creature* creature) : ScriptedAI(creature), _summons(me) + { + _instance = me->GetInstanceScript(); + _submerged = false; + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_AHUNE) + return; + + summon->SetInCombatWithZone(); + _summons.Summon(summon); + } + + void JustDied(Unit* /*killer*/) override + { + _summons.DespawnAll(); + ResetFlameCallers(); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + _summons.DespawnAll(); + ResetFlameCallers(); + + me->SummonGameObject(GO_ICE_STONE, -69.90455f, -162.2449f, -2.366563f, 2.426008f, 0.0f, 0.0f, 0.9366722f, 0.3502074f, 0); + } + + void DoAction(int32 action) override + { + if (action == ACTION_START_EVENT) + { + DoCast(me, SPELL_SUMMONING_VISUAL_1); + me->SummonCreature(NPC_WHISP_SOURCE_BUNNY, SummonPositions[5], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_WHISP_DEST_BUNNY, SummonPositions[6], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SHAMAN_BONFIRE_BUNNY_000, SummonPositions[2], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SHAMAN_BONFIRE_BUNNY_001, SummonPositions[3], TEMPSUMMON_MANUAL_DESPAWN); + me->SummonCreature(NPC_SHAMAN_BONFIRE_BUNNY_002, SummonPositions[4], TEMPSUMMON_MANUAL_DESPAWN); + + for (uint8 counter = 0; counter < MAX_FLAMECALLERS; ++counter) + if (Creature* flameCaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000 + counter))) + flameCaller->GetMotionMaster()->MovePoint(counter, FlameCallerSpots[counter].GetPosition()); + + _submerged = false; + _events.Reset(); + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_AHUNE, 10000); + _events.ScheduleEvent(EVENT_START_LOOKING_FOR_OPENING, 14000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_COLDWEAVE, 22000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_HAILSTONE, 14000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_AHUNE_PHASE_TWO, 108000, 0, PHASE_ONE); + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_START_LOOKING_FOR_OPENING: + Talk(EMOTE_EARTHEN_ASSAULT); + for (uint8 counter = 0; counter < MAX_FLAMECALLERS; ++counter) + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000 + counter))) + DoCast(flamecaller, SPELL_SHAMANS_LOOK_FOR_OPENING, true); + break; + case EVENT_SUMMON_HAILSTONE: + DoCast(SPELL_SUMMON_HAILSTONE); + break; + case EVENT_SUMMON_COLDWEAVE: + DoCast(SPELL_SUMMON_COLDWEAVE); + DoCast(SPELL_SUMMON_COLDWEAVE); + _events.ScheduleEvent(EVENT_SUMMON_COLDWEAVE, 8000, 0, PHASE_ONE); + if (_submerged) + _events.ScheduleEvent(EVENT_SUMMON_FROSTWIND, 4000, 0, PHASE_ONE); + break; + case EVENT_SUMMON_FROSTWIND: + DoCast(SPELL_SUMMON_FROSTWIND); + break; + case EVENT_SUMMON_AHUNE: + if (TempSummon* ahune = me->SummonCreature(NPC_AHUNE, SummonPositions[0], TEMPSUMMON_DEAD_DESPAWN)) + { + ahune->SummonCreature(NPC_FROZEN_CORE, SummonPositions[1], TEMPSUMMON_CORPSE_DESPAWN); + ahune->SetInCombatWithZone(); + DoCast(ahune, SPELL_RESURFACE); + } + break; + case EVENT_CLOSE_OPENING: + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000))) + flamecaller->AI()->DoAction(ACTION_EMOTE_RESURFACE); + DoCast(SPELL_CLOSE_OPENING_VISUAL); + DoCast(me, SPELL_ICE_BOMBARD); + break; + case EVENT_AHUNE_PHASE_TWO: + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000))) + DoCast(flamecaller, SPELL_FOUND_OPENING); + if (Creature* ahune = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_AHUNE))) + ahune->AI()->DoAction(ACTION_AHUNE_RETREAT); + _events.Reset(); + _events.SetPhase(PHASE_TWO); + _events.ScheduleEvent(EVENT_CLOSE_OPENING, 25000, 0, PHASE_TWO); + _events.ScheduleEvent(EVENT_AHUNE_PHASE_ONE, 35000, 0, PHASE_TWO); + break; + case EVENT_AHUNE_PHASE_ONE: + _submerged = true; + _events.Reset(); + _events.SetPhase(PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_COLDWEAVE, 8000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_SUMMON_HAILSTONE, 5000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_START_LOOKING_FOR_OPENING, 5000, 0, PHASE_ONE); + _events.ScheduleEvent(EVENT_AHUNE_PHASE_TWO, 100000, 0, PHASE_ONE); + break; + default: + break; + } + } + } + + void ResetFlameCallers() + { + for (uint8 counter = 0; counter < MAX_FLAMECALLERS; ++counter) + if (Creature* flamecaller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FLAMECALLER_000 + counter))) + flamecaller->AI()->EnterEvadeMode(); + } + + private: + InstanceScript* _instance; + EventMap _events; + SummonList _summons; + bool _submerged; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_ahune_bunnyAI>(creature); + } +}; + +class npc_earthen_ring_flamecaller : public CreatureScript +{ +public: + npc_earthen_ring_flamecaller() : CreatureScript("npc_earthen_ring_flamecaller") { } + + struct npc_earthen_ring_flamecallerAI : public ScriptedAI + { + npc_earthen_ring_flamecallerAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + } + + void Reset() override + { + _events.Reset(); + } + + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_FLAMECALLER_000: + _mySpot = POINT_FLAMECALLER_000; + me->SetOrientation(FlameCallerSpots[_mySpot].GetOrientation()); + break; + case POINT_FLAMECALLER_001: + _mySpot = POINT_FLAMECALLER_001; + me->SetOrientation(FlameCallerSpots[_mySpot].GetOrientation()); + break; + case POINT_FLAMECALLER_002: + _mySpot = POINT_FLAMECALLER_002; + me->SetOrientation(FlameCallerSpots[_mySpot].GetOrientation()); + break; + default: + break; + } + + DoCast(me, SPELL_FIND_OPENING_CHANNEL); + } + + void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override + { + switch (spellInfo->Id) + { + case SPELL_SHAMANS_LOOK_FOR_OPENING: + _events.ScheduleEvent(EVENT_LOOKFOROPENING_0, 17000); + break; + case SPELL_FOUND_OPENING: + _events.ScheduleEvent(EVENT_FOUND_OPENING, 0); + break; + default: + break; + } + } + + void DoAction(int action) override + { + if (action == ACTION_EMOTE_RESURFACE) + Talk(EMOTE_RESURFACE); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_LOOKFOROPENING_0: + LookOpening(true, 0); + _events.ScheduleEvent(EVENT_LOOKFOROPENING_1, 26000); + break; + case EVENT_LOOKFOROPENING_1: + LookOpening(true, 1); + _events.ScheduleEvent(EVENT_LOOKFOROPENING_2, 25000); + break; + case EVENT_LOOKFOROPENING_2: + LookOpening(true, 2); + _events.ScheduleEvent(EVENT_STOP_LOOKING_FOR_OPENING, 27000); + break; + case EVENT_STOP_LOOKING_FOR_OPENING: + LookOpening(false, _mySpot); + break; + case EVENT_FOUND_OPENING: + Talk(EMOTE_RETREAT); + default: + break; + } + } + } + + void LookOpening(bool activate, uint8 spot) + { + if (_mySpot != spot) + return; + + if (Creature* bonfireBunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BONFIRE_BUNNY_000 + spot))) + if (Creature* beamBunny = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_BEAM_BUNNY_000 + spot))) + { + if (activate) + { + DoCast(bonfireBunny, SPELL_FIND_OPENING_TRIGGER); + bonfireBunny->CastSpell(beamBunny, SPELL_FIND_OPENING_VISUAL, true); + } + else + { + DoCast(me, SPELL_FIND_OPENING_CHANNEL); + bonfireBunny->CastStop(); + beamBunny->RemoveAurasDueToSpell(SPELL_FIND_OPENING_BEAM_END); + } + } + } + + private: + EventMap _events; + InstanceScript* _instance; + uint8 _mySpot; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<npc_earthen_ring_flamecallerAI>(creature); + } +}; + +class go_ahune_ice_stone : public GameObjectScript +{ +public: + go_ahune_ice_stone() : GameObjectScript("go_ahune_ice_stone") { } + + bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) + { + InstanceScript* instance = go->GetInstanceScript(); + if (!instance) + return false; + + player->PlayerTalkClass->ClearMenus(); + + if (Creature* ahuneBunny = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_AHUNE_BUNNY))) + { + ahuneBunny->AI()->DoAction(ACTION_START_EVENT); + ahuneBunny->SetInCombatWithZone(); + } + if (Creature* luma = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_LUMA_SKYMOTHER))) + luma->CastSpell(player, SPELL_SUMMONING_RHYME_AURA, true); + player->CLOSE_GOSSIP_MENU(); + go->Delete(); + + return true; + } +}; + +// 46430 - Synch Health +class spell_ahune_synch_health : public SpellScriptLoader +{ +public: + spell_ahune_synch_health() : SpellScriptLoader("spell_ahune_synch_health") { } + + class spell_ahune_synch_health_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ahune_synch_health_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SYNCH_HEALTH)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + if (Unit* caster = GetCaster()) + target->SetHealth(caster->GetHealth()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ahune_synch_health_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ahune_synch_health_SpellScript(); + } +}; + +// 45926 - Summoning Rhyme Aura +class spell_summoning_rhyme_aura : public SpellScriptLoader +{ +public: + spell_summoning_rhyme_aura() : SpellScriptLoader("spell_summoning_rhyme_aura") { } + + class spell_summoning_rhyme_aura_AuraScript : public AuraScript + { + PrepareAuraScript(spell_summoning_rhyme_aura_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_FORCE_WHISP_FLIGHT) || !sSpellMgr->GetSpellInfo(SPELL_SUMMONING_RHYME_BONFIRE)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* aurEff) + { + Creature* caster = GetCaster()->ToCreature(); + Player* player = GetTarget()->ToPlayer(); + + if (!caster || !player) + return; + + player->CastSpell(player, SPELL_FORCE_WHISP_FLIGHT); + + switch (aurEff->GetTickNumber()) + { + case 1: + sCreatureTextMgr->SendChat(caster, SAY_PLAYER_TEXT_1, NULL, CHAT_MSG_SAY, LANG_UNIVERSAL, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player); + player->CastSpell(player, SPELL_SUMMONING_RHYME_BONFIRE, true); + break; + case 2: + sCreatureTextMgr->SendChat(caster, SAY_PLAYER_TEXT_2, NULL, CHAT_MSG_SAY, LANG_UNIVERSAL, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player); + break; + case 3: + sCreatureTextMgr->SendChat(caster, SAY_PLAYER_TEXT_3, NULL, CHAT_MSG_SAY, LANG_UNIVERSAL, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player); + Remove(); + break; + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_summoning_rhyme_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_summoning_rhyme_aura_AuraScript(); + } +}; + +// 46878 - Summon Ice Spear Delayer +class spell_summon_ice_spear_delayer : public SpellScriptLoader +{ +public: + spell_summon_ice_spear_delayer() : SpellScriptLoader("spell_summon_ice_spear_delayer") { } + + class spell_summon_ice_spear_delayer_AuraScript : public AuraScript + { + PrepareAuraScript(spell_summon_ice_spear_delayer_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ICE_SPEAR_GO) || !sSpellMgr->GetSpellInfo(SPELL_ICE_SPEAR_KNOCKBACK)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* aurEff) + { + if (Creature* caster = GetCaster()->ToCreature()) + switch (aurEff->GetTickNumber()) + { + case 1: + caster->CastSpell(caster, SPELL_SUMMON_ICE_SPEAR_GO); + break; + case 3: + if (GameObject* spike = caster->FindNearestGameObject(GO_ICE_SPEAR, 3.0f)) + spike->UseDoorOrButton(); + caster->AI()->DoCastAOE(SPELL_ICE_SPEAR_KNOCKBACK, true); + break; + case 5: + if (GameObject* spike = caster->FindNearestGameObject(GO_ICE_SPEAR, 3.0f)) + spike->Delete(); + caster->DespawnOrUnsummon(); + break; + default: + break; + } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_summon_ice_spear_delayer_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_summon_ice_spear_delayer_AuraScript(); + } +}; + +// 46371 - Ice Spear Control Aura +class spell_ice_spear_control_aura : public SpellScriptLoader +{ +public: + spell_ice_spear_control_aura() : SpellScriptLoader("spell_ice_spear_control_aura") { } + + class spell_ice_spear_control_aura_AuraScript : public AuraScript + { + PrepareAuraScript(spell_ice_spear_control_aura_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ICE_SPEAR_TARGET_PICKER)) + return false; + return true; + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, SPELL_ICE_SPEAR_TARGET_PICKER); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_ice_spear_control_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_ice_spear_control_aura_AuraScript(); + } +}; + +// 46372 - Ice Spear Target Picker +class spell_ice_spear_target_picker : public SpellScriptLoader +{ +public: + spell_ice_spear_target_picker() : SpellScriptLoader("spell_ice_spear_target_picker") { } + + class spell_ice_spear_target_picker_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ice_spear_target_picker_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ICE_SPEAR_BUNNY)) + return false; + return true; + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_ICE_SPEAR_BUNNY, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ice_spear_target_picker_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ice_spear_target_picker_SpellScript(); + } +}; + +// 46320 - Spell Slippery Floor Periodic +class spell_slippery_floor_periodic : public SpellScriptLoader +{ +public: + spell_slippery_floor_periodic() : SpellScriptLoader("spell_slippery_floor_periodic") { } + + class spell_slippery_floor_periodic_SpellScript : public SpellScript + { + PrepareSpellScript(spell_slippery_floor_periodic_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SLIPPERY_FLOOR_SLIP)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + if (target->isMoving()) + target->CastSpell(target, SPELL_SLIPPERY_FLOOR_SLIP, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_slippery_floor_periodic_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_slippery_floor_periodic_SpellScript(); + } +}; + +// 46146 - Ahune Spanky Hands +class spell_ahune_spanky_hands : public SpellScriptLoader +{ +public: + spell_ahune_spanky_hands() : SpellScriptLoader("spell_ahune_spanky_hands") { } + + class spell_ahune_spanky_hands_AuraScript : public AuraScript + { + PrepareAuraScript(spell_ahune_spanky_hands_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_COLD_SLAP)) + return false; + return true; + } + + void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo) + { + PreventDefaultAction(); + GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_COLD_SLAP, true); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_ahune_spanky_hands_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_ahune_spanky_hands_AuraScript(); + } +}; + +class spell_ahune_minion_despawner : public SpellScriptLoader +{ +public: + spell_ahune_minion_despawner() : SpellScriptLoader("spell_ahune_minion_despawner") { } + + class spell_ahune_minion_despawner_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ahune_minion_despawner_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (GetHitCreature()) + GetHitCreature()->DespawnOrUnsummon(); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_ahune_minion_despawner_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ahune_minion_despawner_SpellScript(); + } +}; + +// 46398 - Spell Ice Bombardment Dest Picker +class spell_ice_bombardment_dest_picker : public SpellScriptLoader +{ +public: + spell_ice_bombardment_dest_picker() : SpellScriptLoader("spell_ice_bombardment_dest_picker") { } + + class spell_ice_bombardment_dest_picker_SpellScript : public SpellScript + { + PrepareSpellScript(spell_ice_bombardment_dest_picker_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_ICE_BOMBARDMENT)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitDest()->GetPositionX(), GetHitDest()->GetPositionY(), GetHitDest()->GetPositionZ(), SPELL_ICE_BOMBARDMENT, true); + } + + void Register() override + { + OnEffectHit += SpellEffectFn(spell_ice_bombardment_dest_picker_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_ice_bombardment_dest_picker_SpellScript(); + } +}; + +void AddSC_boss_ahune() +{ + new boss_ahune(); + new npc_frozen_core(); + new npc_earthen_ring_flamecaller(); + new npc_ahune_bunny(); + new go_ahune_ice_stone(); + new spell_ahune_synch_health(); + new spell_summoning_rhyme_aura(); + new spell_summon_ice_spear_delayer(); + new spell_ice_spear_control_aura(); + new spell_slippery_floor_periodic(); + new spell_ahune_spanky_hands(); + new spell_ahune_minion_despawner(); + new spell_ice_spear_target_picker(); + new spell_ice_bombardment_dest_picker(); +} diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp index 87a07cd1e5e..0fac7b5a39d 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp @@ -31,15 +31,125 @@ class instance_the_slave_pens : public InstanceMapScript public: instance_the_slave_pens() : InstanceMapScript(SPScriptName, 547) { } + struct instance_the_slave_pens_InstanceMapScript : public InstanceScript + { + instance_the_slave_pens_InstanceMapScript(Map* map) : InstanceScript(map) + { + counter = DATA_FLAMECALLER_000; + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_AHUNE: + AhuneGUID = creature->GetGUID(); + break; + case NPC_FROZEN_CORE: + FrozenCoreGUID = creature->GetGUID(); + break; + case NPC_AHUNE_LOC_BUNNY: + AhuneBunnyGUID = creature->GetGUID(); + break; + case NPC_SHAMAN_BONFIRE_BUNNY_000: + BonfireBunnyGUIDs[0] = creature->GetGUID(); + break; + case NPC_SHAMAN_BONFIRE_BUNNY_001: + BonfireBunnyGUIDs[1] = creature->GetGUID(); + break; + case NPC_SHAMAN_BONFIRE_BUNNY_002: + BonfireBunnyGUIDs[2] = creature->GetGUID(); + break; + case NPC_SHAMAN_BEAM_BUNNY_000: + BeamBunnyGUIDs[0] = creature->GetGUID(); + break; + case NPC_SHAMAN_BEAM_BUNNY_001: + BeamBunnyGUIDs[1] = creature->GetGUID(); + break; + case NPC_SHAMAN_BEAM_BUNNY_002: + BeamBunnyGUIDs[2] = creature->GetGUID(); + break; + case NPC_LUMA_SKYMOTHER: + LumaGUID = creature->GetGUID(); + break; + case NPC_EARTHEN_RING_FLAMECALLER: + SetGuidData(counter, creature->GetGUID()); + ++counter; + break; + default: + break; + } + } + + void SetGuidData(uint32 data, ObjectGuid guid) override + { + switch (data) + { + case DATA_FLAMECALLER_000: + FlameCallerGUIDs[0] = guid; + break; + case DATA_FLAMECALLER_001: + FlameCallerGUIDs[1] = guid; + break; + case DATA_FLAMECALLER_002: + FlameCallerGUIDs[2] = guid; + break; + default: + break; + } + } + + ObjectGuid GetGuidData(uint32 type) const override + { + switch (type) + { + case DATA_AHUNE: + return AhuneGUID; + case DATA_AHUNE_BUNNY: + return AhuneBunnyGUID; + case DATA_FROZEN_CORE: + return FrozenCoreGUID; + case DATA_FLAMECALLER_000: + return FlameCallerGUIDs[0]; + case DATA_FLAMECALLER_001: + return FlameCallerGUIDs[1]; + case DATA_FLAMECALLER_002: + return FlameCallerGUIDs[2]; + case DATA_BONFIRE_BUNNY_000: + return BonfireBunnyGUIDs[0]; + case DATA_BONFIRE_BUNNY_001: + return BonfireBunnyGUIDs[1]; + case DATA_BONFIRE_BUNNY_002: + return BonfireBunnyGUIDs[2]; + case DATA_BEAM_BUNNY_000: + return BeamBunnyGUIDs[0]; + case DATA_BEAM_BUNNY_001: + return BeamBunnyGUIDs[1]; + case DATA_BEAM_BUNNY_002: + return BeamBunnyGUIDs[2]; + case DATA_LUMA_SKYMOTHER: + return LumaGUID; + default: + break; + } + return ObjectGuid::Empty; + } + + protected: + ObjectGuid AhuneGUID; + ObjectGuid AhuneBunnyGUID; + ObjectGuid FrozenCoreGUID; + ObjectGuid LumaGUID; + ObjectGuid FlameCallerGUIDs[3]; + ObjectGuid BonfireBunnyGUIDs[3]; + ObjectGuid BeamBunnyGUIDs[3]; + uint8 counter; + }; + InstanceScript* GetInstanceScript(InstanceMap* map) const override { return new instance_the_slave_pens_InstanceMapScript(map); } - - struct instance_the_slave_pens_InstanceMapScript : public InstanceScript - { - instance_the_slave_pens_InstanceMapScript(Map* map) : InstanceScript(map) { } - }; }; void AddSC_instance_the_slave_pens() diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h index 95e6e44121e..544e98fd206 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h @@ -27,7 +27,43 @@ enum DataTypes { DATA_MENNU_THE_BETRAYER = 1, DATA_ROKMAR_THE_CRACKLER = 2, - DATA_QUAGMIRRAN = 3 + DATA_QUAGMIRRAN = 3, + DATA_AHUNE = 4, + DATA_AHUNE_BUNNY = 5, + DATA_FROZEN_CORE = 6, + DATA_FLAMECALLER_000 = 7, + DATA_FLAMECALLER_001 = 8, + DATA_FLAMECALLER_002 = 9, + DATA_BONFIRE_BUNNY_000 = 10, + DATA_BONFIRE_BUNNY_001 = 11, + DATA_BONFIRE_BUNNY_002 = 12, + DATA_BEAM_BUNNY_000 = 13, + DATA_BEAM_BUNNY_001 = 14, + DATA_BEAM_BUNNY_002 = 15, + DATA_LUMA_SKYMOTHER = 16 +}; + +enum CreaturesIds +{ + NPC_AHUNE = 25740, + NPC_FROZEN_CORE = 25865, + NPC_LUMA_SKYMOTHER = 25697, + NPC_AHUNE_LOC_BUNNY = 25745, + NPC_EARTHEN_RING_FLAMECALLER = 25754, + NPC_SHAMAN_BONFIRE_BUNNY_000 = 25971, + NPC_SHAMAN_BONFIRE_BUNNY_001 = 25972, + NPC_SHAMAN_BONFIRE_BUNNY_002 = 25973, + NPC_SHAMAN_BEAM_BUNNY_000 = 25964, + NPC_SHAMAN_BEAM_BUNNY_001 = 25965, + NPC_SHAMAN_BEAM_BUNNY_002 = 25966, + NPC_WHISP_DEST_BUNNY = 26120, + NPC_WHISP_SOURCE_BUNNY = 26121 +}; + +enum GameObjectIds +{ + GO_ICE_SPEAR = 188077, + GO_ICE_STONE = 187882 }; #endif // SLAVE_PENS_H 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 4e20e6b0953..9b8220596c9 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 @@ -372,7 +372,7 @@ class boss_vazruden_the_herald : public CreatureScript if (summon->GetEntry() == NPC_NAZAN) { summon->SetDisableGravity(true); - summon->SetSpeed(MOVE_FLIGHT, 2.5f); + summon->SetSpeedRate(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 4faab709e16..c29d560529d 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 @@ -109,7 +109,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript { removeAdds(); _Reset(); - me->SetSpeed(MOVE_RUN, 2); + me->SetSpeedRate(MOVE_RUN, 2); me->SetWalk(false); Initialize(); @@ -231,7 +231,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript { // stop bladedance InBlade = false; - me->SetSpeed(MOVE_RUN, 2); + me->SetSpeedRate(MOVE_RUN, 2); me->GetMotionMaster()->MoveChase(me->GetVictim()); Blade_Dance_Timer = 30000; Wait_Timer = 0; @@ -264,7 +264,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript Wait_Timer = 1; InBlade = true; Blade_Dance_Timer = 0; - me->SetSpeed(MOVE_RUN, 4); + me->SetSpeedRate(MOVE_RUN, 4); return; } else diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp index 56010c09897..20d96ecd29c 100644 --- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp +++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp @@ -130,7 +130,7 @@ class boss_alar : public CreatureScript _Reset(); me->SetDisplayId(me->GetNativeDisplayId()); - me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); + me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate); //me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10); //me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10); me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); @@ -178,7 +178,7 @@ class boss_alar : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); me->AttackStop(); me->SetTarget(ObjectGuid::Empty); - me->SetSpeed(MOVE_RUN, 5.0f); + me->SetSpeedRate(MOVE_RUN, 5.0f); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]); } @@ -261,7 +261,7 @@ class boss_alar : public CreatureScript case WE_REVIVE: me->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_STAND); me->SetFullHealth(); - me->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate); + me->SetSpeedRate(MOVE_RUN, DefaultMoveSpeedRate); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); DoZoneInCombat(); DoCast(me, SPELL_REBIRTH, true); diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp index 3aa2674aec6..d45e17bd28d 100644 --- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp +++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp @@ -176,7 +176,7 @@ class npc_ragin_flames : public CreatureScript Initialize(); me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true); me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true); - me->SetSpeed(MOVE_RUN, DUNGEON_MODE(0.5f, 0.7f)); + me->SetSpeedRate(MOVE_RUN, DUNGEON_MODE(0.5f, 0.7f)); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp index 856649c6c5e..e64c0fe9f5e 100644 --- a/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp +++ b/src/server/scripts/Outland/TempestKeep/botanica/boss_warp_splinter.cpp @@ -167,7 +167,7 @@ class boss_warp_splinter : public CreatureScript { Initialize(); - me->SetSpeed(MOVE_RUN, 0.7f, true); + me->SetSpeedRate(MOVE_RUN, 0.7f); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/outland_script_loader.cpp b/src/server/scripts/Outland/outland_script_loader.cpp index 91ba4e5689f..ed2c21da6c3 100644 --- a/src/server/scripts/Outland/outland_script_loader.cpp +++ b/src/server/scripts/Outland/outland_script_loader.cpp @@ -72,6 +72,7 @@ void AddSC_instance_the_slave_pens(); void AddSC_boss_mennu_the_betrayer(); void AddSC_boss_rokmar_the_crackler(); void AddSC_boss_quagmirran(); +void AddSC_boss_ahune(); // Coilfang Reservoir - The Underbog void AddSC_instance_the_underbog(); @@ -193,6 +194,7 @@ void AddOutlandScripts() AddSC_boss_mennu_the_betrayer(); AddSC_boss_rokmar_the_crackler(); AddSC_boss_quagmirran(); + AddSC_boss_ahune(); // Coilfang Reservoir - The Underbog AddSC_instance_the_underbog(); diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index 404cdc7ceb2..668c484dd63 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -159,7 +159,7 @@ public: else TC_LOG_ERROR("scripts", "TRINITY: npc_ancestral_wolf can not obtain owner or owner is not a player."); - creature->SetSpeed(MOVE_WALK, 1.5f); + creature->SetSpeedRate(MOVE_WALK, 1.5f); Reset(); } @@ -192,7 +192,7 @@ public: if (ryga->IsAlive() && !ryga->IsInCombat()) { ryga->SetWalk(true); - ryga->SetSpeed(MOVE_WALK, 1.5f); + ryga->SetSpeedRate(MOVE_WALK, 1.5f); ryga->GetMotionMaster()->MovePoint(0, 517.340698f, 3885.03975f, 190.455978f, true); Reset(); } @@ -778,7 +778,7 @@ public: me->AddAura(SPELL_JULES_THREATENS_AURA, me); me->SetCanFly(true); - me->SetSpeed(MOVE_RUN, 0.2f); + me->SetSpeedRate(MOVE_RUN, 0.2f); me->SetFacingTo(3.207566f); me->GetMotionMaster()->MoveJump(exorcismPos[2], 2.0f, 2.0f); @@ -798,7 +798,7 @@ public: break; case ACTION_JULES_MOVE_HOME: wpreached = false; - me->SetSpeed(MOVE_RUN, 1.0f); + me->SetSpeedRate(MOVE_RUN, 1.0f); me->GetMotionMaster()->MovePoint(11, exorcismPos[2]); events.CancelEvent(EVENT_SUMMON_SKULL); diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index c734d000077..e4e51a98348 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -29,7 +29,6 @@ npc_salsalabim npc_shattrathflaskvendors npc_zephyr npc_kservant -npc_ishanah EndContentData */ #include "ScriptMgr.h" @@ -43,13 +42,15 @@ EndContentData */ ## npc_raliq_the_drunk ######*/ -#define GOSSIP_RALIQ "You owe Sim'salabim money. Hand them over or die!" - -enum Raliq +enum RaliqTheDrunk { - SPELL_UPPERCUT = 10966, - QUEST_CRACK_SKULLS = 10009, - FACTION_HOSTILE_RD = 45 + SAY_RALIQ_ATTACK = 0, + OPTION_ID_COLLECT_A_DEBT = 0, + FACTION_OGRE_HOSTILE = 45, + MENU_ID_COLLECT_A_DEBT = 7729, + NPC_TEXT_WUT_YOU_WANT = 9440, + CRACKIN_SOME_SKULLS = 10009, + SPELL_UPPERCUT = 10966 }; class npc_raliq_the_drunk : public CreatureScript @@ -63,7 +64,8 @@ public: if (action == GOSSIP_ACTION_INFO_DEF+1) { player->CLOSE_GOSSIP_MENU(); - creature->setFaction(FACTION_HOSTILE_RD); + creature->setFaction(FACTION_OGRE_HOSTILE); + creature->AI()->Talk(SAY_RALIQ_ATTACK, player); creature->AI()->AttackStart(player); } return true; @@ -71,10 +73,16 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - if (player->GetQuestStatus(QUEST_CRACK_SKULLS) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_RALIQ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - - player->SEND_GOSSIP_MENU(9440, creature->GetGUID()); + if (player->GetQuestStatus(CRACKIN_SOME_SKULLS) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM_DB(MENU_ID_COLLECT_A_DEBT, OPTION_ID_COLLECT_A_DEBT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(NPC_TEXT_WUT_YOU_WANT, creature->GetGUID()); + } + else + { + player->PlayerTalkClass->ClearMenus(); + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + } return true; } @@ -125,16 +133,14 @@ public: enum Salsalabim { - // Factions - FACTION_HOSTILE_SA = 90, - FACTION_FRIENDLY_SA = 35, - - // Quests - QUEST_10004 = 10004, - - // Spells - SPELL_MAGNETIC_PULL = 31705 - + SAY_DEMONIC_AGGRO = 0, + OPTION_ID_ALTRUIS_SENT_ME = 0, + FACTION_FRIENDLY = 35, + FACTION_DEMON_HOSTILE = 90, + MENU_ID_ALTRUIS_SENT_ME = 7725, + NPC_TEXT_SAL_GROWLS_AT_YOU = 9435, + PATIENCE_AND_UNDERSTANDING = 10004, + SPELL_MAGNETIC_PULL = 31705 }; class npc_salsalabim : public CreatureScript @@ -142,13 +148,26 @@ class npc_salsalabim : public CreatureScript public: npc_salsalabim() : CreatureScript("npc_salsalabim") { } - bool OnGossipHello(Player* player, Creature* creature) override + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override { - if (player->GetQuestStatus(QUEST_10004) == QUEST_STATUS_INCOMPLETE) + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) { - creature->setFaction(FACTION_HOSTILE_SA); + player->CLOSE_GOSSIP_MENU(); + creature->setFaction(FACTION_DEMON_HOSTILE); + creature->AI()->Talk(SAY_DEMONIC_AGGRO, player); creature->AI()->AttackStart(player); } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) override + { + if (player->GetQuestStatus(PATIENCE_AND_UNDERSTANDING) == QUEST_STATUS_INCOMPLETE) + { + player->ADD_GOSSIP_ITEM_DB(MENU_ID_ALTRUIS_SENT_ME, OPTION_ID_ALTRUIS_SENT_ME, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(NPC_TEXT_SAL_GROWLS_AT_YOU, creature->GetGUID()); + } else { if (creature->IsQuestGiver()) @@ -187,7 +206,7 @@ public: { if (done_by->GetTypeId() == TYPEID_PLAYER && me->HealthBelowPctDamaged(20, damage)) { - done_by->ToPlayer()->GroupEventHappens(QUEST_10004, me); + done_by->ToPlayer()->GroupEventHappens(PATIENCE_AND_UNDERSTANDING, me); damage = 0; EnterEvadeMode(); } @@ -220,6 +239,19 @@ Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and ################################################## */ +enum FlaskVendors +{ + ALDOR_REPUTATION = 932, + SCRYERS_REPUTATION = 934, + THE_SHA_TAR_REPUTATION = 935, + CENARION_EXPEDITION_REP = 942, + NPC_TEXT_EXALTED_ALDOR = 11083, // (need to be exalted with Sha'tar, Cenarion Expedition and the Aldor) + NPC_TEXT_EXALTED_SCRYERS = 11084, // (need to be exalted with Sha'tar, Cenarion Expedition and the Scryers) + NPC_TEXT_WELCOME_NAME = 11085, // Access granted + ARCANIST_XORITH = 23483, // Scryer Apothecary + HALDOR_THE_COMPULSIVE = 23484 // Aldor Apothecary +}; + class npc_shattrathflaskvendors : public CreatureScript { public: @@ -236,31 +268,31 @@ public: bool OnGossipHello(Player* player, Creature* creature) override { - if (creature->GetEntry() == 23484) + if (creature->GetEntry() == HALDOR_THE_COMPULSIVE) { // Aldor vendor - if (creature->IsVendor() && (player->GetReputationRank(932) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) + if (creature->IsVendor() && (player->GetReputationRank(ALDOR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(THE_SHA_TAR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(CENARION_EXPEDITION_REP) == REP_EXALTED)) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_WELCOME_NAME, creature->GetGUID()); } else { - player->SEND_GOSSIP_MENU(11083, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_EXALTED_ALDOR, creature->GetGUID()); } } - if (creature->GetEntry() == 23483) + if (creature->GetEntry() == ARCANIST_XORITH) { // Scryers vendor - if (creature->IsVendor() && (player->GetReputationRank(934) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED)) + if (creature->IsVendor() && (player->GetReputationRank(SCRYERS_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(THE_SHA_TAR_REPUTATION) == REP_EXALTED) && (player->GetReputationRank(CENARION_EXPEDITION_REP) == REP_EXALTED)) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); - player->SEND_GOSSIP_MENU(11085, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_WELCOME_NAME, creature->GetGUID()); } else { - player->SEND_GOSSIP_MENU(11084, creature->GetGUID()); + player->SEND_GOSSIP_MENU(NPC_TEXT_EXALTED_SCRYERS, creature->GetGUID()); } } @@ -272,7 +304,13 @@ public: # npc_zephyr ######*/ -#define GOSSIP_HZ "Take me to the Caverns of Time." +enum Zephyr +{ + OPTION_ID_TAKE_ME_TO_C_O_T = 0, + KEEPERS_OF_TIME_REPUTATION = 989, + MENU_ID_TAKE_ME_TO_C_O_T = 9205, + TELEPORT_CAVERNS_OF_TIME = 37778 +}; class npc_zephyr : public CreatureScript { @@ -283,15 +321,15 @@ public: { player->PlayerTalkClass->ClearMenus(); if (action == GOSSIP_ACTION_INFO_DEF+1) - player->CastSpell(player, 37778, false); + player->CastSpell(player, TELEPORT_CAVERNS_OF_TIME, false); return true; } bool OnGossipHello(Player* player, Creature* creature) override { - if (player->GetReputationRank(989) >= REP_REVERED) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HZ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + if (player->GetReputationRank(KEEPERS_OF_TIME_REPUTATION) >= REP_REVERED) + player->ADD_GOSSIP_ITEM_DB(MENU_ID_TAKE_ME_TO_C_O_T, OPTION_ID_TAKE_ME_TO_C_O_T, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); @@ -305,28 +343,29 @@ public: enum KServant { - SAY1 = 0, - WHISP1 = 1, - WHISP2 = 2, - WHISP3 = 3, - WHISP4 = 4, - WHISP5 = 5, - WHISP6 = 6, - WHISP7 = 7, - WHISP8 = 8, - WHISP9 = 9, - WHISP10 = 10, - WHISP11 = 11, - WHISP12 = 12, - WHISP13 = 13, - WHISP14 = 14, - WHISP15 = 15, - WHISP16 = 16, - WHISP17 = 17, - WHISP18 = 18, - WHISP19 = 19, - WHISP20 = 20, - WHISP21 = 21 + SAY1 = 0, + WHISP1 = 1, + WHISP2 = 2, + WHISP3 = 3, + WHISP4 = 4, + WHISP5 = 5, + WHISP6 = 6, + WHISP7 = 7, + WHISP8 = 8, + WHISP9 = 9, + WHISP10 = 10, + WHISP11 = 11, + WHISP12 = 12, + WHISP13 = 13, + WHISP14 = 14, + WHISP15 = 15, + WHISP16 = 16, + WHISP17 = 17, + WHISP18 = 18, + WHISP19 = 19, + WHISP20 = 20, + WHISP21 = 21, + CITY_OF_LIGHT = 10211 }; class npc_kservant : public CreatureScript @@ -417,7 +456,7 @@ public: break; case 56: Talk(WHISP21, player); - player->GroupEventHappens(10211, me); + player->GroupEventHappens(CITY_OF_LIGHT, me); break; } } @@ -429,7 +468,7 @@ public: return; Player* player = who->ToPlayer(); - if (player && player->GetQuestStatus(10211) == QUEST_STATUS_INCOMPLETE) + if (player && player->GetQuestStatus(CITY_OF_LIGHT) == QUEST_STATUS_INCOMPLETE) { float Radius = 10.0f; if (me->IsWithinDistInMap(who, Radius)) @@ -443,43 +482,6 @@ public: }; }; -/*###### -# npc_ishanah -######*/ - -#define ISANAH_GOSSIP_1 "Who are the Sha'tar?" -#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" - -class npc_ishanah : public CreatureScript -{ -public: - npc_ishanah() : CreatureScript("npc_ishanah") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - player->SEND_GOSSIP_MENU(9458, creature->GetGUID()); - else if (action == GOSSIP_ACTION_INFO_DEF+2) - player->SEND_GOSSIP_MENU(9459, creature->GetGUID()); - - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) override - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); - - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - - return true; - } -}; - void AddSC_shattrath_city() { new npc_raliq_the_drunk(); @@ -487,5 +489,4 @@ void AddSC_shattrath_city() new npc_shattrathflaskvendors(); new npc_zephyr(); new npc_kservant(); - new npc_ishanah(); } diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index 80b3a00774b..113b14a0d54 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -103,8 +103,8 @@ class npc_pet_dk_ebon_gargoyle : public CreatureScript //! HACK: Creature's can't have MOVEMENTFLAG_FLYING // Fly Away me->SetCanFly(true); - me->SetSpeed(MOVE_FLIGHT, 0.75f, true); - me->SetSpeed(MOVE_RUN, 0.75f, true); + me->SetSpeedRate(MOVE_FLIGHT, 0.75f); + me->SetSpeedRate(MOVE_RUN, 0.75f); float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation()); float y = me->GetPositionY() + 20 * std::sin(me->GetOrientation()); float z = me->GetPositionZ() + 40; diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 0abff255e4b..84c67bad63b 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -201,6 +201,55 @@ class spell_item_blessing_of_ancient_kings : public SpellScriptLoader } }; +// 47770 - Roll Dice +class spell_item_decahedral_dwarven_dice : public SpellScriptLoader +{ + public: + spell_item_decahedral_dwarven_dice() : SpellScriptLoader("spell_item_decahedral_dwarven_dice") { } + + class spell_item_decahedral_dwarven_dice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_decahedral_dwarven_dice_SpellScript); + + enum + { + TEXT_DECAHEDRAL_DWARVEN_DICE = 26147 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_DECAHEDRAL_DWARVEN_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_DECAHEDRAL_DWARVEN_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 100; + + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_decahedral_dwarven_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_decahedral_dwarven_dice_SpellScript(); + } +}; + // 8342 - Defibrillate (Goblin Jumper Cables) have 33% chance on success // 22999 - Defibrillate (Goblin Jumper Cables XL) have 50% chance on success // 54732 - Defibrillate (Gnomish Army Knife) have 67% chance on success @@ -1319,6 +1368,57 @@ class spell_item_underbelly_elixir : public SpellScriptLoader } }; +// 47776 - Roll 'dem Bones +class spell_item_worn_troll_dice : public SpellScriptLoader +{ + public: + spell_item_worn_troll_dice() : SpellScriptLoader("spell_item_worn_troll_dice") { } + + class spell_item_worn_troll_dice_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_worn_troll_dice_SpellScript); + + enum + { + TEXT_WORN_TROLL_DICE = 26152 + }; + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sObjectMgr->GetBroadcastText(TEXT_WORN_TROLL_DICE)) + return false; + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->TextEmote(TEXT_WORN_TROLL_DICE, GetHitUnit()); + + static uint32 const minimum = 1; + static uint32 const maximum = 6; + + // roll twice + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + GetCaster()->ToPlayer()->DoRandomRoll(minimum, maximum); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_item_worn_troll_dice_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_item_worn_troll_dice_SpellScript(); + } +}; + enum AirRifleSpells { SPELL_AIR_RIFLE_HOLD_VISUAL = 65582, @@ -2682,6 +2782,7 @@ void AddSC_item_spell_scripts() new spell_item_aegis_of_preservation(); new spell_item_arcane_shroud(); new spell_item_blessing_of_ancient_kings(); + new spell_item_decahedral_dwarven_dice(); new spell_item_defibrillate("spell_item_goblin_jumper_cables", 67, SPELL_GOBLIN_JUMPER_CABLES_FAIL); new spell_item_defibrillate("spell_item_goblin_jumper_cables_xl", 50, SPELL_GOBLIN_JUMPER_CABLES_XL_FAIL); new spell_item_defibrillate("spell_item_gnomish_army_knife", 33); @@ -2706,6 +2807,7 @@ void AddSC_item_spell_scripts() new spell_item_six_demon_bag(); new spell_item_the_eye_of_diminution(); new spell_item_underbelly_elixir(); + new spell_item_worn_troll_dice(); new spell_item_red_rider_air_rifle(); new spell_item_create_heart_candy(); diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 3121a18734d..ae761413ca5 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1707,7 +1707,7 @@ enum Quest13291_13292_13239_13261Data NPC_SKYTALON = 31583, NPC_DECOY = 31578, // Spells - SPELL_RIDE = 56687 + SPELL_RIDE = 59319 }; class spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy : public SpellScriptLoader diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index 1f89720803d..65dec74414b 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -205,7 +205,7 @@ class npc_dream_fog : public CreatureScript } // Seeping fog movement is slow enough for a player to be able to walk backwards and still outpace it me->SetWalk(true); - me->SetSpeed(MOVE_WALK, 0.75f); + me->SetSpeedRate(MOVE_WALK, 0.75f); } else _roamTimer -= diff; diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 2b5553b4bb0..f4d736ac675 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -24,6 +24,7 @@ #include <openssl/crypto.h> #include <boost/asio/io_service.hpp> #include <boost/asio/deadline_timer.hpp> +#include <boost/filesystem/path.hpp> #include <boost/program_options.hpp> #include "Common.h" @@ -53,6 +54,7 @@ #include "AppenderDB.h" using namespace boost::program_options; +namespace fs = boost::filesystem; #ifndef _TRINITY_CORE_CONFIG #define _TRINITY_CORE_CONFIG "worldserver.conf" @@ -90,14 +92,14 @@ void ClearOnlineAccounts(); void ShutdownCLIThread(std::thread* cliThread); void ShutdownThreadPool(std::vector<std::thread>& threadPool); bool LoadRealmInfo(); -variables_map GetConsoleArguments(int argc, char** argv, std::string& cfg_file, std::string& cfg_service); +variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, std::string& cfg_service); /// Launch the Trinity server extern int main(int argc, char** argv) { signal(SIGABRT, &Trinity::AbortHandler); - std::string configFile = _TRINITY_CORE_CONFIG; + auto configFile = fs::absolute(_TRINITY_CORE_CONFIG); std::string configService; auto vm = GetConsoleArguments(argc, argv, configFile, configService); @@ -115,7 +117,9 @@ extern int main(int argc, char** argv) #endif std::string configError; - if (!sConfigMgr->LoadInitial(configFile, configError)) + if (!sConfigMgr->LoadInitial(configFile.generic_string(), + std::vector<std::string>(argv, argv + argc), + configError)) { printf("Error in config file: %s\n", configError.c_str()); return 1; @@ -136,7 +140,7 @@ extern int main(int argc, char** argv) TC_LOG_INFO("server.worldserver", " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\"); TC_LOG_INFO("server.worldserver", " C O R E /\\___/"); TC_LOG_INFO("server.worldserver", "http://TrinityCore.org \\/__/\n"); - TC_LOG_INFO("server.worldserver", "Using configuration file %s.", configFile.c_str()); + TC_LOG_INFO("server.worldserver", "Using configuration file %s.", sConfigMgr->GetFilename().c_str()); TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); TC_LOG_INFO("server.worldserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); @@ -571,7 +575,7 @@ void ClearOnlineAccounts() /// @} -variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile, std::string& configService) +variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile, std::string& configService) { // Silences warning about configService not be used if the OS is not Windows (void)configService; @@ -580,7 +584,8 @@ variables_map GetConsoleArguments(int argc, char** argv, std::string& configFile all.add_options() ("help,h", "print usage message") ("version,v", "print version build info") - ("config,c", value<std::string>(&configFile)->default_value(_TRINITY_CORE_CONFIG), "use <arg> as configuration file") + ("config,c", value<fs::path>(&configFile)->default_value(fs::absolute(_TRINITY_CORE_CONFIG)), + "use <arg> as configuration file") ; #ifdef _WIN32 options_description win("Windows platform specific options"); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index c2694c640c5..1d425e68246 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -3581,6 +3581,7 @@ Appender.DBErrors=2,2,0,DBErrors.log Logger.root=5,Console Server Logger.server=3,Console Server Logger.commands.gm=3,Console GM +Logger.scripts.hotswap=3,Console Server Logger.sql.sql=5,Console DBErrors Logger.sql.updates=3,Console Server Logger.mmaps=3,Server @@ -3623,7 +3624,6 @@ Logger.mmaps=3,Server #Logger.rbac=3,Console Server #Logger.scripts=3,Console Server #Logger.scripts.ai=3,Console Server -#Logger.scripts.hotswap=3,Console Server #Logger.server.authserver=3,Console Server #Logger.spells=3,Console Server #Logger.spells.periodic=3,Console Server |