aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/QuestHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/QuestHandler.cpp')
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp130
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)