aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2014_06_06_00_world_misc.sql92
-rw-r--r--sql/updates/world/2014_06_06_00_world_quest_template.sql4
-rw-r--r--sql/updates/world/2014_06_07_00_world_misc.sql31
-rw-r--r--sql/updates/world/2014_06_08_00_world_conditions.sql1
-rw-r--r--sql/updates/world/2014_06_08_01_world_gameobject.sql17
-rw-r--r--sql/updates/world/2014_06_08_02_world_gameobject.sql40
-rw-r--r--sql/updates/world/2014_06_08_03_world_gameobject.sql1
-rw-r--r--src/server/authserver/Main.cpp16
-rw-r--r--src/server/game/AI/CreatureAI.cpp5
-rw-r--r--src/server/game/AI/CreatureAI.h1
-rw-r--r--src/server/game/AI/CreatureAIImpl.h349
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp1
-rw-r--r--src/server/game/Entities/Player/Player.cpp36
-rw-r--r--src/server/game/Entities/Player/Player.h6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp50
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp2
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp62
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp2
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp1
-rw-r--r--src/server/game/Handlers/PetHandler.cpp7
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp7
-rw-r--r--src/server/game/Handlers/TicketHandler.cpp5
-rw-r--r--src/server/game/Maps/Map.cpp7
-rw-r--r--src/server/game/Server/WorldSession.cpp23
-rw-r--r--src/server/game/Server/WorldSession.h5
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp20
-rw-r--r--src/server/game/Spells/Spell.cpp2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp15
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp13
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp101
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp149
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp139
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp163
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp88
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp99
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp118
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp114
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp103
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp240
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp8
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp5
-rw-r--r--src/server/scripts/Outland/zone_shadowmoon_valley.cpp7
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp10
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp4
-rw-r--r--src/server/scripts/World/npcs_special.cpp56
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.h2
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.cpp2
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.h2
-rw-r--r--src/server/shared/Packets/ByteBuffer.h12
-rw-r--r--src/server/shared/Utilities/Util.h350
-rw-r--r--src/server/worldserver/Master.cpp18
54 files changed, 1546 insertions, 1074 deletions
diff --git a/sql/updates/world/2014_06_06_00_world_misc.sql b/sql/updates/world/2014_06_06_00_world_misc.sql
new file mode 100644
index 00000000000..a1d4dd621c0
--- /dev/null
+++ b/sql/updates/world/2014_06_06_00_world_misc.sql
@@ -0,0 +1,92 @@
+
+UPDATE creature_template SET ScriptName="npc_imp_in_a_ball" WHERE entry=23224;
+
+SET @COUNT := 0;
+DELETE FROM creature_text WHERE entry=23224;
+INSERT INTO creature_text (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, unless I have anything to do with it.', 15, 0, 100, 0, 0, 0, '', 21157),
+(23224, 0, @COUNT := @COUNT + 1, 'I see that happening sometime between tomorrow and the next decade. Definitely.', 15, 0, 100, 0, 0, 0, '', 21158),
+(23224, 0, @COUNT := @COUNT + 1, 'Looks good for you...and bad for me.', 15, 0, 100, 0, 0, 0, '', 21160),
+(23224, 0, @COUNT := @COUNT + 1, 'I\'ve consulted my fellow imps, and we think YES, except for that one imp.', 15, 0, 100, 0, 0, 0, '', 21161),
+(23224, 0, @COUNT := @COUNT + 1, 'The outlook is positive, but I\'m still negative.', 15, 0, 100, 0, 0, 0, '', 21162),
+(23224, 0, @COUNT := @COUNT + 1, 'It pains me to say this, but "Yes".', 15, 0, 100, 0, 0, 0, '', 21163),
+(23224, 0, @COUNT := @COUNT + 1, 'When dwarves fly! They do? Then yes!', 15, 0, 100, 0, 0, 0, '', 21164),
+(23224, 0, @COUNT := @COUNT + 1, 'Sure, but you\'re not going to like it.', 15, 0, 100, 0, 0, 0, '', 21165),
+(23224, 0, @COUNT := @COUNT + 1, 'Be quiet \'bout what you hear and see around here, $r.', 15, 0, 100, 0, 0, 0, '', 21166),
+(23224, 0, @COUNT := @COUNT + 1, 'Unfortunately... yes.', 15, 0, 100, 0, 0, 0, '', 21169),
+(23224, 0, @COUNT := @COUNT + 1, 'I can\'t see why not, although, I can\'t see a lot of things right now.', 15, 0, 100, 0, 0, 0, '', 21170),
+(23224, 0, @COUNT := @COUNT + 1, 'I would bet your soul on it.', 15, 0, 100, 0, 0, 0, '', 21171),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, but if anyone asks... It wasn\'t me who told you.', 15, 0, 100, 0, 0, 0, '', 21172),
+(23224, 0, @COUNT := @COUNT + 1, 'Didn\'t you already ask that once? Yes already!', 15, 0, 100, 0, 0, 0, '', 21173),
+(23224, 0, @COUNT := @COUNT + 1, 'Please... Is Kil\'jaeden red?', 15, 0, 100, 0, 0, 0, '', 21175),
+(23224, 0, @COUNT := @COUNT + 1, 'Yeah, sure. You just keep thinking that.', 15, 0, 100, 0, 0, 0, '', 21176),
+(23224, 0, @COUNT := @COUNT + 1, 'I suppose.', 15, 0, 100, 0, 0, 0, '', 21177),
+(23224, 0, @COUNT := @COUNT + 1, 'Definitely.', 15, 0, 100, 0, 0, 0, '', 21178),
+(23224, 0, @COUNT := @COUNT + 1, 'Jump three times and dance for ten minutes and it will definitely happen!', 15, 0, 100, 0, 0, 0, '', 21179),
+(23224, 0, @COUNT := @COUNT + 1, 'Word on the peninsula is YES!', 15, 0, 100, 0, 0, 0, '', 21180),
+(23224, 0, @COUNT := @COUNT + 1, 'Oh, that one\'s for sure.', 15, 0, 100, 0, 0, 0, '', 21181),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, but not in the way you imagine.', 15, 0, 100, 0, 0, 0, '', 21182),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, yes, a thousand times, yes already!', 15, 0, 100, 0, 0, 0, '', 21183),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, now stop pestering me!', 15, 0, 100, 0, 0, 0, '', 21184),
+(23224, 0, @COUNT := @COUNT + 1, 'The answer will be a yes if you let me out of here.', 15, 0, 100, 0, 0, 0, '', 21185),
+(23224, 0, @COUNT := @COUNT + 1, 'It\'s as sure as the warts on my backside!', 15, 0, 100, 0, 0, 0, '', 21186),
+(23224, 0, @COUNT := @COUNT + 1, 'The answer is yes in here, I don\'t see why it would be any different out there.', 15, 0, 100, 0, 0, 0, '', 21187),
+(23224, 0, @COUNT := @COUNT + 1, 'Three words - "ab - so - lutely"!', 15, 0, 100, 0, 0, 0, '', 21188),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, but I hoped I would never have to answer that.', 15, 0, 100, 0, 0, 0, '', 21189),
+(23224, 0, @COUNT := @COUNT + 1, 'Ask me again later - I\'m trying to scratch my nose and it\'s hard to concentrate.', 15, 0, 100, 0, 0, 0, '', 21190),
+(23224, 0, @COUNT := @COUNT + 1, 'Why should I answer that? Do you tell fortunes when people shake YOU?', 15, 0, 100, 0, 0, 0, '', 21191),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, it will rain. That\'s not what you asked? Too bad!', 15, 0, 100, 0, 0, 0, '', 21192),
+(23224, 0, @COUNT := @COUNT + 1, 'I\'m sorry, I can only speak Demonic.', 15, 0, 100, 0, 0, 0, '', 21193),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes! I mean no! I mean... which answer gets me out of here?', 15, 0, 100, 0, 0, 0, '', 21194),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes, No, Maybe so.', 15, 0, 100, 0, 0, 0, '', 21195),
+(23224, 0, @COUNT := @COUNT + 1, 'It won\'t matter, you\'ll be dead by tomorrow.', 15, 0, 100, 0, 0, 0, '', 21196),
+(23224, 0, @COUNT := @COUNT + 1, 'You should be asking "Is that rogue behind me going to kill me?"', 15, 0, 100, 0, 0, 0, '', 21197),
+(23224, 0, @COUNT := @COUNT + 1, 'It\'s times like these that I wish I had a longer cooldown.', 15, 0, 100, 0, 0, 0, '', 21198),
+(23224, 0, @COUNT := @COUNT + 1, '%s shrugs. Who knows?', 15, 0, 100, 0, 0, 0, '', 21199),
+(23224, 0, @COUNT := @COUNT + 1, 'It\'s like my mother always said: [Demonic] "Razxx khaj jhashxx xashjx."', 15, 0, 100, 0, 0, 0, '', 21205),
+(23224, 0, @COUNT := @COUNT + 1, '%s is ignoring you.', 15, 0, 100, 0, 0, 0, '', 21206),
+(23224, 0, @COUNT := @COUNT + 1, 'Why me? Why not a goblin, or a gnome...', 15, 0, 100, 0, 0, 0, '', 21207),
+(23224, 0, @COUNT := @COUNT + 1, 'What happens in the twisting nether, stays in the twisting nether.', 15, 0, 100, 0, 0, 0, '', 21208),
+(23224, 0, @COUNT := @COUNT + 1, 'Avoid taking unnecessary gambles. Your lucky numbers are two, two and half, and eleven-teen.', 15, 0, 100, 0, 0, 0, '', 21209),
+(23224, 0, @COUNT := @COUNT + 1, 'Wouldn\'t you like to know?', 15, 0, 100, 0, 0, 0, '', 21210),
+(23224, 0, @COUNT := @COUNT + 1, 'Oh, oh, oh! I can see this one clearly... Nah, lost it.', 15, 0, 100, 0, 0, 0, '', 21211),
+(23224, 0, @COUNT := @COUNT + 1, 'This was NOT in my contract!', 15, 0, 100, 0, 0, 0, '', 21212),
+(23224, 0, @COUNT := @COUNT + 1, 'XRA RAHKI MAZIZRA!', 15, 0, 100, 0, 0, 0, '', 21213),
+(23224, 0, @COUNT := @COUNT + 1, '4 8 15 16 23 42', 15, 0, 100, 0, 0, 0, '', 21214),
+(23224, 0, @COUNT := @COUNT + 1, 'Are you making fun of me?', 15, 0, 100, 0, 0, 0, '', 21215),
+(23224, 0, @COUNT := @COUNT + 1, 'What kind of imp do you think I am?', 15, 0, 100, 0, 0, 0, '', 21216),
+(23224, 0, @COUNT := @COUNT + 1, 'Say please.', 15, 0, 100, 0, 0, 0, '', 21217),
+(23224, 0, @COUNT := @COUNT + 1, 'Want to trade places?', 15, 0, 100, 0, 0, 0, '', 21218),
+(23224, 0, @COUNT := @COUNT + 1, 'Do you ask this question to everything that\'s trapped in a ball?', 15, 0, 100, 0, 0, 0, '', 21219),
+(23224, 0, @COUNT := @COUNT + 1, 'Hey! You try arranging furniture with some jerk shaking your house!', 15, 0, 100, 0, 0, 0, '', 21220),
+(23224, 0, @COUNT := @COUNT + 1, 'I can make that happen. Just sign below the dotted line...', 15, 0, 100, 0, 0, 0, '', 21221),
+(23224, 0, @COUNT := @COUNT + 1, 'Reply hazy and slightly damp. Dry thoroughly and try again.', 15, 0, 100, 0, 0, 0, '', 21222),
+(23224, 0, @COUNT := @COUNT + 1, 'Concentrate (on releasing me from this infernal prison) and try again later.', 15, 0, 100, 0, 0, 0, '', 21223),
+(23224, 0, @COUNT := @COUNT + 1, 'Please insert 25 silver pieces and try again.', 15, 0, 100, 0, 0, 0, '', 21224),
+(23224, 0, @COUNT := @COUNT + 1, 'Are you my pal, Danny?', 15, 0, 100, 0, 0, 0, '', 21225),
+(23224, 0, @COUNT := @COUNT + 1, 'You remember the time you tried to drill that hole in your head?', 15, 0, 100, 0, 0, 0, '', 21226),
+(23224, 0, @COUNT := @COUNT + 1, 'Oh that\'s right, don\'t make any effort to make your own fortune!', 15, 0, 100, 0, 0, 0, '', 21227),
+(23224, 0, @COUNT := @COUNT + 1, 'Two words - imp-possible!', 15, 0, 100, 0, 0, 0, '', 21228),
+(23224, 0, @COUNT := @COUNT + 1, 'You need Arcane Intellect, because that answer is obvious! NO!', 15, 0, 100, 0, 0, 0, '', 21229),
+(23224, 0, @COUNT := @COUNT + 1, 'Not on your life!', 15, 0, 100, 0, 0, 0, '', 21230),
+(23224, 0, @COUNT := @COUNT + 1, 'I don\'t have to be a fortune-telling imp to know the answer to that one - NO!', 15, 0, 100, 0, 0, 0, '', 21231),
+(23224, 0, @COUNT := @COUNT + 1, 'The odds are 32.33 (repeating of course) percent chance of success.', 15, 0, 100, 0, 0, 0, '', 21232),
+(23224, 0, @COUNT := @COUNT + 1, 'When Blackrock freezes over!', 15, 0, 100, 0, 0, 0, '', 21233),
+(23224, 0, @COUNT := @COUNT + 1, 'Hahahaha, you\'re kidding right?', 15, 0, 100, 0, 0, 0, '', 21234),
+(23224, 0, @COUNT := @COUNT + 1, 'Inconceivable!', 15, 0, 100, 0, 0, 0, '', 21235),
+(23224, 0, @COUNT := @COUNT + 1, 'My sources say "no". Before the torture, that is.', 15, 0, 100, 0, 0, 0, '', 21236),
+(23224, 0, @COUNT := @COUNT + 1, 'That\'s about as likely as me getting out of this ball.', 15, 0, 100, 0, 0, 0, '', 21237),
+(23224, 0, @COUNT := @COUNT + 1, 'You picked the wrong time to shake me today, buddy! Prepare for disappointment.', 15, 0, 100, 0, 0, 0, '', 21238),
+(23224, 0, @COUNT := @COUNT + 1, 'Not unless you\'re some kind of super-person. And don\'t kid yourself, you\'re not.', 15, 0, 100, 0, 0, 0, '', 21239),
+(23224, 0, @COUNT := @COUNT + 1, 'That\'s about as likely as me getting a date with a succubus.', 15, 0, 100, 0, 0, 0, '', 21240),
+(23224, 0, @COUNT := @COUNT + 1, 'My fortune telling powers are immeasurable - your chances are though: NO CHANCE', 15, 0, 100, 0, 0, 0, '', 21241),
+(23224, 0, @COUNT := @COUNT + 1, 'NO - and don\'t try shaking me again for a better answer!', 15, 0, 100, 0, 0, 0, '', 21242),
+(23224, 0, @COUNT := @COUNT + 1, 'Yes is my answer...', 15, 0, 100, 0, 0, 0, '', 21243),
+(23224, 0, @COUNT := @COUNT + 1, '...NOT!', 15, 0, 100, 0, 0, 0, '', 21244),
+(23224, 0, @COUNT := @COUNT + 1, 'I\'m gonna have to give this one the big N-O.', 15, 0, 100, 0, 0, 0, '', 21245),
+(23224, 0, @COUNT := @COUNT + 1, 'The outlook is very bad - for YOU that is! Haha, take it!', 15, 0, 100, 0, 0, 0, '', 21246),
+(23224, 0, @COUNT := @COUNT + 1, 'Survey says: BZZZT!', 15, 0, 100, 0, 0, 0, '', 21247);
+
+DELETE FROM spell_linked_spell WHERE spell_trigger=40527 AND spell_effect=40528;
+INSERT INTO spell_linked_spell (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
+(40527, 40528, 0, 'Imp in a Bottle');
diff --git a/sql/updates/world/2014_06_06_00_world_quest_template.sql b/sql/updates/world/2014_06_06_00_world_quest_template.sql
new file mode 100644
index 00000000000..6d174f9a7b0
--- /dev/null
+++ b/sql/updates/world/2014_06_06_00_world_quest_template.sql
@@ -0,0 +1,4 @@
+--
+UPDATE `quest_template` SET `RequestItemsText` = 'Supposedly this Malcin is outside Razorfen Downs. There''s no question - he has to die.$b$bMy contacts in Orgrimmar tell me their scouts have found signs of the Plague down there. The quilboar are showing signs of being plagued, too; they''re much more powerful. Whatever the Scourge are doing down there needs to end. Now.$b$bFind this Malcin and kill him. Report back here when he''s dead.' WHERE `id` = 14353;
+UPDATE `quest_template` SET `OfferRewardText` = 'Good work, $C!$b$bYou''ve done the Horde proud by stopping the Scourge from setting down roots on our soil. An act like that deserves a reward, and the Forsaken have enough lying around that I''m sure they can spare a few things.$b$bWe may not know everything they''ve done in the Downs, but we''ll find out. They can''t slink around in the dark forever.' WHERE `id` = 14353;
+UPDATE `quest_template` SET `OfferRewardText` = 'I''m sure Sylvanas will be glad to have that problem taken care of, $N. The task I gave you wasn''t easy, but here you stand, victorious. That commands respect, and what you''ve done won''t be forgotten.' WHERE `id` = 14355;
diff --git a/sql/updates/world/2014_06_07_00_world_misc.sql b/sql/updates/world/2014_06_07_00_world_misc.sql
new file mode 100644
index 00000000000..ff09f8f552e
--- /dev/null
+++ b/sql/updates/world/2014_06_07_00_world_misc.sql
@@ -0,0 +1,31 @@
+UPDATE `creature_template` SET `gossip_menu_id`=3310 WHERE `entry`=11216;
+
+DELETE FROM `gossip_menu_option` WHERE `menu_id` in(3310,3309,3308,3307,3306,3305,3304,3303,3302,3301);
+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
+(3310, 0, 0, 'The pleasure is mine, madam. Might I ask what it is that you are doing here?', 6645, 1, 1, 3309, 0, 0, 0, '', 0),
+(3310, 1, 0, 'Eva, I have lost the Spectral Essence. I need another.', 6799, 1, 1, 0, 0, 0, 0, '', 0),
+(3309, 0, 0, 'Until what, Eva? I must know.', 6647, 1, 1, 3308, 0, 0, 0, '', 0),
+(3308, 0, 0, 'What do you mean?', 6649, 1, 1, 3307, 0, 0, 0, '', 0),
+(3307, 0, 0, 'Why didn''t you just leave?', 6651, 1, 1, 3306, 0, 0, 0, '', 0),
+(3306, 0, 0, 'So what happened?', 6653, 1, 1, 3305, 0, 0, 0, '', 0),
+(3305, 0, 0, 'No restraints? Just a circle?', 6655, 1, 1, 3304, 0, 0, 0, '', 0),
+(3304, 0, 0, 'Tell me more', 6657, 1, 1, 3303, 0, 0, 0, '', 0),
+(3303, 0, 0, 'This is an atrocity.', 6659, 1, 1, 3302, 0, 0, 0, '', 0),
+(3302, 0, 0, 'I feel sick', 6661, 1, 1, 3301, 0, 0, 0, '', 0),
+(3301, 0, 0, 'What can I do to help?', 45678, 1, 1, 0, 0, 0, 0, '', 0);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (3310);
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(15, 3310, 0, 0, 0, 8, 0, 5382, 0, 0, 1, 0, 0, '', 'Gossip Option requires Doctor Theolen Krastinov, the Butcher not rewarded'),
+(15, 3310, 0, 0, 0, 9, 0, 5382, 0, 0, 1, 0, 0, '', 'Gossip Option requires Doctor Theolen Krastinov, the Butcher not taken'),
+(15, 3310, 0, 0, 0, 28, 0, 5382, 0, 0, 1, 0, 0, '', 'Gossip Option requires Doctor Theolen Krastinov, the Butcher not complete'),
+(15, 3310, 1, 0, 0, 8, 0, 5384, 0, 0, 0, 0, 0, '', 'Gossip Option requires Kirtonos the Herald Rewarded'),
+(15, 3310, 1, 0, 0, 2, 0, 13544, 1, 0, 1, 0, 0, '', 'Gossip Option requires Player does not have Spectral Essence');
+
+UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (11216);
+DELETE FROM `smart_scripts` WHERE `entryorguid` IN(11216) 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
+(11216,0,0,1,62,0,100,0,3310,1,0,0,85,17672,2,0,0,0,0,7,0,0,0,0,0,0,0,'Eva Sarkhoff - On Gossip Option 1 Selected - Cast Summon Spectral Essence'),
+(11216,0,1,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Eva Sarkhoff - Link - Close Gossip'),
+(11216,0,3,4,62,0,100,0,3301,0,0,0,7,5382,0,0,0,0,0,7,0,0,0,0,0,0,0,'Eva Sarkhoff - On Gossip Option 0 Selected - Add Quest Doctor Theolen Krastinov, the Butcher'),
+(11216,0,4,0,61,0,100,0,0,0,0,0,72,0,0,0,0,0,0,7,0,0,0,0,0,0,0,'Eva Sarkhoff - Link - Close Gossip');
diff --git a/sql/updates/world/2014_06_08_00_world_conditions.sql b/sql/updates/world/2014_06_08_00_world_conditions.sql
new file mode 100644
index 00000000000..a0a885d5def
--- /dev/null
+++ b/sql/updates/world/2014_06_08_00_world_conditions.sql
@@ -0,0 +1 @@
+UPDATE `conditions` SET `ConditionTypeOrReference`=2,`ConditionValue2`=1,`NegativeCondition`=1 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=9422 AND `ConditionTypeOrReference`=26 AND `ConditionValue1`=36734;
diff --git a/sql/updates/world/2014_06_08_01_world_gameobject.sql b/sql/updates/world/2014_06_08_01_world_gameobject.sql
new file mode 100644
index 00000000000..844d32ed393
--- /dev/null
+++ b/sql/updates/world/2014_06_08_01_world_gameobject.sql
@@ -0,0 +1,17 @@
+UPDATE `gameobject` SET `phaseMask`=1 WHERE `id` IN (192161, 192162);
+UPDATE `gameobject` SET `phaseMask`=9 WHERE `id`=193985;
+UPDATE `gameobject` SET `phaseMask`=12 WHERE `id` IN (190791, 190792, 190793, 190919, 190920, 190921, 190922, 190923, 190924, 190925, 190926, 190927, 190928, 190929);
+UPDATE `gameobject` SET `phaseMask`=19 WHERE `id` IN (190799, 190859, 190860, 190861, 190862, 190863, 190864, 190865, 190866, 190867, 190868, 190869, 190870, 190871, 190872, 190873, 190874, 190875, 190876, 190877, 190878, 190879, 190880, 190881, 190882, 190883, 190884, 190885, 190886, 190887, 190888, 190889, 190890, 190891, 190892, 190893, 190898, 190899, 190900, 190901, 190902, 190903, 190904, 190905, 190906, 190907, 190908, 190909, 190910, 190911, 190930, 190931, 190932, 190933, 190934);
+UPDATE `gameobject` SET `phaseMask`=32 WHERE `id` IN (192273, 192274, 192406, 192407, 192416, 192417, 192418, 192433);
+UPDATE `gameobject` SET `phaseMask`=35 WHERE `id` IN (190800, 191166, 191167, 191169, 191171, 191172, 191173, 191178, 191191);
+UPDATE `gameobject` SET `phaseMask`=51 WHERE `id`=190789;
+UPDATE `gameobject` SET `phaseMask`=64 WHERE `id` IN (192269, 192277, 192278, 192414, 192429, 193110, 193111, 193112, 193113, 193114, 193115, 193116, 193117, 193118, 193119, 193120, 193121, 193122, 193123);
+UPDATE `gameobject` SET `phaseMask`=66 WHERE `id`=192579;
+UPDATE `gameobject` SET `phaseMask`=128 WHERE `id` IN (191261, 191262, 191263, 191264, 191265, 191266, 191267, 191268, 191269, 191270, 191271);
+UPDATE `gameobject` SET `phaseMask`=129 WHERE `id` IN (192575, 192578);
+UPDATE `gameobject` SET `phaseMask`=193 WHERE `id` IN (192576, 192577);
+UPDATE `gameobject` SET `phaseMask`=198 WHERE `id` IN (192934, 192935, 192936, 192937, 192938, 192953, 192954, 192955, 192956, 192957, 192981);
+UPDATE `gameobject` SET `phaseMask`=204 WHERE `id` IN (190801, 190802, 190804, 190805, 190806, 190807, 190808, 190809, 190810, 190811, 190812, 190813, 190814, 190815, 190894, 190895, 190896, 190912, 190913, 190935, 191165, 191168, 191170, 191174, 191175, 191176, 191177, 191190);
+UPDATE `gameobject` SET `phaseMask`=257 WHERE `id`=192038;
+UPDATE `gameobject` SET `phaseMask`=510 WHERE `id` IN (192958, 192959, 192960, 192961, 192962, 192963, 192964, 192965, 192966, 192967, 192968, 192969, 192970, 192971, 192972, 192973, 192974, 192975, 192976, 192977, 192978, 192979, 192980, 192982, 192983, 192985, 192986, 192987, 192988, 192989, 192990, 192991, 192992, 192993, 192994, 192995, 192996, 192997, 192999, 193000, 193001, 193002);
+UPDATE `gameobject` SET `phaseMask`=511 WHERE `id` IN (192522, 192787);
diff --git a/sql/updates/world/2014_06_08_02_world_gameobject.sql b/sql/updates/world/2014_06_08_02_world_gameobject.sql
new file mode 100644
index 00000000000..5b5bfa9a90c
--- /dev/null
+++ b/sql/updates/world/2014_06_08_02_world_gameobject.sql
@@ -0,0 +1,40 @@
+SET @OGUID := 75166;
+
+DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+28;
+INSERT INTO `gameobject` (`guid`, `id`, `map`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`) VALUES
+(@OGUID+0, 192252, 571, 128, 5154.37, 2853.23, 409.183, 3.14159, 0, 0, 1, 0), -- Alliance Banner
+(@OGUID+1, 192253, 571, 128, 5154.42, 2828.93, 409.189, 3.14159, 0, 0, 1, 0), -- Alliance Banner
+(@OGUID+2, 192266, 571, 64, 4452.8, 2639, 358.552, 1.4748, 0, 0, -0.672366, 0.740219), -- Alliance Banner
+(@OGUID+3, 192267, 571, 128, 4452.76, 2639.14, 358.444, 1.67552, 0, 0, 0.743145, 0.66913), -- Horde Banner
+(@OGUID+4, 192268, 571, 128, 4526.51, 2810.18, 390.986, 3.26377, 0, 0, 0.998135, -0.061049), -- Horde Banner
+(@OGUID+5, 192270, 571, 64, 4424.71, 2975.6, 367.387, 1.69297, 0, 0, 0.748955, 0.662621), -- Alliance Banner
+(@OGUID+6, 192271, 571, 128, 4424.74, 2975.6, 367.227, 1.7017, 0, 0, 0.75184, 0.659346), -- Horde Banner
+(@OGUID+7, 192272, 571, 16, 4417.93, 2324.81, 371.219, 3.09796, 0, 0, 0.999762, 0.021815), -- Horde Banner
+(@OGUID+8, 192275, 571, 16, 4424.03, 3286.61, 371.418, 3.14159, 0, 0, 1, 0), -- Horde Banner
+(@OGUID+9, 192276, 571, 128, 4572.94, 3475.42, 362.805, 1.37881, 0, 0, 0.636078, 0.771625), -- Horde Banner
+(@OGUID+10, 192279, 571, 128, 4433.92, 3534.2, 359.942, 1.91113, 0, 0, -0.816641, 0.577146), -- Horde Banner
+(@OGUID+11, 192408, 571, 16, 4399.64, 3231.54, 368.898, 1.49226, 0, 0, 0.678801, 0.734322), -- Horde Banner
+(@OGUID+12, 192409, 571, 32, 4399.59, 3231.43, 369.216, 1.67552, 0, 0, -0.743145, 0.66913), -- Alliance Banner
+(@OGUID+13, 192415, 571, 64, 4517.79, 2716.99, 387.57, 1.53589, 0, 0, -0.694658, 0.71934), -- Alliance Banner
+(@OGUID+14, 192423, 571, 64, 4563.73, 2171.15, 367.68, 1.30027, 0, 0, 0.605294, 0.796002), -- Alliance Banner
+(@OGUID+15, 192424, 571, 128, 4563.7, 2171.03, 367.607, 1.82387, 0, 0, -0.79069, 0.612217), -- Horde Banner
+(@OGUID+16, 192430, 571, 64, 4434.56, 2883.45, 406.025, 0.759216, 0, 0, 0.370557, 0.92881), -- Alliance Banner
+(@OGUID+17, 192431, 571, 64, 4349.9, 2885.56, 406.105, 1.6057, 0, 0, 0.71934, 0.694658), -- Alliance Banner
+(@OGUID+18, 192432, 571, 16, 4401.62, 3377.48, 363.12, 1.53589, 0, 0, 0.694658, 0.71934), -- Horde Banner
+(@OGUID+19, 192440, 571, 128, 4438.38, 3361.01, 371.814, 0.0348707, 0, 0, -0.017452, 0.999848), -- Horde Banner
+(@OGUID+20, 192441, 571, 16, 4448.15, 3235.61, 370.617, 1.56207, 0, 0, -0.704015, 0.710185), -- Horde Banner
+(@OGUID+21, 192442, 571, 128, 4350.04, 2885.61, 406.329, 1.58825, 0, 0, 0.713251, 0.700909), -- Horde Banner
+(@OGUID+22, 192443, 571, 128, 4434.33, 2883.24, 406.346, 0.767944, 0, 0, 0.374607, 0.927184), -- Horde Banner
+(@OGUID+23, 192444, 571, 128, 4464.17, 2855.32, 406.391, 0.802851, 0, 0, 0.390731, 0.920505), -- Horde Banner
+(@OGUID+24, 192449, 571, 128, 4517.75, 2717.23, 387.812, 1.53589, 0, 0, -0.694658, 0.71934), -- Horde Banner
+(@OGUID+25, 192450, 571, 128, 4387.59, 2719.9, 390.201, 1.51843, 0, 0, -0.688354, 0.725375), -- Horde Banner
+(@OGUID+26, 192451, 571, 16, 4408.65, 2422.67, 377.454, 1.58825, 0, 0, 0.713251, 0.700909), -- Horde Banner
+(@OGUID+27, 192452, 571, 128, 4416.8, 2414.04, 377.487, 0.00895035, 0, 0, 0.004363, 0.99999), -- Horde Banner
+(@OGUID+28, 192453, 571, 16, 4417.56, 2301.07, 377.43, 0.017442, 0, 0, 0.008727, 0.999962); -- Horde Banner
+
+
+UPDATE `gameobject` SET `position_x`=4526.46, `position_y`=2810.18, `position_z`=391.2, `orientation`=3.28995 WHERE `id`=192269; -- Horde Banner
+UPDATE `gameobject` SET `position_x`=4991.04, `position_y`=2525.72, `position_z`=340.366, `orientation`=4.04916 WHERE `id`=192290; -- Horde Banner
+UPDATE `gameobject` SET `position_x`=4991.08, `position_y`=2525.76, `position_z`=340.918, `orientation`=4.04044 WHERE `id`=192291; -- Alliance Banner
+UPDATE `gameobject` SET `position_x`=5352.15, `position_y`=3054.77, `position_z`=444.61, `orientation`=1.57952 WHERE `id`=192376; -- Horde Banner
+UPDATE `gameobject` SET `position_x`=4408.57, `position_y`=2422.61, `position_z`=377.179, `orientation`=1.58825 WHERE `id`=192416; -- Alliance Banner
diff --git a/sql/updates/world/2014_06_08_03_world_gameobject.sql b/sql/updates/world/2014_06_08_03_world_gameobject.sql
new file mode 100644
index 00000000000..8fe57fa39b5
--- /dev/null
+++ b/sql/updates/world/2014_06_08_03_world_gameobject.sql
@@ -0,0 +1 @@
+DELETE FROM `gameobject` WHERE `guid` IN (66459, 66460, 66461, 66462, 66463, 66464, 66465, 66466, 66467, 66468, 66469, 66470, 66478, 66479, 66516, 66518, 66520, 66600, 66601, 66602, 66603, 66604, 66605, 66606, 66607, 66608, 66609, 66610, 74688, 74690, 74696, 74698, 74702, 74704, 74706, 74712, 74714, 74720, 74722, 74724, 74726, 74728, 74730, 74732, 74734, 74736, 74738, 74740, 74742, 74744, 74746, 74748, 74750, 74752, 74754, 74756, 74758, 74760, 74762, 74764, 74766, 74768, 74770, 74772);
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index d1b2b614037..be6623c7fa3 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -179,24 +179,24 @@ extern int main(int argc, char** argv)
Handler.register_handler(SIGTERM, &SignalTERM);
#if defined(_WIN32) || defined(__linux__)
-
+
///- Handle affinity for multiple processors and process priority
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
#ifdef _WIN32 // Windows
-
+
HANDLE hProcess = GetCurrentProcess();
if (affinity > 0)
{
ULONG_PTR appAff;
ULONG_PTR sysAff;
-
+
if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
{
// remove non accessible processors
ULONG_PTR currentAffinity = affinity & appAff;
-
+
if (!currentAffinity)
TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff);
else if (SetProcessAffinityMask(hProcess, currentAffinity))
@@ -205,7 +205,7 @@ extern int main(int argc, char** argv)
TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity);
}
}
-
+
if (highPriority)
{
if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
@@ -213,9 +213,9 @@ extern int main(int argc, char** argv)
else
TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class.");
}
-
+
#else // Linux
-
+
if (affinity > 0)
{
cpu_set_t mask;
@@ -242,7 +242,7 @@ extern int main(int argc, char** argv)
else
TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
}
-
+
#endif
#endif
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index dd8b42deb9f..ac9de00cd10 100644
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -43,6 +43,11 @@ void CreatureAI::Talk(uint8 id, WorldObject const* whisperTarget /*= NULL*/)
sCreatureTextMgr->SendChat(me, id, whisperTarget);
}
+void CreatureAI::TalkToMap(uint8 id, WorldObject const* whisperTarget /*= NULL*/)
+{
+ sCreatureTextMgr->SendChat(me, id, whisperTarget, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
+}
+
void CreatureAI::DoZoneInCombat(Creature* creature /*= NULL*/, float maxRangeToNearestTarget /* = 50.0f*/)
{
if (!creature)
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index 6357ac33f1e..209995d359d 100644
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -79,6 +79,7 @@ class CreatureAI : public UnitAI
public:
void Talk(uint8 id, WorldObject const* whisperTarget = NULL);
+ void TalkToMap(uint8 id, WorldObject const* whisperTarget = NULL);
explicit CreatureAI(Creature* creature) : UnitAI(creature), me(creature), m_MoveInLineOfSight_locked(false) { }
virtual ~CreatureAI() { }
diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h
index 378d3ca18ab..838171a544e 100644
--- a/src/server/game/AI/CreatureAIImpl.h
+++ b/src/server/game/AI/CreatureAIImpl.h
@@ -311,355 +311,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c
}
}
-class EventMap
-{
- /**
- * Internal storage type.
- * Key: Time as uint32 when the event should occur.
- * Value: The event data as uint32.
- *
- * Structure of event data:
- * - Bit 0 - 15: Event Id.
- * - Bit 16 - 23: Group
- * - Bit 24 - 31: Phase
- * - Pattern: 0xPPGGEEEE
- */
- typedef std::multimap<uint32, uint32> EventStore;
-
- public:
- EventMap() : _time(0), _phase(0), _lastEvent(0) { }
-
- /**
- * @name Reset
- * @brief Removes all scheduled events and resets time and phase.
- */
- void Reset()
- {
- _eventMap.clear();
- _time = 0;
- _phase = 0;
- }
-
- /**
- * @name Update
- * @brief Updates the timer of the event map.
- * @param time Value to be added to time.
- */
- void Update(uint32 time)
- {
- _time += time;
- }
-
- /**
- * @name GetTimer
- * @return Current timer value.
- */
- uint32 GetTimer() const
- {
- return _time;
- }
-
- /**
- * @name GetPhaseMask
- * @return Active phases as mask.
- */
- uint8 GetPhaseMask() const
- {
- return _phase;
- }
-
- /**
- * @name Empty
- * @return True, if there are no events scheduled.
- */
- bool Empty() const
- {
- return _eventMap.empty();
- }
-
- /**
- * @name SetPhase
- * @brief Sets the phase of the map (absolute).
- * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase.
- */
- void SetPhase(uint8 phase)
- {
- if (!phase)
- _phase = 0;
- else if (phase <= 8)
- _phase = (1 << (phase - 1));
- }
-
- /**
- * @name AddPhase
- * @brief Activates the given phase (bitwise).
- * @param phase Phase which should be activated. Values: 1 - 8
- */
- void AddPhase(uint8 phase)
- {
- if (phase && phase <= 8)
- _phase |= (1 << (phase - 1));
- }
-
- /**
- * @name RemovePhase
- * @brief Deactivates the given phase (bitwise).
- * @param phase Phase which should be deactivated. Values: 1 - 8.
- */
- void RemovePhase(uint8 phase)
- {
- if (phase && phase <= 8)
- _phase &= ~(1 << (phase - 1));
- }
-
- /**
- * @name ScheduleEvent
- * @brief Creates new event entry in map.
- * @param eventId The id of the new event.
- * @param time The time in milliseconds until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
- {
- if (group && group <= 8)
- eventId |= (1 << (group + 15));
-
- if (phase && phase <= 8)
- eventId |= (1 << (phase + 23));
-
- _eventMap.insert(EventStore::value_type(_time + time, eventId));
- }
-
- /**
- * @name RescheduleEvent
- * @brief Cancels the given event and reschedules it.
- * @param eventId The id of the event.
- * @param time The time in milliseconds until the event occurs.
- * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
- * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
- */
- void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
- {
- CancelEvent(eventId);
- ScheduleEvent(eventId, time, group, phase);
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event.
- * @param time Time until the event occurs.
- */
- void Repeat(uint32 time)
- {
- _eventMap.insert(EventStore::value_type(_time + time, _lastEvent));
- }
-
- /**
- * @name RepeatEvent
- * @brief Repeats the mostly recently executed event.
- * @param time Time until the event occurs. Equivalent to Repeat(urand(minTime, maxTime).
- */
- void Repeat(uint32 minTime, uint32 maxTime)
- {
- Repeat(urand(minTime, maxTime));
- }
-
- /**
- * @name ExecuteEvent
- * @brief Returns the next event to execute and removes it from map.
- * @return Id of the event to execute.
- */
- uint32 ExecuteEvent()
- {
- while (!Empty())
- {
- EventStore::iterator itr = _eventMap.begin();
-
- if (itr->first > _time)
- return 0;
- else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase))
- _eventMap.erase(itr);
- else
- {
- uint32 eventId = (itr->second & 0x0000FFFF);
- _lastEvent = itr->second; // include phase/group
- _eventMap.erase(itr);
- return eventId;
- }
- }
-
- return 0;
- }
-
- /**
- * @name DelayEvents
- * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0.
- * @param delay Amount of delay.
- */
- void DelayEvents(uint32 delay)
- {
- _time = delay < _time ? _time - delay : 0;
- }
-
- /**
- * @name DelayEvents
- * @brief Delay all events of the same group.
- * @param delay Amount of delay.
- * @param group Group of the events.
- */
- void DelayEvents(uint32 delay, uint32 group)
- {
- if (!group || group > 8 || Empty())
- return;
-
- EventStore delayed;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (itr->second & (1 << (group + 15)))
- {
- delayed.insert(EventStore::value_type(itr->first + delay, itr->second));
- _eventMap.erase(itr++);
- }
- else
- ++itr;
- }
-
- _eventMap.insert(delayed.begin(), delayed.end());
- }
-
- /**
- * @name CancelEvent
- * @brief Cancels all events of the specified id.
- * @param eventId Event id to cancel.
- */
- void CancelEvent(uint32 eventId)
- {
- if (Empty())
- return;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (eventId == (itr->second & 0x0000FFFF))
- _eventMap.erase(itr++);
- else
- ++itr;
- }
- }
-
- /**
- * @name CancelEventGroup
- * @brief Cancel events belonging to specified group.
- * @param group Group to cancel.
- */
- void CancelEventGroup(uint32 group)
- {
- if (!group || group > 8 || Empty())
- return;
-
- for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
- {
- if (itr->second & (1 << (group + 15)))
- _eventMap.erase(itr++);
- else
- ++itr;
- }
- }
-
- /**
- * @name GetNextEventTime
- * @brief Returns closest occurence of specified event.
- * @param eventId Wanted event id.
- * @return Time of found event.
- */
- uint32 GetNextEventTime(uint32 eventId) const
- {
- if (Empty())
- return 0;
-
- for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
- if (eventId == (itr->second & 0x0000FFFF))
- return itr->first;
-
- return 0;
- }
-
- /**
- * @name GetNextEventTime
- * @return Time of next event.
- */
- uint32 GetNextEventTime() const
- {
- return Empty() ? 0 : _eventMap.begin()->first;
- }
-
- /**
- * @name IsInPhase
- * @brief Returns wether event map is in specified phase or not.
- * @param phase Wanted phase.
- * @return True, if phase of event map contains specified phase.
- */
- bool IsInPhase(uint8 phase)
- {
- return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
- }
-
- /**
- * @name GetTimeUntilEvent
- * @brief Returns time in milliseconds until next event.
- * @param Id of the event.
- * @return Time of next event.
- */
- uint32 GetTimeUntilEvent(uint32 eventId) const
- {
- for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
- if (eventId == (itr->second & 0x0000FFFF))
- return itr->first - _time;
-
- return std::numeric_limits<uint32>::max();
- }
-
- private:
- /**
- * @name _time
- * @brief Internal timer.
- *
- * This does not represent the real date/time value.
- * It's more like a stopwatch: It can run, it can be stopped,
- * it can be resetted and so on. Events occur when this timer
- * has reached their time value. Its value is changed in the
- * Update method.
- */
- uint32 _time;
-
- /**
- * @name _phase
- * @brief Phase mask of the event map.
- *
- * Contains the phases the event map is in. Multiple
- * phases from 1 to 8 can be set with SetPhase or
- * AddPhase. RemovePhase deactives a phase.
- */
- uint8 _phase;
-
- /**
- * @name _eventMap
- * @brief Internal event storage map. Contains the scheduled events.
- *
- * See typedef at the beginning of the class for more
- * details.
- */
- EventStore _eventMap;
-
-
- /**
- * @name _lastEvent
- * @brief Stores information on the most recently executed event
- */
- uint32 _lastEvent;
-};
-
enum AITarget
{
AITARGET_SELF,
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 4cf7d34cc11..370696474ae 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1404,6 +1404,7 @@ void GameObject::Use(Unit* user)
// prevent removing GO at spell cancel
RemoveFromOwner();
SetOwnerGUID(player->GetGUID());
+ SetSpellId(0); // prevent removing unintended auras at Unit::RemoveGameObject
/// @todo find reasonable value for fishing hole search
GameObject* ok = LookupFishingHoleAround(20.0f + CONTACT_DISTANCE);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 433551104b9..b73a542a92b 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -689,7 +689,7 @@ Player::Player(WorldSession* session): Unit(true)
m_areaUpdateId = 0;
m_team = 0;
-
+
m_needsZoneUpdate = false;
m_nextSave = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE);
@@ -5964,6 +5964,8 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
ApplyCastTimePercentMod(oldVal, false);
ApplyCastTimePercentMod(newVal, true);
break;
+ default: // shut up compiler warnings
+ break;
}
}
@@ -16381,12 +16383,8 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count)
uint16 curitemcount = q_status.ItemCount[j];
if (curitemcount < reqitemcount)
{
- uint16 additemcount = curitemcount + count <= reqitemcount ? count : reqitemcount - curitemcount;
- q_status.ItemCount[j] += additemcount;
-
+ q_status.ItemCount[j] = std::min<uint16>(q_status.ItemCount[j] + count, reqitemcount);
m_QuestStatusSave[questid] = true;
-
- SendQuestUpdateAddItem(qInfo, j, additemcount);
}
if (CanCompleteQuest(questid))
CompleteQuest(questid);
@@ -16404,9 +16402,11 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
uint32 questid = GetQuestSlotQuestId(i);
if (!questid)
continue;
+
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
if (!qInfo)
continue;
+
if (!qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
continue;
@@ -16418,18 +16418,17 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
QuestStatusData& q_status = m_QuestStatus[questid];
uint32 reqitemcount = qInfo->RequiredItemCount[j];
- uint16 curitemcount;
- if (q_status.Status != QUEST_STATUS_COMPLETE)
- curitemcount = q_status.ItemCount[j];
- else
- curitemcount = GetItemCount(entry, true);
- if (curitemcount < reqitemcount + count)
- {
- uint16 remitemcount = curitemcount <= reqitemcount ? count : count + reqitemcount - curitemcount;
- q_status.ItemCount[j] = (curitemcount <= remitemcount) ? 0 : curitemcount - remitemcount;
+ uint16 curitemcount = q_status.ItemCount[j];
- m_QuestStatusSave[questid] = true;
+ if (q_status.ItemCount[j] >= reqitemcount) // we may have more than what the status shows
+ curitemcount = GetItemCount(entry, false);
+ uint16 newItemCount = (count > curitemcount) ? 0 : curitemcount - count;
+ newItemCount = std::min<uint16>(newItemCount, reqitemcount);
+ if (newItemCount != q_status.ItemCount[j])
+ {
+ q_status.ItemCount[j] = newItemCount;
+ m_QuestStatusSave[questid] = true;
IncompleteQuest(questid);
}
return;
@@ -26757,3 +26756,8 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
return pet;
}
+
+bool Player::IsLoading() const
+{
+ return GetSession()->PlayerLoading();
+}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 52674032c0a..aeac9db98aa 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1676,7 +1676,7 @@ class Player : public Unit, public GridObject<Player>
void UpdateZone(uint32 newZone, uint32 newArea);
void UpdateArea(uint32 newArea);
void SetNeedsZoneUpdate(bool needsUpdate) { m_needsZoneUpdate = needsUpdate; }
-
+
void UpdateZoneDependentAuras(uint32 zone_id); // zones
void UpdateAreaDependentAuras(uint32 area_id); // subzones
@@ -2303,6 +2303,8 @@ class Player : public Unit, public GridObject<Player>
std::string GetMapAreaAndZoneString();
std::string GetCoordsMapAreaAndZoneString();
+ bool IsLoading() const;
+
protected:
// Gamemaster whisper whitelist
WhisperListContainer WhisperList;
@@ -2562,7 +2564,7 @@ class Player : public Unit, public GridObject<Player>
bool IsAlwaysDetectableFor(WorldObject const* seer) const;
uint8 m_grantableLevels;
-
+
bool m_needsZoneUpdate;
private:
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index aa8698f5480..43b12cb0cba 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -10279,7 +10279,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
int32 TakenTotal = 0;
float TakenTotalMod = 1.0f;
float TakenTotalCasterMod = 0.0f;
-
+
// Mod damage from spell mechanic
if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
{
@@ -11161,8 +11161,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons
// Check for immune to application of harmful magical effects
AuraEffectList const& immuneAuraApply = GetAuraEffectsByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
for (AuraEffectList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
- if (spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff
- ((*iter)->GetMiscValue() & spellInfo->GetSchoolMask()) && // Check school
+ if (((*iter)->GetMiscValue() & spellInfo->GetSchoolMask()) && // Check school
!spellInfo->IsPositiveEffect(index)) // Harmful
return true;
}
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 278c180c380..0a797f0e008 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -235,20 +235,28 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData.ReadPackedTime(unkPackedTime);
recvData >> flags;
- CalendarEvent calendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
+ // prevent events in the past
+ // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
+ if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L)))
+ {
+ recvData.rfinish();
+ return;
+ }
+
+ CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
- if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
+ if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
if (Player* creator = ObjectAccessor::FindPlayer(guid))
- calendarEvent.SetGuildId(creator->GetGuildId());
+ calendarEvent->SetGuildId(creator->GetGuildId());
- if (calendarEvent.IsGuildAnnouncement())
+ if (calendarEvent->IsGuildAnnouncement())
{
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite invite(0, calendarEvent.GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
+ CalendarInvite invite(0, calendarEvent->GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
// WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind
// of storage of the pointer as it will lead to memory corruption
- sCalendarMgr->AddInvite(&calendarEvent, &invite);
+ sCalendarMgr->AddInvite(calendarEvent, &invite);
}
else
{
@@ -271,15 +279,15 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData >> status >> rank;
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent.GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
- sCalendarMgr->AddInvite(&calendarEvent, invite, trans);
+ CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
+ sCalendarMgr->AddInvite(calendarEvent, invite, trans);
}
if (inviteCount > 1)
CharacterDatabase.CommitTransaction(trans);
}
- sCalendarMgr->AddEvent(new CalendarEvent(calendarEvent, calendarEvent.GetEventId()), CALENDAR_SENDTYPE_ADD);
+ sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
}
void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
@@ -304,6 +312,14 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
recvData.ReadPackedTime(timeZoneTime);
recvData >> flags;
+ // prevent events in the past
+ // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
+ if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L)))
+ {
+ recvData.rfinish();
+ return;
+ }
+
TC_LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [" UI64FMTD "] EventId [" UI64FMTD
"], InviteId [" UI64FMTD "] Title %s, Description %s, type %u "
"Repeatable %u, MaxInvites %u, Dungeon ID %d, Time %u "
@@ -346,17 +362,25 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData)
uint64 guid = _player->GetGUID();
uint64 eventId;
uint64 inviteId;
- uint32 time;
+ uint32 eventTime;
recvData >> eventId >> inviteId;
- recvData.ReadPackedTime(time);
+ recvData.ReadPackedTime(eventTime);
TC_LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [" UI64FMTD "], EventId [" UI64FMTD
- "] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, time);
+ "] inviteId [" UI64FMTD "] Time: %u", guid, eventId, inviteId, eventTime);
+
+ // prevent events in the past
+ // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
+ if (time_t(eventTime) < (time(NULL) - time_t(86400L)))
+ {
+ recvData.rfinish();
+ return;
+ }
if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
{
CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
- newEvent->SetEventTime(time_t(time));
+ newEvent->SetEventTime(time_t(eventTime));
sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 7d9d83abfde..d4af17ca78b 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -761,7 +761,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
{
if (PlayerLoading() || GetPlayer() != NULL)
{
- TC_LOG_ERROR("network", "Player tryes to login again, AccountId = %d", GetAccountId());
+ TC_LOG_ERROR("network", "Player tries to login again, AccountId = %d", GetAccountId());
KickPlayer();
return;
}
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 0ca7885b82b..3ef99cc2fc1 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -85,6 +85,18 @@ void WorldSession::HandleSwapInvItemOpcode(WorldPacket& recvData)
return;
}
+ if (_player->IsBankPos(INVENTORY_SLOT_BAG_0, srcslot) && !CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(m_currentBankerGUID)));
+ return;
+ }
+
+ if (_player->IsBankPos(INVENTORY_SLOT_BAG_0, dstslot) && !CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(m_currentBankerGUID)));
+ return;
+ }
+
uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
@@ -137,6 +149,18 @@ void WorldSession::HandleSwapItem(WorldPacket& recvData)
return;
}
+ if (_player->IsBankPos(srcbag, srcslot) && !CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(m_currentBankerGUID)));
+ return;
+ }
+
+ if (_player->IsBankPos(dstbag, dstslot) && !CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(m_currentBankerGUID)));
+ return;
+ }
+
_player->SwapItem(src, dst);
}
@@ -858,15 +882,11 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
uint64 guid;
recvPacket >> guid;
- // cheating protection
- /* not critical if "cheated", and check skip allow by slots in bank windows open by .bank command.
- Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER);
- if (!creature)
+ if (!CanUseBank(guid))
{
- TC_LOG_DEBUG("WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
+ TC_LOG_DEBUG("network", "WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
return;
}
- */
uint32 slot = _player->GetBankBagSlotCount();
@@ -912,6 +932,12 @@ void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket)
recvPacket >> srcbag >> srcslot;
TC_LOG_DEBUG("network", "STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot);
+ if (!CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleAutoBankItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(m_currentBankerGUID)));
+ return;
+ }
+
Item* pItem = _player->GetItemByPos(srcbag, srcslot);
if (!pItem)
return;
@@ -943,6 +969,12 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket)
recvPacket >> srcbag >> srcslot;
TC_LOG_DEBUG("network", "STORAGE: receive srcbag = %u, srcslot = %u", srcbag, srcslot);
+ if (!CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(m_currentBankerGUID)));
+ return;
+ }
+
Item* pItem = _player->GetItemByPos(srcbag, srcslot);
if (!pItem)
return;
@@ -1441,3 +1473,21 @@ void WorldSession::HandleItemTextQuery(WorldPacket& recvData )
SendPacket(&data);
}
+
+bool WorldSession::CanUseBank(uint64 bankerGUID) const
+{
+ // bankerGUID parameter is optional, set to 0 by default.
+ if (!bankerGUID)
+ bankerGUID = m_currentBankerGUID;
+
+ bool isUsingBankCommand = (bankerGUID == GetPlayer()->GetGUID() && bankerGUID == m_currentBankerGUID);
+
+ if (!isUsingBankCommand)
+ {
+ Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(bankerGUID, UNIT_NPC_FLAG_BANKER);
+ if (!creature)
+ return false;
+ }
+
+ return true;
+} \ No newline at end of file
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 11fa89d9d6b..c4ff2581e75 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -502,7 +502,7 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket& recvData)
// use server side data, but only after update the player position. See Player::UpdatePosition().
GetPlayer()->SetNeedsZoneUpdate(true);
-
+
//GetPlayer()->SendInitWorldStates(true, newZone);
}
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index fc14797ea94..d8a518a24db 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -100,6 +100,7 @@ void WorldSession::SendShowBank(uint64 guid)
{
WorldPacket data(SMSG_SHOW_BANK, 8);
data << guid;
+ m_currentBankerGUID = guid;
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 616ea9c7326..d64f21f2028 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -868,7 +868,10 @@ void WorldSession::HandleLearnPreviewTalentsPet(WorldPacket& recvData)
uint32 talentId, talentRank;
- for (uint32 i = 0; i < talentsCount; ++i)
+ // Client has max 24 talents, rounded up : 30
+ uint32 const MaxTalentsCount = 30;
+
+ for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
{
recvData >> talentId >> talentRank;
@@ -876,4 +879,6 @@ void WorldSession::HandleLearnPreviewTalentsPet(WorldPacket& recvData)
}
_player->SendTalentsInfoData(true);
+
+ recvData.rfinish();
}
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index fe893314b87..f90dfef2684 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -45,7 +45,10 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
uint32 talentId, talentRank;
- for (uint32 i = 0; i < talentsCount; ++i)
+ // Client has max 44 talents for tree for 3 trees, rounded up : 150
+ uint32 const MaxTalentsCount = 150;
+
+ for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
{
recvPacket >> talentId >> talentRank;
@@ -53,6 +56,8 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
}
_player->SendTalentsInfoData(false);
+
+ recvPacket.rfinish();
}
void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index 1378f9b3f2d..a2aa426c096 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -187,6 +187,7 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData)
uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
recvData >> mainSurvey;
+ std::unordered_set<uint32> surveyIds;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
for (uint8 i = 0; i < 10; i++)
@@ -201,6 +202,10 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData)
std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
recvData >> comment;
+ // make sure the same sub survey is not added to DB twice
+ if (!surveyIds.insert(subSurveyId).second)
+ continue;
+
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SUBSURVEY);
stmt->setUInt32(0, nextSurveyID);
stmt->setUInt32(1, subSurveyId);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index ba271235330..d3be33cb441 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2854,10 +2854,9 @@ bool InstanceMap::CanEnter(Player* player)
return false;
}
- // cannot enter while an encounter is in progress on raids
- /*Group* group = player->GetGroup();
- if (!player->IsGameMaster() && group && group->InCombatToInstance(GetInstanceId()) && player->GetMapId() != GetId())*/
- if (IsRaid() && GetInstanceScript() && GetInstanceScript()->IsEncounterInProgress())
+ // cannot enter while an encounter is in progress
+ // allow if just loading
+ if (!player->IsLoading() && IsRaid() && GetInstanceScript() && GetInstanceScript()->IsEncounterInProgress())
{
player->SendTransferAborted(GetId(), TRANSFER_ABORT_ZONE_IN_COMBAT);
return false;
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 9f052b75386..f8df683d90c 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -121,7 +121,10 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
m_TutorialsChanged(false),
recruiterId(recruiter),
isRecruiter(isARecruiter),
- _RBACData(NULL)
+ _RBACData(NULL),
+ expireTime(60000), // 1 min after socket loss, session is deleted
+ forceExit(false),
+ m_currentBankerGUID(0)
{
memset(m_Tutorials, 0, sizeof(m_Tutorials));
@@ -419,8 +422,12 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
///- Cleanup socket pointer if need
if (m_Socket && m_Socket->IsClosed())
{
- m_Socket->RemoveReference();
- m_Socket = NULL;
+ expireTime -= expireTime > diff ? diff : expireTime;
+ if (expireTime < diff || forceExit)
+ {
+ m_Socket->RemoveReference();
+ m_Socket = NULL;
+ }
}
if (!m_Socket)
@@ -446,7 +453,6 @@ void WorldSession::LogoutPlayer(bool save)
DoLootRelease(lguid);
///- If the player just died before logging out, make him appear as a ghost
- //FIXME: logout must be delayed in case lost connection with client in time of combat
if (_player->GetDeathTimer())
{
_player->getHostileRefManager().deleteReferences();
@@ -576,7 +582,10 @@ void WorldSession::LogoutPlayer(bool save)
void WorldSession::KickPlayer()
{
if (m_Socket)
+ {
m_Socket->CloseSocket();
+ forceExit = true;
+ }
}
void WorldSession::SendNotification(const char *format, ...)
@@ -1251,11 +1260,11 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co
if (++packetCounter.amountCounter > maxPacketCounterAllowed)
{
dosTriggered = true;
- TC_LOG_WARN("network", "AntiDOS: Account %u, IP: %s, Character: %s, flooding packet (opc: %s (0x%X), count: %u)",
- Session->GetAccountId(), Session->GetRemoteAddress().c_str(), Session->GetPlayerName().c_str(),
+ TC_LOG_WARN("network", "AntiDOS: Account %u, IP: %s, Ping: %u, Character: %s, flooding packet (opc: %s (0x%X), count: %u)",
+ Session->GetAccountId(), Session->GetRemoteAddress().c_str(), Session->GetLatency(), Session->GetPlayerName().c_str(),
opcodeTable[p.GetOpcode()].name, p.GetOpcode(), packetCounter.amountCounter);
}
-
+
// Then check if player is sending packets not allowed
if (!IsOpcodeAllowed(p.GetOpcode()))
{
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 968f5a229ba..2f5f17952db 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -975,6 +975,8 @@ class WorldSession
// private trade methods
void moveItems(Item* myItems[], Item* hisItems[]);
+ bool CanUseBank(uint64 bankerGUID = 0) const;
+
// logging helper
void LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason);
void LogUnprocessedTail(WorldPacket* packet);
@@ -1021,6 +1023,9 @@ class WorldSession
bool isRecruiter;
ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
rbac::RBACData* _RBACData;
+ uint32 expireTime;
+ bool forceExit;
+ uint64 m_currentBankerGUID;
WorldSession(WorldSession const& right) = delete;
WorldSession& operator=(WorldSession const& right) = delete;
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 977578ddd7a..138e6b84d0a 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1668,9 +1668,6 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
if (aurApp->GetRemoveMode())
return;
- if (modelid > 0)
- target->SetDisplayId(modelid);
-
if (PowerType != POWER_MANA)
{
uint32 oldPower = target->GetPower(PowerType);
@@ -1721,6 +1718,12 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
return;
target->SetShapeshiftForm(form);
+ if (modelid > 0)
+ {
+ SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(target->getTransForm());
+ if (!transformSpellInfo || !GetSpellInfo()->IsPositive())
+ target->SetDisplayId(modelid);
+ }
}
else
{
@@ -1843,9 +1846,11 @@ void AuraEffect::HandleAuraTransform(AuraApplication const* aurApp, uint8 mode,
if (apply)
{
- // update active transform spell only when transform or shapeshift not set or not overwriting negative by positive case
- if (!target->GetModelForForm(target->GetShapeshiftForm()) || !GetSpellInfo()->IsPositive())
+ // update active transform spell only when transform not set or not overwriting negative by positive case
+ SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(target->getTransForm());
+ if (!transformSpellInfo || !GetSpellInfo()->IsPositive() || transformSpellInfo->IsPositive())
{
+ target->setTransForm(GetId());
// special case (spell specific functionality)
if (GetMiscValue() == 0)
{
@@ -2014,11 +2019,6 @@ void AuraEffect::HandleAuraTransform(AuraApplication const* aurApp, uint8 mode,
}
}
- // update active transform spell only when transform or shapeshift not set or not overwriting negative by positive case
- SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(target->getTransForm());
- if (!transformSpellInfo || !GetSpellInfo()->IsPositive() || transformSpellInfo->IsPositive())
- target->setTransForm(GetId());
-
// polymorph case
if ((mode & AURA_EFFECT_HANDLE_REAL) && target->GetTypeId() == TYPEID_PLAYER && target->IsPolymorphed())
{
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index cdd6f9ecfd1..ca170187e82 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -567,7 +567,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme
m_spellState = SPELL_STATE_NULL;
_triggeredCastFlags = triggerFlags;
if (info->AttributesEx4 & SPELL_ATTR4_TRIGGERED)
- _triggeredCastFlags = TRIGGERED_FULL_MASK;
+ _triggeredCastFlags = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT);
m_CastItem = NULL;
m_castItemGUID = 0;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 4aced0c92dd..b94d0def3dd 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -784,14 +784,14 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
bool hasFamilyMask = false;
- /**
-
+ /**
+
* @brief Check auras procced by periodics
*Only damaging Dots can proc auras with PROC_FLAG_TAKEN_DAMAGE
*Only Dots can proc if ONLY has PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC.
-
+
*Hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC and spellfamily != 0
*Only Dots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
@@ -806,7 +806,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
* @param procFlags proc_flags of spellProc
* @param procExtra proc_EX of procSpell
* @param EventProcFlag proc_flags of aura to be procced
- * @param spellProto SpellInfo of aura to be procced
+ * @param spellProto SpellInfo of aura to be procced
*/
@@ -815,7 +815,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
return true;
if (procFlags & PROC_FLAG_DONE_PERIODIC && EventProcFlag & PROC_FLAG_DONE_PERIODIC)
- {
+ {
if (procExtra & PROC_EX_INTERNAL_HOT)
{
if (EventProcFlag == PROC_FLAG_DONE_PERIODIC)
@@ -835,7 +835,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, Spell
}
if (procFlags & PROC_FLAG_TAKEN_PERIODIC && EventProcFlag & PROC_FLAG_TAKEN_PERIODIC)
- {
+ {
if (procExtra & PROC_EX_INTERNAL_HOT)
{
/// No aura that only has PROC_FLAG_TAKEN_PERIODIC can proc from a HOT.
@@ -3385,6 +3385,9 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd
spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd
break;
+ case 72830: // Achievement Check
+ spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ break;
case 72900: // Start Halls of Reflection Quest AE
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp
index 57690d7e5c1..8bd7a5a5e71 100644
--- a/src/server/game/Texts/CreatureTextMgr.cpp
+++ b/src/server/game/Texts/CreatureTextMgr.cpp
@@ -24,6 +24,7 @@
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CreatureTextMgr.h"
+#include "Group.h"
class CreatureTextBuilder
{
@@ -346,6 +347,18 @@ void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data,
}
break;
}
+ case CHAT_MSG_MONSTER_PARTY:
+ if (!whisperTarget)
+ return;
+
+ if (Player const* player = whisperTarget->ToPlayer())
+ {
+ if (Group* group = const_cast<Group*>(player->GetGroup()))
+ for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (Player* member = itr->GetSource())
+ member->GetSession()->SendPacket(data);
+ }
+ return;
default:
break;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp
index 4ac039e9138..3e4097daf20 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -24,64 +23,74 @@ enum Spells
SPELL_FIREBLAST = 15573
};
-class boss_ambassador_flamelash : public CreatureScript
+enum Events
{
-public:
- boss_ambassador_flamelash() : CreatureScript("boss_ambassador_flamelash") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_ambassador_flamelashAI(creature);
- }
-
- struct boss_ambassador_flamelashAI : public ScriptedAI
- {
- boss_ambassador_flamelashAI(Creature* creature) : ScriptedAI(creature) { }
+ EVENT_FIREBLAST = 1,
+ EVENT_SUMMON_SPIRITS = 2
+};
- uint32 FireBlast_Timer;
- uint32 Spirit_Timer;
+class boss_ambassador_flamelash : public CreatureScript
+{
+ public:
+ boss_ambassador_flamelash() : CreatureScript("boss_ambassador_flamelash") { }
- void Reset() override
+ struct boss_ambassador_flamelashAI : public ScriptedAI
{
- FireBlast_Timer = 2000;
- Spirit_Timer = 24000;
- }
+ boss_ambassador_flamelashAI(Creature* creature) : ScriptedAI(creature) { }
- void EnterCombat(Unit* /*who*/) override { }
-
- void SummonSpirits(Unit* victim)
- {
- if (Creature* Spirit = DoSpawnCreature(9178, float(irand(-9, 9)), float(irand(-9, 9)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000))
- Spirit->AI()->AttackStart(victim);
- }
+ void Reset() override
+ {
+ _events.Reset();
+ }
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_FIREBLAST, 2000);
+ _events.ScheduleEvent(EVENT_SUMMON_SPIRITS, 24000);
+ }
- //FireBlast_Timer
- if (FireBlast_Timer <= diff)
+ void SummonSpirit(Unit* victim)
{
- DoCastVictim(SPELL_FIREBLAST);
- FireBlast_Timer = 7000;
- } else FireBlast_Timer -= diff;
+ if (Creature* spirit = DoSpawnCreature(9178, frand(-9, 9), frand(-9, 9), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000))
+ spirit->AI()->AttackStart(victim);
+ }
- //Spirit_Timer
- if (Spirit_Timer <= diff)
+ void UpdateAI(uint32 diff) override
{
- SummonSpirits(me->GetVictim());
- SummonSpirits(me->GetVictim());
- SummonSpirits(me->GetVictim());
- SummonSpirits(me->GetVictim());
+ if (!UpdateVictim())
+ return;
- Spirit_Timer = 30000;
- } else Spirit_Timer -= diff;
+ _events.Update(diff);
- DoMeleeAttackIfReady();
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FIREBLAST:
+ DoCastVictim(SPELL_FIREBLAST);
+ _events.ScheduleEvent(EVENT_FIREBLAST, 7000);
+ break;
+ case EVENT_SUMMON_SPIRITS:
+ for (uint32 i = 0; i < 4; ++i)
+ SummonSpirit(me->GetVictim());
+ _events.ScheduleEvent(EVENT_SUMMON_SPIRITS, 30000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_ambassador_flamelashAI(creature);
}
- };
};
void AddSC_boss_ambassador_flamelash()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp
index fd8b77ea8d4..894b528c03c 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -21,90 +20,94 @@
enum Spells
{
- SPELL_SHADOWBOLT = 17228,
- SPELL_CURSEOFTONGUES = 15470,
- SPELL_CURSEOFWEAKNESS = 17227,
- SPELL_DEMONARMOR = 11735,
- SPELL_ENVELOPINGWEB = 15471
+ SPELL_SHADOWBOLT = 17228,
+ SPELL_CURSEOFTONGUES = 15470,
+ SPELL_CURSEOFWEAKNESS = 17227,
+ SPELL_DEMONARMOR = 11735,
+ SPELL_ENVELOPINGWEB = 15471
};
-class boss_anubshiah : public CreatureScript
+enum Events
{
-public:
- boss_anubshiah() : CreatureScript("boss_anubshiah") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_anubshiahAI(creature);
- }
-
- struct boss_anubshiahAI : public ScriptedAI
- {
- boss_anubshiahAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 ShadowBolt_Timer;
- uint32 CurseOfTongues_Timer;
- uint32 CurseOfWeakness_Timer;
- uint32 DemonArmor_Timer;
- uint32 EnvelopingWeb_Timer;
-
- void Reset() override
- {
- ShadowBolt_Timer = 7000;
- CurseOfTongues_Timer = 24000;
- CurseOfWeakness_Timer = 12000;
- DemonArmor_Timer = 3000;
- EnvelopingWeb_Timer = 16000;
- }
+ EVENT_SHADOWBOLT = 1,
+ EVENT_CURSE_OF_TONGUES = 2,
+ EVENT_CURSE_OF_WEAKNESS = 3,
+ EVENT_DEMON_ARMOR = 4,
+ EVENT_ENVELOPING_WEB = 5
+};
- void EnterCombat(Unit* /*who*/) override { }
+class boss_anubshiah : public CreatureScript
+{
+ public:
+ boss_anubshiah() : CreatureScript("boss_anubshiah") { }
- void UpdateAI(uint32 diff) override
+ struct boss_anubshiahAI : public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //ShadowBolt_Timer
- if (ShadowBolt_Timer <= diff)
- {
- DoCastVictim(SPELL_SHADOWBOLT);
- ShadowBolt_Timer = 7000;
- } else ShadowBolt_Timer -= diff;
-
- //CurseOfTongues_Timer
- if (CurseOfTongues_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_CURSEOFTONGUES);
- CurseOfTongues_Timer = 18000;
- } else CurseOfTongues_Timer -= diff;
+ boss_anubshiahAI(Creature* creature) : ScriptedAI(creature) { }
- //CurseOfWeakness_Timer
- if (CurseOfWeakness_Timer <= diff)
+ void Reset() override
{
- DoCastVictim(SPELL_CURSEOFWEAKNESS);
- CurseOfWeakness_Timer = 45000;
- } else CurseOfWeakness_Timer -= diff;
+ _events.Reset();
+ }
- //DemonArmor_Timer
- if (DemonArmor_Timer <= diff)
+ void EnterCombat(Unit* /*who*/) override
{
- DoCast(me, SPELL_DEMONARMOR);
- DemonArmor_Timer = 300000;
- } else DemonArmor_Timer -= diff;
-
- //EnvelopingWeb_Timer
- if (EnvelopingWeb_Timer <= diff)
+ _events.ScheduleEvent(EVENT_SHADOWBOLT, 7000);
+ _events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, 24000);
+ _events.ScheduleEvent(EVENT_CURSE_OF_WEAKNESS, 12000);
+ _events.ScheduleEvent(EVENT_DEMON_ARMOR, 3000);
+ _events.ScheduleEvent(EVENT_ENVELOPING_WEB, 16000);
+ }
+
+ void UpdateAI(uint32 diff) override
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_ENVELOPINGWEB);
- EnvelopingWeb_Timer = 12000;
- } else EnvelopingWeb_Timer -= diff;
-
- DoMeleeAttackIfReady();
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHADOWBOLT:
+ DoCast(me, SPELL_SHADOWBOLT);
+ _events.ScheduleEvent(EVENT_SHADOWBOLT, 7000);
+ break;
+ case EVENT_CURSE_OF_TONGUES:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(target, SPELL_CURSEOFTONGUES);
+ _events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, 18000);
+ break;
+ case EVENT_CURSE_OF_WEAKNESS:
+ DoCastVictim(SPELL_CURSEOFWEAKNESS);
+ _events.ScheduleEvent(EVENT_CURSE_OF_WEAKNESS, 45000);
+ break;
+ case EVENT_DEMON_ARMOR:
+ DoCast(me, SPELL_DEMONARMOR);
+ _events.ScheduleEvent(EVENT_DEMON_ARMOR, 300000);
+ break;
+ case EVENT_ENVELOPING_WEB:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(target, SPELL_ENVELOPINGWEB);
+ _events.ScheduleEvent(EVENT_ENVELOPING_WEB, 12000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_anubshiahAI(creature);
}
- };
};
void AddSC_boss_anubshiah()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
index fffdf9c7514..cec29bcd4d1 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -32,89 +31,89 @@ enum Spells
SPELL_AVATAROFFLAME = 15636
};
-class boss_emperor_dagran_thaurissan : public CreatureScript
+enum Events
{
-public:
- boss_emperor_dagran_thaurissan() : CreatureScript("boss_emperor_dagran_thaurissan") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_draganthaurissanAI>(creature);
- }
-
- struct boss_draganthaurissanAI : public ScriptedAI
- {
- boss_draganthaurissanAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = me->GetInstanceScript();
- }
-
- InstanceScript* instance;
- uint32 HandOfThaurissan_Timer;
- uint32 AvatarOfFlame_Timer;
- //uint32 Counter;
+ EVENT_HANDOFTHAURISSAN = 1,
+ EVENT_AVATAROFFLAME = 2
+};
- void Reset() override
- {
- HandOfThaurissan_Timer = 4000;
- AvatarOfFlame_Timer = 25000;
- //Counter= 0;
- }
+class boss_emperor_dagran_thaurissan : public CreatureScript
+{
+ public:
+ boss_emperor_dagran_thaurissan() : CreatureScript("boss_emperor_dagran_thaurissan") { }
- void EnterCombat(Unit* /*who*/) override
+ struct boss_draganthaurissanAI : public ScriptedAI
{
- Talk(SAY_AGGRO);
- me->CallForHelp(VISIBLE_RANGE);
- }
+ boss_draganthaurissanAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = me->GetInstanceScript();
+ }
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_SLAY);
- }
+ void Reset() override
+ {
+ _events.Reset();
+ }
- void JustDied(Unit* /*killer*/) override
- {
- if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOIRA)))
+ void EnterCombat(Unit* /*who*/) override
{
- Moira->AI()->EnterEvadeMode();
- Moira->setFaction(35);
+ Talk(SAY_AGGRO);
+ me->CallForHelp(VISIBLE_RANGE);
+ _events.ScheduleEvent(EVENT_HANDOFTHAURISSAN, 4000);
+ _events.ScheduleEvent(EVENT_AVATAROFFLAME, 25000);
}
- }
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void KilledUnit(Unit* who) override
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- if (HandOfThaurissan_Timer <= diff)
+ void JustDied(Unit* /*killer*/) override
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_HANDOFTHAURISSAN);
-
- //3 Hands of Thaurissan will be cast
- //if (Counter < 3)
- //{
- // HandOfThaurissan_Timer = 1000;
- // ++Counter;
- //}
- //else
- //{
- HandOfThaurissan_Timer = 5000;
- //Counter = 0;
- //}
- } else HandOfThaurissan_Timer -= diff;
-
- //AvatarOfFlame_Timer
- if (AvatarOfFlame_Timer <= diff)
+ if (Creature* moira = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MOIRA)))
+ {
+ moira->AI()->EnterEvadeMode();
+ moira->setFaction(35);
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
{
- DoCastVictim(SPELL_AVATAROFFLAME);
- AvatarOfFlame_Timer = 18000;
- } else AvatarOfFlame_Timer -= diff;
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_HANDOFTHAURISSAN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_HANDOFTHAURISSAN);
+ _events.ScheduleEvent(EVENT_HANDOFTHAURISSAN, 5000);
+ break;
+ case EVENT_AVATAROFFLAME:
+ DoCastVictim(SPELL_AVATAROFFLAME);
+ _events.ScheduleEvent(EVENT_AVATAROFFLAME, 18000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_draganthaurissanAI>(creature);
}
- };
};
void AddSC_boss_draganthaurissan()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp
index 34ce2276a54..d5b8d1deadd 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -26,101 +25,113 @@ enum Spells
SPELL_CLEAVE = 20691
};
-class boss_general_angerforge : public CreatureScript
+enum Events
{
-public:
- boss_general_angerforge() : CreatureScript("boss_general_angerforge") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_general_angerforgeAI(creature);
- }
-
- struct boss_general_angerforgeAI : public ScriptedAI
- {
- boss_general_angerforgeAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 MightyBlow_Timer;
- uint32 HamString_Timer;
- uint32 Cleave_Timer;
- uint32 Adds_Timer;
- bool Medics;
-
- void Reset() override
- {
- MightyBlow_Timer = 8000;
- HamString_Timer = 12000;
- Cleave_Timer = 16000;
- Adds_Timer = 0;
- Medics = false;
- }
-
- void EnterCombat(Unit* /*who*/) override { }
+ EVENT_MIGHTYBLOW = 1,
+ EVENT_HAMSTRING = 2,
+ EVENT_CLEAVE = 3,
+ EVENT_MEDIC = 4,
+ EVENT_ADDS = 5
+};
- void SummonAdds(Unit* victim)
- {
- if (Creature* SummonedAdd = DoSpawnCreature(8901, float(irand(-14, 14)), float(irand(-14, 14)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000))
- SummonedAdd->AI()->AttackStart(victim);
- }
+enum Phases
+{
+ PHASE_ONE = 1,
+ PHASE_TWO = 2
+};
- void SummonMedics(Unit* victim)
- {
- if (Creature* SummonedMedic = DoSpawnCreature(8894, float(irand(-9, 9)), float(irand(-9, 9)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000))
- SummonedMedic->AI()->AttackStart(victim);
- }
+class boss_general_angerforge : public CreatureScript
+{
+ public:
+ boss_general_angerforge() : CreatureScript("boss_general_angerforge") { }
- void UpdateAI(uint32 diff) override
+ struct boss_general_angerforgeAI : public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ boss_general_angerforgeAI(Creature* creature) : ScriptedAI(creature) { }
- //MightyBlow_Timer
- if (MightyBlow_Timer <= diff)
+ void Reset() override
{
- DoCastVictim(SPELL_MIGHTYBLOW);
- MightyBlow_Timer = 18000;
- } else MightyBlow_Timer -= diff;
+ _events.Reset();
+ }
- //HamString_Timer
- if (HamString_Timer <= diff)
+ void EnterCombat(Unit* /*who*/) override
{
- DoCastVictim(SPELL_HAMSTRING);
- HamString_Timer = 15000;
- } else HamString_Timer -= diff;
+ _events.SetPhase(PHASE_ONE);
+ _events.ScheduleEvent(EVENT_MIGHTYBLOW, 8000);
+ _events.ScheduleEvent(EVENT_HAMSTRING, 12000);
+ _events.ScheduleEvent(EVENT_CLEAVE, 16000);
+ }
- //Cleave_Timer
- if (Cleave_Timer <= diff)
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
- DoCastVictim(SPELL_CLEAVE);
- Cleave_Timer = 9000;
- } else Cleave_Timer -= diff;
+ if (me->HealthBelowPctDamaged(20, damage) && _events.IsInPhase(PHASE_ONE))
+ {
+ _events.SetPhase(PHASE_TWO);
+ _events.ScheduleEvent(EVENT_MEDIC, 0, 0, PHASE_TWO);
+ _events.ScheduleEvent(EVENT_ADDS, 0, 0, PHASE_TWO);
+ }
+ }
- //Adds_Timer
- if (HealthBelowPct(21))
+ void SummonAdd(Unit* victim)
{
- if (Adds_Timer <= diff)
- {
- // summon 3 Adds every 25s
- SummonAdds(me->GetVictim());
- SummonAdds(me->GetVictim());
- SummonAdds(me->GetVictim());
+ if (Creature* SummonedAdd = DoSpawnCreature(8901, float(irand(-14, 14)), float(irand(-14, 14)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000))
+ SummonedAdd->AI()->AttackStart(victim);
+ }
- Adds_Timer = 25000;
- } else Adds_Timer -= diff;
+ void SummonMedic(Unit* victim)
+ {
+ if (Creature* SummonedMedic = DoSpawnCreature(8894, float(irand(-9, 9)), float(irand(-9, 9)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000))
+ SummonedMedic->AI()->AttackStart(victim);
}
- //Summon Medics
- if (!Medics && HealthBelowPct(21))
+ void UpdateAI(uint32 diff) override
{
- SummonMedics(me->GetVictim());
- SummonMedics(me->GetVictim());
- Medics = true;
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MIGHTYBLOW:
+ DoCastVictim(SPELL_MIGHTYBLOW);
+ _events.ScheduleEvent(EVENT_MIGHTYBLOW, 18000);
+ break;
+ case EVENT_HAMSTRING:
+ DoCastVictim(SPELL_HAMSTRING);
+ _events.ScheduleEvent(EVENT_HAMSTRING, 15000);
+ break;
+ case EVENT_CLEAVE:
+ DoCastVictim(SPELL_CLEAVE);
+ _events.ScheduleEvent(EVENT_CLEAVE, 9000);
+ break;
+ case EVENT_MEDIC:
+ for (uint8 i = 0; i < 2; ++i)
+ SummonMedic(me->GetVictim());
+ break;
+ case EVENT_ADDS:
+ for (uint8 i = 0; i < 3; ++i)
+ SummonAdd(me->GetVictim());
+ _events.ScheduleEvent(EVENT_ADDS, 25000, 0, PHASE_TWO);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_general_angerforgeAI(creature);
}
- };
};
void AddSC_boss_general_angerforge()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
index b5998576f24..e9034e17d83 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -25,56 +24,67 @@ enum Spells
SPELL_MORTALSTRIKE = 24573
};
+enum Events
+{
+ EVENT_WHIRLWIND = 1,
+ EVENT_MORTALSTRIKE = 2
+};
+
class boss_gorosh_the_dervish : public CreatureScript
{
-public:
- boss_gorosh_the_dervish() : CreatureScript("boss_gorosh_the_dervish") { }
+ public:
+ boss_gorosh_the_dervish() : CreatureScript("boss_gorosh_the_dervish") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_gorosh_the_dervishAI(creature);
- }
+ struct boss_gorosh_the_dervishAI : public ScriptedAI
+ {
+ boss_gorosh_the_dervishAI(Creature* creature) : ScriptedAI(creature) { }
- struct boss_gorosh_the_dervishAI : public ScriptedAI
- {
- boss_gorosh_the_dervishAI(Creature* creature) : ScriptedAI(creature) { }
+ void Reset() override
+ {
+ _events.Reset();
+ }
- uint32 WhirlWind_Timer;
- uint32 MortalStrike_Timer;
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_WHIRLWIND, 12000);
+ _events.ScheduleEvent(EVENT_MORTALSTRIKE, 22000);
+ }
- void Reset() override
- {
- WhirlWind_Timer = 12000;
- MortalStrike_Timer = 22000;
- }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- void EnterCombat(Unit* /*who*/) override
- {
- }
+ _events.Update(diff);
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_WHIRLWIND:
+ DoCast(me, SPELL_WHIRLWIND);
+ _events.ScheduleEvent(EVENT_WHIRLWIND, 15000);
+ break;
+ case EVENT_MORTALSTRIKE:
+ DoCastVictim(SPELL_MORTALSTRIKE);
+ _events.ScheduleEvent(EVENT_MORTALSTRIKE, 15000);
+ break;
+ default:
+ break;
+ }
+ }
- //WhirlWind_Timer
- if (WhirlWind_Timer <= diff)
- {
- DoCast(me, SPELL_WHIRLWIND);
- WhirlWind_Timer = 15000;
- } else WhirlWind_Timer -= diff;
+ DoMeleeAttackIfReady();
+ }
- //MortalStrike_Timer
- if (MortalStrike_Timer <= diff)
- {
- DoCastVictim(SPELL_MORTALSTRIKE);
- MortalStrike_Timer = 15000;
- } else MortalStrike_Timer -= diff;
+ private:
+ EventMap _events;
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_gorosh_the_dervishAI(creature);
}
- };
};
void AddSC_boss_gorosh_the_dervish()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp
index c4277c2447e..f53fd0f65b3 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -26,59 +25,83 @@ enum Grizzle
EMOTE_FRENZY_KILL = 0
};
-class boss_grizzle : public CreatureScript
+enum Events
{
-public:
- boss_grizzle() : CreatureScript("boss_grizzle") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_grizzleAI(creature);
- }
+ EVENT_GROUNDTREMOR = 1,
+ EVENT_FRENZY = 2
+};
- struct boss_grizzleAI : public ScriptedAI
- {
- boss_grizzleAI(Creature* creature) : ScriptedAI(creature) { }
+enum Phases
+{
+ PHASE_ONE = 1,
+ PHASE_TWO = 2
+};
- uint32 GroundTremor_Timer;
- uint32 Frenzy_Timer;
+class boss_grizzle : public CreatureScript
+{
+ public:
+ boss_grizzle() : CreatureScript("boss_grizzle") { }
- void Reset() override
+ struct boss_grizzleAI : public ScriptedAI
{
- GroundTremor_Timer = 12000;
- Frenzy_Timer =0;
- }
+ boss_grizzleAI(Creature* creature) : ScriptedAI(creature) { }
- void EnterCombat(Unit* /*who*/) override { }
+ void Reset() override
+ {
+ _events.Reset();
+ }
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _events.SetPhase(PHASE_ONE);
+ _events.ScheduleEvent(EVENT_GROUNDTREMOR, 12000);
+ }
- //GroundTremor_Timer
- if (GroundTremor_Timer <= diff)
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
- DoCastVictim(SPELL_GROUNDTREMOR);
- GroundTremor_Timer = 8000;
- } else GroundTremor_Timer -= diff;
+ if (me->HealthBelowPctDamaged(50, damage) && _events.IsInPhase(PHASE_ONE))
+ {
+ _events.SetPhase(PHASE_TWO);
+ _events.ScheduleEvent(EVENT_FRENZY, 0, 0, PHASE_TWO);
+ }
+ }
- //Frenzy_Timer
- if (HealthBelowPct(51))
+ void UpdateAI(uint32 diff) override
{
- if (Frenzy_Timer <= diff)
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
{
- DoCast(me, SPELL_FRENZY);
- Talk(EMOTE_FRENZY_KILL);
+ switch (eventId)
+ {
+ case EVENT_GROUNDTREMOR:
+ DoCastVictim(SPELL_GROUNDTREMOR);
+ _events.ScheduleEvent(EVENT_GROUNDTREMOR, 8000);
+ break;
+ case EVENT_FRENZY:
+ DoCast(me, SPELL_FRENZY);
+ Talk(EMOTE_FRENZY_KILL);
+ _events.ScheduleEvent(EVENT_FRENZY, 15000, 0, PHASE_TWO);
+ break;
+ default:
+ break;
+ }
+ }
- Frenzy_Timer = 15000;
- } else Frenzy_Timer -= diff;
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_grizzleAI(creature);
}
- };
};
void AddSC_boss_grizzle()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp
index 6aa89aa491d..c41ddf9d98b 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -27,74 +26,81 @@ enum Spells
SPELL_SHADOWSHIELD = 22417
};
-class boss_high_interrogator_gerstahn : public CreatureScript
+enum Events
{
-public:
- boss_high_interrogator_gerstahn() : CreatureScript("boss_high_interrogator_gerstahn") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_high_interrogator_gerstahnAI(creature);
- }
-
- struct boss_high_interrogator_gerstahnAI : public ScriptedAI
- {
- boss_high_interrogator_gerstahnAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 ShadowWordPain_Timer;
- uint32 ManaBurn_Timer;
- uint32 PsychicScream_Timer;
- uint32 ShadowShield_Timer;
-
- void Reset() override
- {
- ShadowWordPain_Timer = 4000;
- ManaBurn_Timer = 14000;
- PsychicScream_Timer = 32000;
- ShadowShield_Timer = 8000;
- }
+ EVENT_SHADOW_WORD_PAIN = 1,
+ EVENT_MANABURN = 2,
+ EVENT_PSYCHIC_SCREAM = 3,
+ EVENT_SHADOWSHIELD = 4
+};
- void EnterCombat(Unit* /*who*/) override { }
+class boss_high_interrogator_gerstahn : public CreatureScript
+{
+ public:
+ boss_high_interrogator_gerstahn() : CreatureScript("boss_high_interrogator_gerstahn") { }
- void UpdateAI(uint32 diff) override
+ struct boss_high_interrogator_gerstahnAI : public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ boss_high_interrogator_gerstahnAI(Creature* creature) : ScriptedAI(creature) { }
- //ShadowWordPain_Timer
- if (ShadowWordPain_Timer <= diff)
+ void Reset() override
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_SHADOWWORDPAIN);
- ShadowWordPain_Timer = 7000;
- } else ShadowWordPain_Timer -= diff;
+ _events.Reset();
+ }
- //ManaBurn_Timer
- if (ManaBurn_Timer <= diff)
+ void EnterCombat(Unit* /*who*/) override
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_MANABURN);
- ManaBurn_Timer = 10000;
- } else ManaBurn_Timer -= diff;
+ _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 4000);
+ _events.ScheduleEvent(EVENT_MANABURN, 14000);
+ _events.ScheduleEvent(EVENT_PSYCHIC_SCREAM, 32000);
+ _events.ScheduleEvent(EVENT_SHADOWSHIELD, 8000);
+ }
- //PsychicScream_Timer
- if (PsychicScream_Timer <= diff)
+ void UpdateAI(uint32 diff) override
{
- DoCastVictim(SPELL_PSYCHICSCREAM);
- PsychicScream_Timer = 30000;
- } else PsychicScream_Timer -= diff;
+ if (!UpdateVictim())
+ return;
- //ShadowShield_Timer
- if (ShadowShield_Timer <= diff)
- {
- DoCast(me, SPELL_SHADOWSHIELD);
- ShadowShield_Timer = 25000;
- } else ShadowShield_Timer -= diff;
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHADOW_WORD_PAIN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_SHADOWWORDPAIN);
+ _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 7000);
+ break;
+ case EVENT_PSYCHIC_SCREAM:
+ DoCastVictim(SPELL_PSYCHICSCREAM);
+ _events.ScheduleEvent(EVENT_PSYCHIC_SCREAM, 30000);
+ break;
+ case EVENT_MANABURN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_MANABURN);
+ _events.ScheduleEvent(EVENT_MANABURN, 10000);
+ break;
+ case EVENT_SHADOWSHIELD:
+ DoCast(me, SPELL_SHADOWSHIELD);
+ _events.ScheduleEvent(EVENT_SHADOWSHIELD, 25000);
+ break;
+ default:
+ break;
+ }
+ }
- DoMeleeAttackIfReady();
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_high_interrogator_gerstahnAI(creature);
}
- };
};
void AddSC_boss_high_interrogator_gerstahn()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp
index 4cf968ad3b7..e6bbbaa73a9 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -18,75 +17,96 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "blackrock_depths.h"
enum Spells
{
- SPELL_FIERYBURST = 13900,
- SPELL_WARSTOMP = 24375
+ SPELL_FIERYBURST = 13900,
+ SPELL_WARSTOMP = 24375
};
-enum Misc
+enum Events
{
- DATA_THRONE_DOOR = 24 // not id or guid of doors but number of enum in blackrock_depths.h
+ EVENT_FIERY_BURST = 1,
+ EVENT_WARSTOMP = 2
};
-class boss_magmus : public CreatureScript
+enum Phases
{
-public:
- boss_magmus() : CreatureScript("boss_magmus") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_magmusAI(creature);
- }
-
- struct boss_magmusAI : public ScriptedAI
- {
- boss_magmusAI(Creature* creature) : ScriptedAI(creature) { }
+ PHASE_ONE = 1,
+ PHASE_TWO = 2
+};
- uint32 FieryBurst_Timer;
- uint32 WarStomp_Timer;
+class boss_magmus : public CreatureScript
+{
+ public:
+ boss_magmus() : CreatureScript("boss_magmus") { }
- void Reset() override
+ struct boss_magmusAI : public ScriptedAI
{
- FieryBurst_Timer = 5000;
- WarStomp_Timer =0;
- }
+ boss_magmusAI(Creature* creature) : ScriptedAI(creature) { }
- void EnterCombat(Unit* /*who*/) override { }
+ void Reset() override
+ {
+ _events.Reset();
+ }
- void UpdateAI(uint32 diff) override
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _events.SetPhase(PHASE_ONE);
+ _events.ScheduleEvent(EVENT_FIERY_BURST, 5000);
+ }
- //FieryBurst_Timer
- if (FieryBurst_Timer <= diff)
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
- DoCastVictim(SPELL_FIERYBURST);
- FieryBurst_Timer = 6000;
- } else FieryBurst_Timer -= diff;
+ if (me->HealthBelowPctDamaged(50, damage) && _events.IsInPhase(PHASE_ONE))
+ {
+ _events.SetPhase(PHASE_TWO);
+ _events.ScheduleEvent(EVENT_WARSTOMP, 0, 0, PHASE_TWO);
+ }
+ }
- //WarStomp_Timer
- if (HealthBelowPct(51))
+ void UpdateAI(uint32 diff) override
{
- if (WarStomp_Timer <= diff)
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
{
- DoCastVictim(SPELL_WARSTOMP);
- WarStomp_Timer = 8000;
- } else WarStomp_Timer -= diff;
+ switch (eventId)
+ {
+ case EVENT_FIERY_BURST:
+ DoCastVictim(SPELL_FIERYBURST);
+ _events.ScheduleEvent(EVENT_FIERY_BURST, 6000);
+ break;
+ case EVENT_WARSTOMP:
+ DoCastVictim(SPELL_WARSTOMP);
+ _events.ScheduleEvent(EVENT_WARSTOMP, 8000, 0, PHASE_TWO);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
- }
- // When he die open door to last chamber
- void JustDied(Unit* killer) override
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (InstanceScript* instance = me->GetInstanceScript())
+ instance->HandleGameObject(instance->GetData64(DATA_THRONE_DOOR), true);
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (InstanceScript* instance = killer->GetInstanceScript())
- instance->HandleGameObject(instance->GetData64(DATA_THRONE_DOOR), true);
+ return new boss_magmusAI(creature);
}
- };
};
void AddSC_boss_magmus()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp
index 98f5f75ae3f..8342bef682b 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -29,63 +28,73 @@ enum Spells
SPELL_SMITE = 10934
};
-class boss_moira_bronzebeard : public CreatureScript
+enum Events
{
-public:
- boss_moira_bronzebeard() : CreatureScript("boss_moira_bronzebeard") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_moira_bronzebeardAI(creature);
- }
-
- struct boss_moira_bronzebeardAI : public ScriptedAI
- {
- boss_moira_bronzebeardAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 Heal_Timer;
- uint32 MindBlast_Timer;
- uint32 ShadowWordPain_Timer;
- uint32 Smite_Timer;
-
- void Reset() override
- {
- Heal_Timer = 12000; //These times are probably wrong
- MindBlast_Timer = 16000;
- ShadowWordPain_Timer = 2000;
- Smite_Timer = 8000;
- }
+ EVENT_MINDBLAST = 1,
+ EVENT_SHADOW_WORD_PAIN = 2,
+ EVENT_SMITE = 3,
+ EVENT_HEAL = 4 // not used atm
+};
- void EnterCombat(Unit* /*who*/) override { }
+class boss_moira_bronzebeard : public CreatureScript
+{
+ public:
+ boss_moira_bronzebeard() : CreatureScript("boss_moira_bronzebeard") { }
- void UpdateAI(uint32 diff) override
+ struct boss_moira_bronzebeardAI : public ScriptedAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ boss_moira_bronzebeardAI(Creature* creature) : ScriptedAI(creature) { }
- //MindBlast_Timer
- if (MindBlast_Timer <= diff)
+ void Reset() override
{
- DoCastVictim(SPELL_MINDBLAST);
- MindBlast_Timer = 14000;
- } else MindBlast_Timer -= diff;
+ _events.Reset();
+ }
- //ShadowWordPain_Timer
- if (ShadowWordPain_Timer <= diff)
+ void EnterCombat(Unit* /*who*/) override
{
- DoCastVictim(SPELL_SHADOWWORDPAIN);
- ShadowWordPain_Timer = 18000;
- } else ShadowWordPain_Timer -= diff;
+ //_events.ScheduleEvent(EVENT_HEAL, 12000); // not used atm // These times are probably wrong
+ _events.ScheduleEvent(EVENT_MINDBLAST, 16000);
+ _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 2000);
+ _events.ScheduleEvent(EVENT_SMITE, 8000);
+ }
- //Smite_Timer
- if (Smite_Timer <= diff)
+ void UpdateAI(uint32 diff) override
{
- DoCastVictim(SPELL_SMITE);
- Smite_Timer = 10000;
- } else Smite_Timer -= diff;
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MINDBLAST:
+ DoCastVictim(SPELL_MINDBLAST);
+ _events.ScheduleEvent(EVENT_MINDBLAST, 14000);
+ break;
+ case EVENT_SHADOW_WORD_PAIN:
+ DoCastVictim(SPELL_SHADOWWORDPAIN);
+ _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 18000);
+ break;
+ case EVENT_SMITE:
+ DoCastVictim(SPELL_SMITE);
+ _events.ScheduleEvent(EVENT_SMITE, 10000);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new boss_moira_bronzebeardAI(creature);
}
- };
};
void AddSC_boss_moira_bronzebeard()
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
index cbcafa32a89..83464c12230 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
@@ -24,18 +24,24 @@
enum Spells
{
- SPELL_SMELT_DARK_IRON = 14891,
- SPELL_LEARN_SMELT = 14894,
+ SPELL_SMELT_DARK_IRON = 14891,
+ SPELL_LEARN_SMELT = 14894,
};
enum Quests
{
- QUEST_SPECTRAL_CHALICE = 4083
+ QUEST_SPECTRAL_CHALICE = 4083
};
enum Misc
{
- DATA_SKILLPOINT_MIN = 230
+ DATA_SKILLPOINT_MIN = 230
+};
+
+enum Phases
+{
+ PHASE_ONE = 1,
+ PHASE_TWO = 2
};
#define GOSSIP_ITEM_TEACH_1 "Teach me the art of smelting dark iron"
@@ -99,149 +105,151 @@ enum DoomrelSpells
SPELL_SUMMON_VOIDWALKERS = 15092
};
+enum DoomrelEvents
+{
+ EVENT_SHADOW_BOLT_VOLLEY = 1,
+ EVENT_IMMOLATE = 2,
+ EVENT_CURSE_OF_WEAKNESS = 3,
+ EVENT_DEMONARMOR = 4,
+ EVENT_SUMMON_VOIDWALKERS = 5
+};
+
#define GOSSIP_ITEM_CHALLENGE "Your bondage is at an end, Doom'rel. I challenge you!"
#define GOSSIP_SELECT_DOOMREL "[PH] Continue..."
class boss_doomrel : public CreatureScript
{
-public:
- boss_doomrel() : CreatureScript("boss_doomrel") { }
+ public:
+ boss_doomrel() : CreatureScript("boss_doomrel") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_DOOMREL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(2605, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->CLOSE_GOSSIP_MENU();
- //start event here
- creature->setFaction(FACTION_HOSTILE);
- creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- creature->AI()->AttackStart(player);
- InstanceScript* instance = creature->GetInstanceScript();
- if (instance)
- instance->SetData64(DATA_EVENSTARTER, player->GetGUID());
- break;
+ player->PlayerTalkClass->ClearMenus();
+ switch (action)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_DOOMREL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->SEND_GOSSIP_MENU(2605, creature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ player->CLOSE_GOSSIP_MENU();
+ //start event here
+ creature->setFaction(FACTION_HOSTILE);
+ creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ creature->AI()->AttackStart(player);
+ InstanceScript* instance = creature->GetInstanceScript();
+ if (instance)
+ instance->SetData64(DATA_EVENSTARTER, player->GetGUID());
+ break;
+ }
+ return true;
}
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHALLENGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(2601, creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_doomrelAI>(creature);
- }
-
- struct boss_doomrelAI : public ScriptedAI
- {
- boss_doomrelAI(Creature* creature) : ScriptedAI(creature)
+ bool OnGossipHello(Player* player, Creature* creature) override
{
- instance = creature->GetInstanceScript();
- }
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_CHALLENGE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ player->SEND_GOSSIP_MENU(2601, creature->GetGUID());
- InstanceScript* instance;
- uint32 ShadowVolley_Timer;
- uint32 Immolate_Timer;
- uint32 CurseOfWeakness_Timer;
- uint32 DemonArmor_Timer;
- bool Voidwalkers;
+ return true;
+ }
- void Reset() override
+ struct boss_doomrelAI : public ScriptedAI
{
- ShadowVolley_Timer = 10000;
- Immolate_Timer = 18000;
- CurseOfWeakness_Timer = 5000;
- DemonArmor_Timer = 16000;
- Voidwalkers = false;
+ boss_doomrelAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- me->setFaction(FACTION_FRIEND);
+ void Reset() override
+ {
+ _voidwalkers = false;
- // was set before event start, so set again
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->setFaction(FACTION_FRIEND);
- if (instance->GetData(DATA_GHOSTKILL) >= 7)
- me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
- else
- me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
+ // was set before event start, so set again
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- void EnterCombat(Unit* /*who*/) override
- {
- }
-
- void EnterEvadeMode() override
- {
- me->RemoveAllAuras();
- me->DeleteThreatList();
- me->CombatStop(true);
- me->LoadCreaturesAddon();
- if (me->IsAlive())
- me->GetMotionMaster()->MoveTargetedHome();
- me->SetLootRecipient(NULL);
- instance->SetData64(DATA_EVENSTARTER, 0);
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- instance->SetData(DATA_GHOSTKILL, 1);
- }
+ if (_instance->GetData(DATA_GHOSTKILL) >= 7)
+ me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
+ else
+ me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ void EnterCombat(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_SHADOW_BOLT_VOLLEY, 10000);
+ _events.ScheduleEvent(EVENT_IMMOLATE, 18000);
+ _events.ScheduleEvent(EVENT_CURSE_OF_WEAKNESS, 5000);
+ _events.ScheduleEvent(EVENT_DEMONARMOR, 16000);
+ }
- //ShadowVolley_Timer
- if (ShadowVolley_Timer <= diff)
+ void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
{
- DoCastVictim(SPELL_SHADOWBOLTVOLLEY);
- ShadowVolley_Timer = 12000;
- } else ShadowVolley_Timer -= diff;
+ if (!_voidwalkers && !HealthAbovePct(50))
+ {
+ DoCastVictim(SPELL_SUMMON_VOIDWALKERS, true);
+ _voidwalkers = true;
+ }
+ }
- //Immolate_Timer
- if (Immolate_Timer <= diff)
+ void EnterEvadeMode() override
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_IMMOLATE);
+ ScriptedAI::EnterEvadeMode();
- Immolate_Timer = 25000;
- } else Immolate_Timer -= diff;
+ _instance->SetData64(DATA_EVENSTARTER, 0);
+ }
- //CurseOfWeakness_Timer
- if (CurseOfWeakness_Timer <= diff)
+ void JustDied(Unit* /*killer*/) override
{
- DoCastVictim(SPELL_CURSEOFWEAKNESS);
- CurseOfWeakness_Timer = 45000;
- } else CurseOfWeakness_Timer -= diff;
+ _instance->SetData(DATA_GHOSTKILL, 1);
+ }
- //DemonArmor_Timer
- if (DemonArmor_Timer <= diff)
+ void UpdateAI(uint32 diff) override
{
- DoCast(me, SPELL_DEMONARMOR);
- DemonArmor_Timer = 300000;
- } else DemonArmor_Timer -= diff;
+ if (!UpdateVictim())
+ return;
- //Summon Voidwalkers
- if (!Voidwalkers && HealthBelowPct(51))
- {
- DoCastVictim(SPELL_SUMMON_VOIDWALKERS, true);
- Voidwalkers = true;
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHADOW_BOLT_VOLLEY:
+ DoCastVictim(SPELL_SHADOWBOLTVOLLEY);
+ _events.ScheduleEvent(EVENT_SHADOW_BOLT_VOLLEY, 12000);
+ break;
+ case EVENT_IMMOLATE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_IMMOLATE);
+ _events.ScheduleEvent(EVENT_IMMOLATE, 25000);
+ break;
+ case EVENT_CURSE_OF_WEAKNESS:
+ DoCastVictim(SPELL_CURSEOFWEAKNESS);
+ _events.ScheduleEvent(EVENT_CURSE_OF_WEAKNESS, 45000);
+ break;
+ case EVENT_DEMONARMOR:
+ DoCast(me, SPELL_DEMONARMOR);
+ _events.ScheduleEvent(EVENT_DEMONARMOR, 300000);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ bool _voidwalkers;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_doomrelAI>(creature);
}
- };
};
void AddSC_boss_tomb_of_seven()
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
index dbd844aa34c..503166e0b12 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
@@ -187,7 +187,7 @@ class instance_culling_of_stratholme : public InstanceMapScript
// Summon Chromie and global whisper
if (Creature* chromie = instance->SummonCreature(NPC_CHROMIE_2, ChromieSummonPos))
if (!instance->GetPlayers().isEmpty())
- sCreatureTextMgr->SendChat(chromie, SAY_CRATES_COMPLETED, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
+ chromie->AI()->TalkToMap(SAY_CRATES_COMPLETED);
}
DoUpdateWorldState(WORLDSTATE_CRATES_REVEALED, _crateCount);
break;
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
index 562105c0866..8a62453d7c1 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h
@@ -40,7 +40,7 @@ enum SpellIds
enum MiscData
{
- DESPAWN_TIME = 300000,
+ DESPAWN_TIME = 1200000,
DISPLAYID_DESTROYED_FLOOR = 9060
};
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 ccdd92ae4ba..4303026ba64 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -1100,7 +1100,7 @@ class npc_jaina_or_sylvanas_escape_hor : public CreatureScript
Talk(SAY_JAINA_ESCAPE_9);
if (Transport* gunship = ObjectAccessor::GetTransport(*me, _instance->GetData64(DATA_GUNSHIP)))
gunship->EnableMovement(true);
- _instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, DONE);
+ _instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, DONE);
break;
case EVENT_ESCAPE_17:
if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
@@ -1139,7 +1139,7 @@ class npc_the_lich_king_escape_hor : public CreatureScript
struct npc_the_lich_king_escape_horAI : public ScriptedAI
{
- npc_the_lich_king_escape_horAI(Creature* creature) : ScriptedAI(creature)
+ npc_the_lich_king_escape_horAI(Creature* creature) : ScriptedAI(creature)
{
_instance = me->GetInstanceScript();
_instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, NOT_STARTED);
@@ -1248,12 +1248,12 @@ class npc_the_lich_king_escape_hor : public CreatureScript
_events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 66000);
_events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 14000);
Talk(SAY_LK_ESCAPE_ICEWALL_SUMMONED_4);
- break;
+ break;
default:
break;
}
}
-
+
void EnterEvadeMode() override
{
if (_despawn)
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 192249955cf..fefdfa633ea 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -664,7 +664,7 @@ public:
Talk(SAY_BUFF_SPARK);
}
else if (spell->Id == SPELL_MALYGOS_BERSERK)
- sCreatureTextMgr->SendChat(me, EMOTE_HIT_BERSERKER_TIMER, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
+ TalkToMap(EMOTE_HIT_BERSERKER_TIMER);
}
void MoveInLineOfSight(Unit* who) override
@@ -1113,8 +1113,7 @@ public:
npc_power_sparkAI(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
- // Talk range was not enough for this encounter
- sCreatureTextMgr->SendChat(me, EMOTE_POWER_SPARK_SUMMONED, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
+ TalkToMap(EMOTE_POWER_SPARK_SUMMONED);
MoveToMalygos();
}
diff --git a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
index 116beb3d081..cfcc05a625c 100644
--- a/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/zone_shadowmoon_valley.cpp
@@ -1813,7 +1813,6 @@ public:
enum ZuluhedChains
{
- QUEST_ZULUHED = 10866,
NPC_KARYNAKU = 22112,
};
@@ -1828,9 +1827,9 @@ class spell_unlocking_zuluheds_chains : public SpellScriptLoader
void HandleAfterHit()
{
- if (GetCaster()->GetTypeId() == TYPEID_PLAYER)
- if (Creature* karynaku = GetCaster()->FindNearestCreature(NPC_KARYNAKU, 15.0f))
- GetCaster()->ToPlayer()->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
+ if (Player* caster = GetCaster()->ToPlayer())
+ if (Creature* karynaku = caster->FindNearestCreature(NPC_KARYNAKU, 15.0f))
+ caster->KilledMonsterCredit(NPC_KARYNAKU, karynaku->GetGUID());
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 6a6ee144aac..5ae0e1601c5 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -322,13 +322,14 @@ class spell_dk_blood_gorged : public SpellScriptLoader
class CorpseExplosionCheck
{
public:
- explicit CorpseExplosionCheck(uint64 casterGUID) : _casterGUID(casterGUID) { }
+ explicit CorpseExplosionCheck(uint64 casterGUID, bool allowGhoul) : _casterGUID(casterGUID),
+ _allowGhoul(allowGhoul) { }
bool operator()(WorldObject* obj) const
{
if (Unit* target = obj->ToUnit())
{
- if ((target->isDead() || (target->GetEntry() == NPC_DK_GHOUL && target->GetOwnerGUID() == _casterGUID))
+ if ((target->isDead() || (_allowGhoul && target->GetEntry() == NPC_DK_GHOUL && target->GetOwnerGUID() == _casterGUID))
&& !(target->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)
&& target->GetDisplayId() == target->GetNativeDisplayId())
return false;
@@ -339,6 +340,7 @@ public:
private:
uint64 _casterGUID;
+ bool _allowGhoul;
};
// 49158 - Corpse Explosion (51325, 51326, 51327, 51328)
@@ -369,7 +371,7 @@ class spell_dk_corpse_explosion : public SpellScriptLoader
void CheckTarget(WorldObject*& target)
{
- if (CorpseExplosionCheck(GetCaster()->GetGUID())(target))
+ if (CorpseExplosionCheck(GetCaster()->GetGUID(), true)(target))
target = NULL;
_target = target;
@@ -380,7 +382,7 @@ class spell_dk_corpse_explosion : public SpellScriptLoader
WorldObject* target = _target;
if (!target)
{
- targets.remove_if(CorpseExplosionCheck(GetCaster()->GetGUID()));
+ targets.remove_if(CorpseExplosionCheck(GetCaster()->GetGUID(), false));
if (targets.empty())
{
FinishCast(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index bf4f1b77a19..447cb645e76 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -866,8 +866,8 @@ class spell_pal_improved_aura : public SpellScriptLoader
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
- if (!target->GetOwnedAura(_spellId))
- target->CastSpell(target, _spellId, true);
+ GetTarget()->RemoveOwnedAura(_spellId, GetCasterGUID()); // need to remove to reapply spellmods
+ target->CastSpell(target, _spellId, true);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index bb7da1b7042..c32edff09bc 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -56,6 +56,7 @@ EndContentData */
#include "CellImpl.h"
#include "SpellAuras.h"
#include "Pet.h"
+#include "CreatureTextMgr.h"
/*########
# npc_air_force_bots
@@ -2353,6 +2354,60 @@ public:
};
};
+class npc_imp_in_a_ball : public CreatureScript
+{
+private:
+ enum
+ {
+ SAY_RANDOM,
+
+ EVENT_TALK = 1,
+ };
+
+public:
+ npc_imp_in_a_ball() : CreatureScript("npc_imp_in_a_ball") { }
+
+ struct npc_imp_in_a_ballAI : public ScriptedAI
+ {
+ npc_imp_in_a_ballAI(Creature* creature) : ScriptedAI(creature)
+ {
+ summonerGUID = 0;
+ }
+
+ void IsSummonedBy(Unit* summoner) override
+ {
+ if (summoner->GetTypeId() == TYPEID_PLAYER)
+ {
+ summonerGUID = summoner->GetGUID();
+ events.ScheduleEvent(EVENT_TALK, 3000);
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_TALK)
+ {
+ if (Player* owner = ObjectAccessor::GetPlayer(*me, summonerGUID))
+ {
+ sCreatureTextMgr->SendChat(me, SAY_RANDOM, owner,
+ owner->GetGroup() ? CHAT_MSG_MONSTER_PARTY : CHAT_MSG_MONSTER_WHISPER, LANG_ADDON, TEXT_RANGE_NORMAL);
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ uint64 summonerGUID;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_imp_in_a_ballAI(creature);
+ }
+};
+
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -2375,4 +2430,5 @@ void AddSC_npcs_special()
new npc_experience();
new npc_firework();
new npc_spring_rabbit();
+ new npc_imp_in_a_ball();
}
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
index 3665a388854..9c56c75bf71 100644
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -99,7 +99,7 @@ class DatabaseWorkerPool
(_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC]));
else
TC_LOG_ERROR("sql.driver", "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile "
- "for specific errors.", GetDatabaseName());
+ "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", GetDatabaseName());
return res;
}
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp
index 3b6bd3d2cc8..81825c9055b 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.cpp
+++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp
@@ -45,7 +45,7 @@ inline LPTSTR ErrorMessage(DWORD dw)
sprintf(msgBuf, "Unknown error: %u", dw);
return msgBuf;
}
-
+
}
//============================== Global Variables =============================
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h
index f6d6b7f4b9e..e1cc3050929 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.h
+++ b/src/server/shared/Debugging/WheatyExceptionReport.h
@@ -83,7 +83,7 @@ struct SymbolPair
bool operator<(const SymbolPair& other) const
{
- return _offset < other._offset ||
+ return _offset < other._offset ||
(_offset == other._offset && _type < other._type);
}
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 9f766a72d19..11e835566e9 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -382,18 +382,18 @@ class ByteBuffer
return *this;
}
- uint8 * contents()
- {
+ uint8 * contents()
+ {
if (_storage.empty())
throw ByteBufferException();
- return &_storage[0];
+ return &_storage[0];
}
- const uint8 *contents() const
- {
+ const uint8 *contents() const
+ {
if (_storage.empty())
throw ByteBufferException();
- return &_storage[0];
+ return &_storage[0];
}
size_t size() const { return _storage.size(); }
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index b086a28134c..d6ead607c55 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -26,6 +26,7 @@
#include <string>
#include <vector>
#include <list>
+#include <map>
#include <ace/INET_Addr.h>
// Searcher for map of structs
@@ -565,4 +566,353 @@ bool CompareValues(ComparisionType type, T val1, T val2)
}
}
+class EventMap
+{
+ /**
+ * Internal storage type.
+ * Key: Time as uint32 when the event should occur.
+ * Value: The event data as uint32.
+ *
+ * Structure of event data:
+ * - Bit 0 - 15: Event Id.
+ * - Bit 16 - 23: Group
+ * - Bit 24 - 31: Phase
+ * - Pattern: 0xPPGGEEEE
+ */
+ typedef std::multimap<uint32, uint32> EventStore;
+
+ public:
+ EventMap() : _time(0), _phase(0), _lastEvent(0) { }
+
+ /**
+ * @name Reset
+ * @brief Removes all scheduled events and resets time and phase.
+ */
+ void Reset()
+ {
+ _eventMap.clear();
+ _time = 0;
+ _phase = 0;
+ }
+
+ /**
+ * @name Update
+ * @brief Updates the timer of the event map.
+ * @param time Value to be added to time.
+ */
+ void Update(uint32 time)
+ {
+ _time += time;
+ }
+
+ /**
+ * @name GetTimer
+ * @return Current timer value.
+ */
+ uint32 GetTimer() const
+ {
+ return _time;
+ }
+
+ /**
+ * @name GetPhaseMask
+ * @return Active phases as mask.
+ */
+ uint8 GetPhaseMask() const
+ {
+ return _phase;
+ }
+
+ /**
+ * @name Empty
+ * @return True, if there are no events scheduled.
+ */
+ bool Empty() const
+ {
+ return _eventMap.empty();
+ }
+
+ /**
+ * @name SetPhase
+ * @brief Sets the phase of the map (absolute).
+ * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase.
+ */
+ void SetPhase(uint8 phase)
+ {
+ if (!phase)
+ _phase = 0;
+ else if (phase <= 8)
+ _phase = (1 << (phase - 1));
+ }
+
+ /**
+ * @name AddPhase
+ * @brief Activates the given phase (bitwise).
+ * @param phase Phase which should be activated. Values: 1 - 8
+ */
+ void AddPhase(uint8 phase)
+ {
+ if (phase && phase <= 8)
+ _phase |= (1 << (phase - 1));
+ }
+
+ /**
+ * @name RemovePhase
+ * @brief Deactivates the given phase (bitwise).
+ * @param phase Phase which should be deactivated. Values: 1 - 8.
+ */
+ void RemovePhase(uint8 phase)
+ {
+ if (phase && phase <= 8)
+ _phase &= ~(1 << (phase - 1));
+ }
+
+ /**
+ * @name ScheduleEvent
+ * @brief Creates new event entry in map.
+ * @param eventId The id of the new event.
+ * @param time The time in milliseconds until the event occurs.
+ * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
+ * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
+ */
+ void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
+ {
+ if (group && group <= 8)
+ eventId |= (1 << (group + 15));
+
+ if (phase && phase <= 8)
+ eventId |= (1 << (phase + 23));
+
+ _eventMap.insert(EventStore::value_type(_time + time, eventId));
+ }
+
+ /**
+ * @name RescheduleEvent
+ * @brief Cancels the given event and reschedules it.
+ * @param eventId The id of the event.
+ * @param time The time in milliseconds until the event occurs.
+ * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group.
+ * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases.
+ */
+ void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0)
+ {
+ CancelEvent(eventId);
+ ScheduleEvent(eventId, time, group, phase);
+ }
+
+ /**
+ * @name RepeatEvent
+ * @brief Repeats the mostly recently executed event.
+ * @param time Time until the event occurs.
+ */
+ void Repeat(uint32 time)
+ {
+ _eventMap.insert(EventStore::value_type(_time + time, _lastEvent));
+ }
+
+ /**
+ * @name RepeatEvent
+ * @brief Repeats the mostly recently executed event.
+ * @param time Time until the event occurs. Equivalent to Repeat(urand(minTime, maxTime).
+ */
+ void Repeat(uint32 minTime, uint32 maxTime)
+ {
+ Repeat(urand(minTime, maxTime));
+ }
+
+ /**
+ * @name ExecuteEvent
+ * @brief Returns the next event to execute and removes it from map.
+ * @return Id of the event to execute.
+ */
+ uint32 ExecuteEvent()
+ {
+ while (!Empty())
+ {
+ EventStore::iterator itr = _eventMap.begin();
+
+ if (itr->first > _time)
+ return 0;
+ else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase))
+ _eventMap.erase(itr);
+ else
+ {
+ uint32 eventId = (itr->second & 0x0000FFFF);
+ _lastEvent = itr->second; // include phase/group
+ _eventMap.erase(itr);
+ return eventId;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * @name DelayEvents
+ * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0.
+ * @param delay Amount of delay.
+ */
+ void DelayEvents(uint32 delay)
+ {
+ _time = delay < _time ? _time - delay : 0;
+ }
+
+ /**
+ * @name DelayEvents
+ * @brief Delay all events of the same group.
+ * @param delay Amount of delay.
+ * @param group Group of the events.
+ */
+ void DelayEvents(uint32 delay, uint32 group)
+ {
+ if (!group || group > 8 || Empty())
+ return;
+
+ EventStore delayed;
+
+ for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
+ {
+ if (itr->second & (1 << (group + 15)))
+ {
+ delayed.insert(EventStore::value_type(itr->first + delay, itr->second));
+ _eventMap.erase(itr++);
+ }
+ else
+ ++itr;
+ }
+
+ _eventMap.insert(delayed.begin(), delayed.end());
+ }
+
+ /**
+ * @name CancelEvent
+ * @brief Cancels all events of the specified id.
+ * @param eventId Event id to cancel.
+ */
+ void CancelEvent(uint32 eventId)
+ {
+ if (Empty())
+ return;
+
+ for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
+ {
+ if (eventId == (itr->second & 0x0000FFFF))
+ _eventMap.erase(itr++);
+ else
+ ++itr;
+ }
+ }
+
+ /**
+ * @name CancelEventGroup
+ * @brief Cancel events belonging to specified group.
+ * @param group Group to cancel.
+ */
+ void CancelEventGroup(uint32 group)
+ {
+ if (!group || group > 8 || Empty())
+ return;
+
+ for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
+ {
+ if (itr->second & (1 << (group + 15)))
+ _eventMap.erase(itr++);
+ else
+ ++itr;
+ }
+ }
+
+ /**
+ * @name GetNextEventTime
+ * @brief Returns closest occurence of specified event.
+ * @param eventId Wanted event id.
+ * @return Time of found event.
+ */
+ uint32 GetNextEventTime(uint32 eventId) const
+ {
+ if (Empty())
+ return 0;
+
+ for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
+ if (eventId == (itr->second & 0x0000FFFF))
+ return itr->first;
+
+ return 0;
+ }
+
+ /**
+ * @name GetNextEventTime
+ * @return Time of next event.
+ */
+ uint32 GetNextEventTime() const
+ {
+ return Empty() ? 0 : _eventMap.begin()->first;
+ }
+
+ /**
+ * @name IsInPhase
+ * @brief Returns wether event map is in specified phase or not.
+ * @param phase Wanted phase.
+ * @return True, if phase of event map contains specified phase.
+ */
+ bool IsInPhase(uint8 phase)
+ {
+ return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
+ }
+
+ /**
+ * @name GetTimeUntilEvent
+ * @brief Returns time in milliseconds until next event.
+ * @param Id of the event.
+ * @return Time of next event.
+ */
+ uint32 GetTimeUntilEvent(uint32 eventId) const
+ {
+ for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr)
+ if (eventId == (itr->second & 0x0000FFFF))
+ return itr->first - _time;
+
+ return std::numeric_limits<uint32>::max();
+ }
+
+ private:
+ /**
+ * @name _time
+ * @brief Internal timer.
+ *
+ * This does not represent the real date/time value.
+ * It's more like a stopwatch: It can run, it can be stopped,
+ * it can be resetted and so on. Events occur when this timer
+ * has reached their time value. Its value is changed in the
+ * Update method.
+ */
+ uint32 _time;
+
+ /**
+ * @name _phase
+ * @brief Phase mask of the event map.
+ *
+ * Contains the phases the event map is in. Multiple
+ * phases from 1 to 8 can be set with SetPhase or
+ * AddPhase. RemovePhase deactives a phase.
+ */
+ uint8 _phase;
+
+ /**
+ * @name _eventMap
+ * @brief Internal event storage map. Contains the scheduled events.
+ *
+ * See typedef at the beginning of the class for more
+ * details.
+ */
+ EventStore _eventMap;
+
+
+ /**
+ * @name _lastEvent
+ * @brief Stores information on the most recently executed event
+ */
+ uint32 _lastEvent;
+};
+
#endif
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
index c5424374f5a..6e4214603cb 100644
--- a/src/server/worldserver/Master.cpp
+++ b/src/server/worldserver/Master.cpp
@@ -201,24 +201,24 @@ int Master::Run()
ACE_Based::Thread rarThread(new RARunnable);
#if defined(_WIN32) || defined(__linux__)
-
+
///- Handle affinity for multiple processors and process priority
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
#ifdef _WIN32 // Windows
-
+
HANDLE hProcess = GetCurrentProcess();
-
+
if (affinity > 0)
{
ULONG_PTR appAff;
ULONG_PTR sysAff;
-
+
if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
{
ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors
-
+
if (!currentAffinity)
TC_LOG_ERROR("server.worldserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", affinity, appAff);
else if (SetProcessAffinityMask(hProcess, currentAffinity))
@@ -227,7 +227,7 @@ int Master::Run()
TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x", currentAffinity);
}
}
-
+
if (highPriority)
{
if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
@@ -235,9 +235,9 @@ int Master::Run()
else
TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class.");
}
-
+
#else // Linux
-
+
if (affinity > 0)
{
cpu_set_t mask;
@@ -264,7 +264,7 @@ int Master::Run()
else
TC_LOG_INFO("server.worldserver", "worldserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
}
-
+
#endif
#endif