diff options
Diffstat (limited to 'src/server/game/Handlers/QuestHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 130 |
1 files changed, 58 insertions, 72 deletions
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 1fe2dbc32b9..d86bbf17cb1 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -28,6 +28,7 @@ #include "GossipDef.h" #include "Group.h" #include "Log.h" +#include "Memory.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" @@ -94,118 +95,103 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG else object = ObjectAccessor::FindPlayer(packet.QuestGiverGUID); - auto CLOSE_GOSSIP_CLEAR_SHARING_INFO = ([this]() + auto CLOSE_GOSSIP_CLEAR_SHARING_INFO = Trinity::make_unique_ptr_with_deleter(_player, [](Player* player) { - _player->PlayerTalkClass->SendCloseGossip(); - _player->ClearQuestSharingInfo(); + player->PlayerTalkClass->SendCloseGossip(); + player->ClearQuestSharingInfo(); }); // no or incorrect quest giver if (!object) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } if (Player* playerQuestObject = object->ToPlayer()) { if ((_player->GetPlayerSharingQuest().IsEmpty() && _player->GetPlayerSharingQuest() != packet.QuestGiverGUID) || !playerQuestObject->CanShareQuest(packet.QuestID)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } + if (!_player->IsInSameRaidWith(playerQuestObject)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } } else { if (!object->hasQuest(packet.QuestID)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } } // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } - if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID)) + Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); + if (!quest) + return; + + // prevent cheating + if (!GetPlayer()->CanTakeQuest(quest, true)) + return; + + if (!_player->GetPlayerSharingQuest().IsEmpty()) { - // prevent cheating - if (!GetPlayer()->CanTakeQuest(quest, true)) + Player* player = ObjectAccessor::FindPlayer(_player->GetPlayerSharingQuest()); + if (player) { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); - return; + player->SendPushToPartyResponse(_player, QuestPushReason::Accepted); + _player->ClearQuestSharingInfo(); } + } - if (!_player->GetPlayerSharingQuest().IsEmpty()) - { - Player* player = ObjectAccessor::FindPlayer(_player->GetPlayerSharingQuest()); - if (player) - { - player->SendPushToPartyResponse(_player, QuestPushReason::Accepted); - _player->ClearQuestSharingInfo(); - } - } + if (!_player->CanAddQuest(quest, true)) + return; - if (_player->CanAddQuest(quest, true)) - { - _player->AddQuestAndCheckCompletion(quest, object); + (void)CLOSE_GOSSIP_CLEAR_SHARING_INFO.release(); + + _player->AddQuestAndCheckCompletion(quest, object); - if (quest->IsPushedToPartyOnAccept()) + if (quest->IsPushedToPartyOnAccept()) + { + if (Group* group = _player->GetGroup()) + { + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { - if (Group* group = _player->GetGroup()) - { - for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) - { - Player* player = itr->GetSource(); + Player* player = itr->GetSource(); - if (!player || player == _player || !player->IsInMap(_player)) // not self and in same map - continue; + if (!player || player == _player || !player->IsInMap(_player)) // not self and in same map + continue; - if (player->CanTakeQuest(quest, true)) - { - player->SetQuestSharingInfo(_player->GetGUID(), quest->GetQuestId()); + if (player->CanTakeQuest(quest, true)) + { + player->SetQuestSharingInfo(_player->GetGUID(), quest->GetQuestId()); - // need confirmation that any gossip window will close - player->PlayerTalkClass->SendCloseGossip(); + // need confirmation that any gossip window will close + player->PlayerTalkClass->SendCloseGossip(); - _player->SendQuestConfirmAccept(quest, player); - } - } + _player->SendQuestConfirmAccept(quest, player); } } - - if (quest->HasFlag(QUEST_FLAGS_LAUNCH_GOSSIP_ACCEPT) && !quest->HasFlagEx(QUEST_FLAGS_EX_SUPPRESS_GOSSIP_ACCEPT)) - { - auto launchGossip = [&](WorldObject* worldObject) - { - _player->PlayerTalkClass->ClearMenus(); - _player->PrepareGossipMenu(worldObject, _player->GetGossipMenuForSource(worldObject), true); - _player->SendPreparedGossip(worldObject); - _player->PlayerTalkClass->GetInteractionData().IsLaunchedByQuest = true; - }; - - if (Creature* creature = object->ToCreature()) - launchGossip(creature); - else if (GameObject* go = object->ToGameObject()) - launchGossip(go); - } - else - _player->PlayerTalkClass->SendCloseGossip(); - - return; } } - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); + if (quest->HasFlag(QUEST_FLAGS_LAUNCH_GOSSIP_ACCEPT) && !quest->HasFlagEx(QUEST_FLAGS_EX_SUPPRESS_GOSSIP_ACCEPT)) + { + auto launchGossip = [&](WorldObject* worldObject) + { + _player->PlayerTalkClass->ClearMenus(); + _player->PrepareGossipMenu(worldObject, _player->GetGossipMenuForSource(worldObject), true); + _player->SendPreparedGossip(worldObject); + _player->PlayerTalkClass->GetInteractionData().IsLaunchedByQuest = true; + }; + + if (Creature* creature = object->ToCreature()) + launchGossip(creature); + else if (GameObject* go = object->ToGameObject()) + launchGossip(go); + } + // do not close gossip if quest accept script started a new interaction + else if (!_player->PlayerTalkClass->GetInteractionData().IsInteractingWith(object->GetGUID(), PlayerInteractionType::QuestGiver)) + _player->PlayerTalkClass->GetInteractionData().IsLaunchedByQuest = true; + else + _player->PlayerTalkClass->SendCloseGossip(); } void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPackets::Quest::QuestGiverQueryQuest& packet) |