From d99f0362cb9ee9e6710162c147260bb7e23eef10 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Tue, 3 Jun 2014 00:39:20 +0100 Subject: Core/Auras: Update model overwriting rules for SPELL_AURA_TRANSFORM --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b87524357d2..0dc6acdd4d8 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1672,9 +1672,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); @@ -1725,6 +1722,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 { @@ -1847,9 +1850,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) { @@ -2018,11 +2023,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()) { -- cgit v1.2.3 From 18868f5cbdd55baa95cd5d5c56d77926ae7f1f9c Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Tue, 3 Jun 2014 00:57:36 +0100 Subject: Core/Maps: Allow logging players to enter in instances that have an encounter in progress --- src/server/game/Entities/Player/Player.cpp | 5 +++++ src/server/game/Entities/Player/Player.h | 2 ++ src/server/game/Maps/Map.cpp | 7 +++---- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 433551104b9..eeb72b16f07 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -26757,3 +26757,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..94175834969 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2303,6 +2303,8 @@ class Player : public Unit, public GridObject std::string GetMapAreaAndZoneString(); std::string GetCoordsMapAreaAndZoneString(); + bool IsLoading() const; + protected: // Gamemaster whisper whitelist WhisperListContainer WhisperList; 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; -- cgit v1.2.3 From d05bf542a50c836c1cf1bea402acab35372f2983 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Thu, 5 Jun 2014 11:35:32 +0100 Subject: Core/Spells: Corpse Explosion should not be able to pick the Ghoul out of implicit targets --- src/server/scripts/Spells/spell_dk.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') 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); -- cgit v1.2.3 From bb01c60a526abb280401f73ebee2206ac8ee8111 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Fri, 6 Jun 2014 10:41:45 +0100 Subject: Core/Players: Improve quest item adding/removal checks, solves cases where quest item removal (under specific conditions) incorrectly incompletes quests --- src/server/game/Entities/Player/Player.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index fdb0b526363..a01c3188f3d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -16383,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(q_status.ItemCount[j] + count, reqitemcount); m_QuestStatusSave[questid] = true; - - SendQuestUpdateAddItem(qInfo, j, additemcount); } if (CanCompleteQuest(questid)) CompleteQuest(questid); @@ -16406,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; @@ -16420,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(newItemCount, reqitemcount); + if (newItemCount != q_status.ItemCount[j]) + { + q_status.ItemCount[j] = newItemCount; + m_QuestStatusSave[questid] = true; IncompleteQuest(questid); } return; -- cgit v1.2.3 From b4b3e6f3a22359411417cd60abcfd0133ac5ef24 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Fri, 6 Jun 2014 11:01:36 +0100 Subject: Scripts/Items: Imp in a Ball --- sql/updates/world/2014_06_06_00_world_misc.sql | 92 ++++++++++++++++++++++++++ src/server/game/Texts/CreatureTextMgr.cpp | 13 ++++ src/server/scripts/World/npcs_special.cpp | 56 ++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 sql/updates/world/2014_06_06_00_world_misc.sql (limited to 'src') 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/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(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/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(); } -- cgit v1.2.3 From eae18d8ed0db62ff74bc30bc6a260e4aa9e5fcbc Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Fri, 6 Jun 2014 11:14:32 +0100 Subject: Core/Utils: Move EventMap to Util.h --- src/server/game/AI/CreatureAIImpl.h | 349 ------------------------------------ src/server/shared/Utilities/Util.h | 349 ++++++++++++++++++++++++++++++++++++ 2 files changed, 349 insertions(+), 349 deletions(-) (limited to 'src') 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 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::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/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index b086a28134c..96d5a2abfea 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -565,4 +565,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 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::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 -- cgit v1.2.3 From 2cd0dce366878d995669865a36c99ad834204cd4 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sat, 7 Jun 2014 00:30:08 +0200 Subject: Core: Fix non pch build --- src/server/shared/Utilities/Util.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index 96d5a2abfea..d6ead607c55 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -26,6 +26,7 @@ #include #include #include +#include #include // Searcher for map of structs -- cgit v1.2.3 From 32a3ecb9861d4178665c516ef4c3e61f338cd9fd Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sat, 7 Jun 2014 17:04:20 +0200 Subject: Core/Spells: add missing spellradius to spell "Achievement Check" (fixes hor achievments) --- src/server/game/Spells/SpellMgr.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 4aced0c92dd..9eadd178eb3 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -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; -- cgit v1.2.3 From 6abfdc1ceaa78a9547f5a25e0d819f3db2e2f838 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sat, 7 Jun 2014 17:58:45 +0100 Subject: Core/GOs: When unlinking Fishing Bobber from player to prevent despawning, unlink from spell as well to prevent removing unwanted auras --- src/server/game/Entities/GameObject/GameObject.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') 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); -- cgit v1.2.3 From 1b3149b07f3c3b7bd09a2ae7cd207fb3e4c1dbbf Mon Sep 17 00:00:00 2001 From: aletuna Date: Sat, 7 Jun 2014 19:02:39 +0200 Subject: Scripts/Blackrock Depths: Converted to eventmap+minor coding style changes Closes #11730 --- .../BlackrockDepths/boss_ambassador_flamelash.cpp | 101 +++++---- .../BlackrockDepths/boss_anubshiah.cpp | 149 ++++++------- .../boss_emperor_dagran_thaurissan.cpp | 139 ++++++------ .../BlackrockDepths/boss_general_angerforge.cpp | 163 +++++++------- .../BlackrockDepths/boss_gorosh_the_dervish.cpp | 88 ++++---- .../BlackrockDepths/boss_grizzle.cpp | 99 +++++---- .../boss_high_interrogator_gerstahn.cpp | 118 +++++----- .../BlackrockDepths/boss_magmus.cpp | 114 ++++++---- .../BlackrockDepths/boss_moira_bronzebeard.cpp | 103 +++++---- .../BlackrockDepths/boss_tomb_of_seven.cpp | 240 +++++++++++---------- 10 files changed, 706 insertions(+), 608 deletions(-) (limited to 'src') 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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..1a2e8bba805 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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(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(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..79ffedc8c17 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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..f46c0c118b1 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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..7105d78f2ee 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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..efc9a6e793b 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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..0c36fe9696d 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 - * Copyright (C) 2006-2009 ScriptDev2 * * 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(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(creature); } - }; }; void AddSC_boss_tomb_of_seven() -- cgit v1.2.3 From 97046283b56cc6042332a20ff9405e0e7a6f81f5 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sat, 7 Jun 2014 18:06:22 +0100 Subject: Core/Spells: Anti-Magic shell should give immunity to all spells that belong to SPELL_SCHOOL_MASK_MAGIC regardless of dispel type --- src/server/game/Entities/Unit/Unit.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4efa1374ec7..7721aec151b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11111,8 +11111,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; } -- cgit v1.2.3 From 4ec84fd1ec77f19aa6b81e052caab6e9b16e2e91 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 7 Jun 2014 22:13:42 +0200 Subject: Core/Database: Update log for incorrect db structure --- src/server/shared/Database/DatabaseWorkerPool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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; } -- cgit v1.2.3 From 5fee5b012566191bfd0c27d3fcfc64aad6d657cb Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 7 Jun 2014 22:47:50 +0200 Subject: Core/Banks: Fix some bank exploits Re-implement the cheat checks removed in a12501fb5e6f827d905e0eeba5bc908f8279880a and check if Player can interact with the Banker when handling bank-related opcodes. --- src/server/game/Handlers/ItemHandler.cpp | 62 ++++++++++++++++++++++++++++---- src/server/game/Handlers/NPCHandler.cpp | 1 + src/server/game/Server/WorldSession.cpp | 3 +- src/server/game/Server/WorldSession.h | 3 ++ 4 files changed, 62 insertions(+), 7 deletions(-) (limited to 'src') 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/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/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index eda7b8917a7..a0ff8b98e43 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -123,7 +123,8 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8 isRecruiter(isARecruiter), _RBACData(NULL), expireTime(60000), // 1 min after socket loss, session is deleted - forceExit(false) + forceExit(false), + m_currentBankerGUID(0) { memset(m_Tutorials, 0, sizeof(m_Tutorials)); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 82125aafd6d..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); @@ -1023,6 +1025,7 @@ class WorldSession rbac::RBACData* _RBACData; uint32 expireTime; bool forceExit; + uint64 m_currentBankerGUID; WorldSession(WorldSession const& right) = delete; WorldSession& operator=(WorldSession const& right) = delete; -- cgit v1.2.3