OregonCore  revision 3611e8a-git
Your Favourite TBC server
QuestHandler.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "Log.h"
20 #include "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "Opcodes.h"
23 #include "World.h"
24 #include "ObjectMgr.h"
25 #include "Player.h"
26 #include "GossipDef.h"
27 #include "QuestDef.h"
28 #include "ObjectAccessor.h"
29 #include "Group.h"
30 #include "Battleground.h"
31 #include "BattlegroundAV.h"
32 #include "ScriptMgr.h"
33 #include "CreatureAI.h"
34 #include "GameObjectAI.h"
35 #include "ConditionMgr.h"
36 
38 {
39  uint64 guid;
40  recv_data >> guid;
41  uint8 questStatus = DIALOG_STATUS_NONE;
42  uint8 defstatus = DIALOG_STATUS_NONE;
43 
45  if (!questgiver)
46  {
47  sLog.outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)", GuidHigh2TypeId(GUID_HIPART(guid)), GUID_LOPART(guid));
48  return;
49  }
50 
51  switch (questgiver->GetTypeId())
52  {
53  case TYPEID_UNIT:
54  {
55  DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", uint32(GUID_LOPART(guid)));
56  Creature* cr_questgiver = questgiver->ToCreature();
57  if (!cr_questgiver->IsHostileTo(_player)) // not show quest status to enemies
58  {
59  questStatus = sScriptMgr.NPCDialogStatus(_player, cr_questgiver);
60  if (questStatus > 6)
61  questStatus = getDialogStatus(_player, cr_questgiver, defstatus);
62  }
63  break;
64  }
65  case TYPEID_GAMEOBJECT:
66  {
67  DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", uint32(GUID_LOPART(guid)));
68  GameObject* go_questgiver = (GameObject*)questgiver;
69  questStatus = sScriptMgr.GODialogStatus(_player, go_questgiver);
70  if (questStatus > 6)
71  questStatus = getDialogStatus(_player, go_questgiver, defstatus);
72  break;
73  }
74  default:
75  sLog.outError("QuestGiver called for unexpected type %u", questgiver->GetTypeId());
76  break;
77  }
78 
79  //inform client about status of quest
80  _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid);
81 }
82 
84 {
85  uint64 guid;
86  recv_data >> guid;
87 
88  sLog.outDebug ("WORLD: Received CMSG_QUESTGIVER_HELLO npc = %u", GUID_LOPART(guid));
89 
91  if (!pCreature)
92  {
93  sLog.outDebug ("WORLD: HandleQuestgiverHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guid));
94  return;
95  }
96 
97  // remove fake death
98  if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
100  // Stop the npc if moving
101  if (!pCreature->IsStopped())
102  pCreature->StopMoving();
103 
104  if (sScriptMgr.GossipHello(_player, pCreature))
105  return;
106 
107  _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureTemplate()->GossipMenuId);
108  _player->SendPreparedGossip(pCreature);
109 
110  pCreature->AI()->sGossipHello(_player);
111 }
112 
114 {
115  uint64 guid;
116  uint32 quest;
117  recv_data >> guid >> quest;
118 
119  if (!GetPlayer()->IsAlive())
120  return;
121 
122  DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), quest);
123 
125 
126  // no or incorrect quest giver
127  if (!pObject || (pObject->GetTypeId() != TYPEID_PLAYER && !pObject->hasQuest(quest)) ||
128  (pObject->GetTypeId() == TYPEID_PLAYER && !pObject->ToPlayer()->CanShareQuest(quest)))
129  {
131  _player->SetDivider(0);
132  return;
133  }
134 
135  Quest const* qInfo = sObjectMgr.GetQuestTemplate(quest);
136  if (qInfo)
137  {
138  // prevent cheating
139  if (!GetPlayer()->CanTakeQuest(qInfo, true))
140  {
142  _player->SetDivider(0);
143  return;
144  }
145 
146  if (_player->GetDivider() != 0)
147  {
149  if (pPlayer)
150  {
152  _player->SetDivider(0);
153  }
154  }
155 
156  if (_player->CanAddQuest(qInfo, true))
157  {
158  _player->AddQuest(qInfo, pObject);
159 
160  if (qInfo->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
161  {
162  if (Group* pGroup = _player->GetGroup())
163  {
164  for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
165  {
166  Player* pPlayer = itr->GetSource();
167 
168  if (!pPlayer || pPlayer == _player) // not self
169  continue;
170 
171  if (pPlayer->CanTakeQuest(qInfo, true))
172  {
173  pPlayer->SetDivider(_player->GetGUID());
174 
175  //need confirmation that any gossip window will close
176  pPlayer->PlayerTalkClass->CloseGossip();
177 
178  _player->SendQuestConfirmAccept(qInfo, pPlayer);
179  }
180  }
181  }
182  }
183 
184  if (_player->CanCompleteQuest(quest))
185  _player->CompleteQuest(quest);
186 
187  switch (pObject->GetTypeId())
188  {
189  case TYPEID_UNIT:
190  sScriptMgr.QuestAccept(_player, pObject->ToCreature(), qInfo);
191  pObject->ToCreature()->AI()->sQuestAccept(_player, qInfo);
192  break;
193  case TYPEID_ITEM:
194  case TYPEID_CONTAINER:
195  {
196  sScriptMgr.ItemQuestAccept(_player, ((Item*)pObject), qInfo);
197 
198  // destroy not required for quest finish quest starting item
199  bool destroyItem = true;
200  for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
201  {
202  if ((qInfo->ReqItemId[i] == ((Item*)pObject)->GetEntry()) && (((Item*)pObject)->GetProto()->MaxCount > 0))
203  {
204  destroyItem = false;
205  break;
206  }
207  }
208 
209  if (destroyItem)
210  _player->DestroyItem(((Item*)pObject)->GetBagSlot(), ((Item*)pObject)->GetSlot(), true);
211 
212  break;
213  }
214  case TYPEID_GAMEOBJECT:
215  sScriptMgr.GOQuestAccept(_player, ((GameObject*)pObject), qInfo);
216  pObject->ToGameObject()->AI()->QuestAccept(_player, qInfo);
217  break;
218  }
220 
221  if (qInfo->GetSrcSpell() > 0)
222  _player->CastSpell(_player, qInfo->GetSrcSpell(), true);
223 
224  return;
225  }
226  }
227 
229 }
230 
232 {
233  uint64 guid;
234  uint32 quest;
235  recv_data >> guid >> quest;
236  DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), quest);
237 
238  // Verify that the guid is valid and is a questgiver or involved in the requested quest
240  if (!pObject || (!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest)))
241  {
243  return;
244  }
245 
246  Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest);
247  if (pQuest)
248  _player->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, pObject->GetGUID(), true);
249 }
250 
252 {
253  if (!_player)
254  return;
255 
256  uint32 quest;
257  recv_data >> quest;
258  DEBUG_LOG("WORLD: Received CMSG_QUEST_QUERY quest = %u", quest);
259 
260  Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest);
261  if (pQuest)
263 }
264 
266 {
267  uint32 quest, reward;
268  uint64 guid;
269  recv_data >> guid >> quest >> reward;
270 
271  if (reward >= QUEST_REWARD_CHOICES_COUNT)
272  {
273  sLog.outError("Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (probably packet hacking)", _player->GetName(), _player->GetGUIDLow(), reward);
274  return;
275  }
276 
277  if (!GetPlayer()->IsAlive())
278  return;
279 
280  sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), quest, reward);
281 
283  if (!pObject)
284  return;
285 
286  if (!pObject->hasInvolvedQuest(quest))
287  return;
288 
289  if (Quest const *pQuest = sObjectMgr.GetQuestTemplate(quest))
290  {
291  if ((!_player->CanSeeStartQuest(pQuest) && _player->GetQuestStatus(quest) == QUEST_STATUS_NONE) ||
292  (_player->GetQuestStatus(quest) != QUEST_STATUS_COMPLETE && !pQuest->IsAutoComplete()))
293  {
294  sLog.outError("HACK ALERT: Player %s (guid: %u) is trying to complete quest (id: %u) but he has no right to do it!",
295  _player->GetName(), _player->GetGUIDLow(), quest);
296  return;
297  }
298  if (_player->CanRewardQuest(pQuest, reward, true))
299  {
300  _player->RewardQuest(pQuest, reward, pObject);
301 
302  switch (pObject->GetTypeId())
303  {
304  case TYPEID_UNIT:
305  {
306  Creature* questgiver = pObject->ToCreature();
307  if (!(sScriptMgr.ChooseReward(_player, pObject->ToCreature(), pQuest, reward)))
308  {
309  // Send next quest
310  if (Quest const* nextquest = _player->GetNextQuest(guid, pQuest))
311  _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest, guid, true);
312 
313  questgiver->AI()->sQuestReward(_player, pQuest, reward);
314  }
315  break;
316  }
317  case TYPEID_GAMEOBJECT:
318  {
319  GameObject* questGiver = pObject->ToGameObject();
320  if (!sScriptMgr.GOChooseReward(_player, ((GameObject*)pObject), pQuest, reward))
321  {
322  // Send next quest
323  if (Quest const* nextquest = _player->GetNextQuest(guid, pQuest))
324  _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextquest, guid, true);
325 
326  questGiver->AI()->QuestReward(_player, pQuest, reward);
327  }
328  break;
329  }
330  default:
331  break;
332  }
333  }
334  else
335  _player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
336  }
337 }
338 
340 {
341  uint32 quest;
342  uint64 guid;
343  recv_data >> guid >> quest;
344 
345  if (!GetPlayer()->IsAlive())
346  return;
347 
348  sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u", uint32(GUID_LOPART(guid)), quest);
349 
351  if (!pObject || !pObject->hasInvolvedQuest(quest))
352  return;
353 
354  if (_player->CanCompleteQuest(quest))
355  _player->CompleteQuest(quest);
356 
358  return;
359 
360  if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest))
361  _player->PlayerTalkClass->SendQuestGiverOfferReward(pQuest, guid, true);
362 }
363 
365 {
366  sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_CANCEL");
367 
369 }
370 
372 {
373  uint8 slot1, slot2;
374  recv_data >> slot1 >> slot2;
375 
376  if (slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE)
377  return;
378 
379  sLog.outDebug("WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = %u, slot 2 = %u", slot1, slot2);
380 
381  GetPlayer()->SwapQuestSlot(slot1, slot2);
382 }
383 
385 {
386  uint8 slot;
387  recv_data >> slot;
388 
389  sLog.outDebug("WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = %u", slot);
390 
391  if (slot < MAX_QUEST_LOG_SIZE)
392  {
393  if (uint32 quest = _player->GetQuestSlotQuestId(slot))
394  {
395  if (!_player->TakeQuestSourceItem(quest, true))
396  return; // can't un-equip some items, reject quest cancel
397 
398  if (const Quest* pQuest = sObjectMgr.GetQuestTemplate(quest))
399  {
400  if (pQuest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
401  _player->RemoveTimedQuest(quest);
402  }
403 
405  }
406 
407  _player->SetQuestSlot(slot, 0);
408  }
409 }
410 
412 {
413  uint32 questId;
414  recv_data >> questId;
415 
416  sLog.outDebug("WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", questId);
417 
418  if (Quest const* quest = sObjectMgr.GetQuestTemplate(questId))
419  {
420  if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
421  return;
422 
423  Player* originalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
424  if (!originalPlayer)
425  return;
426 
427  if (!_player->IsInSameRaidWith(originalPlayer))
428  return;
429 
430  if (!_player->CanTakeQuest(quest, true))
431  return;
432 
433  if (_player->CanAddQuest(quest, true))
434  _player->AddQuest(quest, NULL); // NULL, this prevent DB script from duplicate running
435 
436  _player->SetDivider(0);
437  }
438 }
439 
441 {
442  uint32 quest;
443  uint64 guid;
444  recv_data >> guid >> quest;
445 
446  if (!_player->IsAlive())
447  return;
448 
449  sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), quest);
450 
451  if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest))
452  {
454  {
455  sLog.outError("Possible hacking attempt: Player %s [guid: %u] tried to complete quest [entry: %u] without being in possession of the quest!",
456  _player->GetName(), _player->GetGUIDLow(), quest);
457  return;
458  }
459  // @todo need a virtual function
460  if (_player->InBattleground())
461  if (Battleground* bg = _player->GetBattleground())
462  if (bg->GetTypeID() == BATTLEGROUND_AV)
464 
466  {
467  if (pQuest->IsRepeatable())
469  else
470  _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest, false), false);
471  }
472  else
473  _player->PlayerTalkClass->SendQuestGiverRequestItems(pQuest, guid, _player->CanRewardQuest(pQuest, false), false);
474  }
475 }
476 
478 {
479  sLog.outDebug("WORLD: Received CMSG_QUESTGIVER_QUEST_AUTOLAUNCH");
480 }
481 
483 {
484  uint32 questId;
485  recvPacket >> questId;
486 
487  sLog.outDebug("WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId);
488 
489  if (Quest const* pQuest = sObjectMgr.GetQuestTemplate(questId))
490  {
491  if (Group* pGroup = _player->GetGroup())
492  {
493  for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
494  {
495  Player* pPlayer = itr->GetSource();
496 
497  if (!pPlayer || pPlayer == _player) // skip self
498  continue;
499 
501 
502  // 2.4.3: can only share quests within 10 yards
503  if (_player->GetDistance(pPlayer) > 10)
504  {
506  continue;
507  }
508 
509  //player already has quest
510  if (!pPlayer->SatisfyQuestStatus(pQuest, false))
511  {
513  continue;
514  }
515 
516  //player already completed quest
517  if (pPlayer->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
518  {
520  continue;
521  }
522 
523  //player is ineligible for the quest
524  if (!pPlayer->CanTakeQuest(pQuest, false))
525  {
527  continue;
528  }
529 
530  //player has full quest log
531  if (!pPlayer->SatisfyQuestLog(false))
532  {
534  continue;
535  }
536 
537  if (pPlayer->GetDivider() != 0)
538  {
540  continue;
541  }
542 
543  pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetGUID(), true);
544  pPlayer->SetDivider(_player->GetGUID());
545  }
546  }
547  }
548 }
549 
551 {
552  uint64 guid;
553  uint8 msg;
554  recvPacket >> guid >> msg;
555 
556  sLog.outDebug("WORLD: Received MSG_QUEST_PUSH_RESULT");
557 
558  if (_player->GetDivider() != 0)
559  {
561  if (pPlayer)
562  {
563  WorldPacket data(MSG_QUEST_PUSH_RESULT, (8 + 1));
564  data << uint64(guid);
565  data << uint8(msg); // valid values: 0-8
566  pPlayer->GetSession()->SendPacket(&data);
567  _player->SetDivider(0);
568  }
569  }
570 }
571 
572 uint32 WorldSession::getDialogStatus(Player* pPlayer, Object* questgiver, uint32 defstatus)
573 {
574  uint32 result = defstatus;
575 
576  QuestRelations const* qir;
577  QuestRelations const* qr;
578 
579  switch (questgiver->GetTypeId())
580  {
581  case TYPEID_GAMEOBJECT:
582  {
583  qir = &sObjectMgr.mGOQuestInvolvedRelations;
584  qr = &sObjectMgr.mGOQuestRelations;
585  break;
586  }
587  case TYPEID_UNIT:
588  {
589  qir = &sObjectMgr.mCreatureQuestInvolvedRelations;
590  qr = &sObjectMgr.mCreatureQuestRelations;
591  break;
592  }
593  default:
594  //its imposible, but check ^)
595  sLog.outError("Warning: GetDialogStatus called for unexpected type %u", questgiver->GetTypeId());
596  return DIALOG_STATUS_NONE;
597  }
598 
599  for (QuestRelations::const_iterator i = qir->lower_bound(questgiver->GetEntry()); i != qir->upper_bound(questgiver->GetEntry()); ++i)
600  {
601  uint32 result2 = 0;
602  uint32 quest_id = i->second;
603  Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
604  if (!pQuest) continue;
605 
606  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, pQuest->GetQuestId());
607  if (!sConditionMgr.IsObjectMeetToConditions(pPlayer, conditions))
608  continue;
609 
610  QuestStatus status = pPlayer->GetQuestStatus(quest_id);
611  if ((status == QUEST_STATUS_COMPLETE && !pPlayer->GetQuestRewardStatus(quest_id)) ||
612  (pQuest->IsAutoComplete() && pPlayer->CanTakeQuest(pQuest, false)))
613  {
614  if (pQuest->IsAutoComplete() && pQuest->IsRepeatable())
615  result2 = DIALOG_STATUS_REWARD_REP;
616  else
617  result2 = DIALOG_STATUS_REWARD;
618  }
619  else if (status == QUEST_STATUS_INCOMPLETE)
620  result2 = DIALOG_STATUS_INCOMPLETE;
621 
622  if (result2 > result)
623  result = result2;
624  }
625 
626  for (QuestRelations::const_iterator i = qr->lower_bound(questgiver->GetEntry()); i != qr->upper_bound(questgiver->GetEntry()); ++i)
627  {
628  uint32 result2 = 0;
629  uint32 quest_id = i->second;
630  Quest const* pQuest = sObjectMgr.GetQuestTemplate(quest_id);
631  if (!pQuest)
632  continue;
633 
634  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, pQuest->GetQuestId());
635  if (!sConditionMgr.IsObjectMeetToConditions(pPlayer, conditions))
636  continue;
637 
638  QuestStatus status = pPlayer->GetQuestStatus(quest_id);
639  if (status == QUEST_STATUS_NONE)
640  {
641  if (pPlayer->CanSeeStartQuest(pQuest))
642  {
643  if (pPlayer->SatisfyQuestLevel(pQuest, false))
644  {
645  auto questStatusItr = pPlayer->getQuestStatusMap().find(quest_id);
646  bool rewarded = (questStatusItr != pPlayer->getQuestStatusMap().end()) ? questStatusItr->second.m_rewarded : false;
647 
648  if (pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && rewarded))
649  {
650  result2 = DIALOG_STATUS_REWARD_REP;
651  }
652  else if (pPlayer->getLevel() <= pPlayer->GetQuestLevelForPlayer(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF))
653  {
654  if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
655  result2 = DIALOG_STATUS_AVAILABLE_REP;
656  else
657  result2 = DIALOG_STATUS_AVAILABLE;
658  }
659  else
660  result2 = DIALOG_STATUS_CHAT;
661  }
662  else
663  result2 = DIALOG_STATUS_UNAVAILABLE;
664  }
665  }
666 
667  if (result2 > result)
668  result = result2;
669  }
670 
671  return result;
672 }
673 
675 {
676  DEBUG_LOG("WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
677 
678  uint32 count = 0;
679 
681  data << uint32(count); // placeholder
682 
683  for (Player::ClientGUIDs::iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
684  {
685  uint8 questStatus = DIALOG_STATUS_NONE;
686  uint8 defstatus = DIALOG_STATUS_NONE;
687 
688  if (IS_CREATURE_GUID(*itr))
689  {
690  Creature* questgiver = GetPlayer()->GetMap()->GetCreature(*itr);
691  if (!questgiver || questgiver->IsHostileTo(_player))
692  continue;
694  continue;
695  questStatus = sScriptMgr.NPCDialogStatus(_player, questgiver);
696  if (questStatus > 6)
697  questStatus = getDialogStatus(_player, questgiver, defstatus);
698 
699  data << uint64(questgiver->GetGUID());
700  data << uint8(questStatus);
701  ++count;
702  }
703  else if (IS_GAMEOBJECT_GUID(*itr))
704  {
705  GameObject* questgiver = GetPlayer()->GetMap()->GetGameObject(*itr);
706  if (!questgiver)
707  continue;
708  if (questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
709  continue;
710  questStatus = sScriptMgr.GODialogStatus(_player, questgiver);
711  if (questStatus > 6)
712  questStatus = getDialogStatus(_player, questgiver, defstatus);
713 
714  data << uint64(questgiver->GetGUID());
715  data << uint8(questStatus);
716  ++count;
717  }
718  }
719 
720  data.put<uint32>(0, count); // write real count
721  SendPacket(&data);
722 }
723 
Definition: Object.h:124
void RemoveTimedQuest(uint32 quest_id)
Definition: Player.h:1467
virtual bool QuestAccept(Player *, Quest const *)
Definition: GameObjectAI.h:47
virtual void sQuestReward(Player *, Quest const *, uint32)
Definition: UnitAI.h:116
void HandleQuestgiverQuestQueryOpcode(WorldPacket &recvPacket)
bool SatisfyQuestLog(bool msg)
Definition: Player.cpp:13236
bool IsAutoComplete() const
Definition: QuestDef.h:370
ClientGUIDs m_clientGUIDs
Definition: Player.h:2471
Group * GetGroup()
Definition: Player.h:2589
GameObjectAI * AI() const
Definition: GameObject.h:836
void SetDivider(uint64 guid)
Definition: Player.h:1448
bool CanRewardQuest(Quest const *pQuest, bool msg)
Definition: Player.cpp:12867
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition: Player.cpp:13641
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
void SendQuestQueryResponse(Quest const *pQuest)
Definition: GossipDef.cpp:500
Battleground * GetBattleground() const
Definition: Player.cpp:19386
PlayerMenu * PlayerTalkClass
Definition: Player.h:2194
Map * GetMap() const
Definition: Object.h:829
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:31
static Object * GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask)
bool CanCompleteQuest(uint32 quest_id)
Definition: Player.cpp:12776
void SendQuestConfirmAccept(Quest const *pQuest, Player *pReceiver)
Definition: Player.cpp:14207
void HandleQuestgiverStatusQueryOpcode(WorldPacket &recvPacket)
void RewardQuest(Quest const *pQuest, uint32 reward, Object *questGiver, bool announce=true)
Definition: Player.cpp:13045
uint32 getDialogStatus(Player *pPlayer, Object *questgiver, uint32 defstatus)
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:223
void HandleQuestgiverAcceptQuestOpcode(WorldPacket &recvPacket)
uint32 ReqItemId[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:385
void RemoveSpellsCausingAura(AuraType auraType)
Definition: Unit.cpp:648
bool CanSeeStartQuest(Quest const *pQuest)
Definition: Player.cpp:12728
QuestStatus
Definition: QuestDef.h:89
#define sLog
Log class singleton.
Definition: Log.h:187
void SendQuestGiverQuestDetails(Quest const *pQuest, uint64 npcGUID, bool ActivateAccept)
Definition: GossipDef.cpp:401
Quest const * GetNextQuest(uint64 guid, Quest const *pQuest)
Definition: Player.cpp:12691
void HandleQuestgiverRequestRewardOpcode(WorldPacket &recvPacket)
void HandleQuestConfirmAccept(WorldPacket &recv_data)
bool SatisfyQuestStatus(Quest const *qInfo, bool msg)
Definition: Player.cpp:13409
void HandleQuestPushResult(WorldPacket &recvPacket)
#define GUID_HIPART(x)
Definition: ObjectGuid.h:82
Player * GetPlayer() const
Definition: WorldSession.h:104
uint32 GetGUIDLow() const
Definition: Object.h:160
uint32 GetSrcSpell() const
Definition: QuestDef.h:281
uint64 GetDivider()
Definition: Player.h:1444
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
GameObject * ToGameObject()
Definition: Object.h:395
void HandleQuestComplete(WorldPacket &recv_data)
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition: Player.cpp:10724
Player * ToPlayer()
Definition: Object.h:386
void PrepareGossipMenu(WorldObject *pSource, uint32 menuId=0)
Definition: Player.cpp:12174
uint8 GetTypeId() const
Definition: Object.h:204
bool IsRepeatable() const
Definition: QuestDef.h:368
void SendPreparedGossip(WorldObject *pSource)
Definition: Player.cpp:12332
Creature * GetCreature(uint64 guid)
Definition: Map.cpp:2632
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1364
uint32 GetQuestLevelForPlayer(Quest const *pQuest) const
Definition: Player.h:1318
std::multimap< uint32, uint32 > QuestRelations
Definition: ObjectMgr.h:390
virtual bool QuestReward(Player *, Quest const *, uint32)
Definition: GameObjectAI.h:48
uint32 GuidHigh2TypeId(uint32 guid_hi)
Definition: Object.cpp:43
#define IS_CREATURE_GUID(Guid)
Definition: ObjectGuid.h:66
bool IsStopped() const
Definition: Unit.h:2006
uint32 GossipMenuId
Definition: Creature.h:141
uint32 GetQuestId() const
Definition: QuestDef.h:186
void HandleQuestgiverCancel(WorldPacket &recv_data)
bool IsAlive() const
Definition: Unit.h:1433
float GetDistance(const WorldObject *obj) const
Definition: Object.h:706
virtual void sQuestAccept(Player *, Quest const *)
Definition: UnitAI.h:114
void HandleQuestgiverHelloOpcode(WorldPacket &recvPacket)
void put(size_t pos, T value)
Definition: ByteBuffer.h:79
Definition: Item.h:196
void AddQuest(Quest const *pQuest, Object *questGiver)
Definition: Player.cpp:12954
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1174
CreatureAI * AI() const
Definition: Creature.h:548
void SendQuestGiverOfferReward(Quest const *pQuest, uint64 npcGUID, bool EnbleNext)
Definition: GossipDef.cpp:618
bool TakeQuestSourceItem(uint32 quest_id, bool msg)
Definition: Player.cpp:13597
static Player * FindPlayer(uint64, bool force=false)
void SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID)
Definition: GossipDef.cpp:391
#define DEBUG_LOG(...)
Definition: Log.h:194
#define sConditionMgr
Definition: ConditionMgr.h:312
void HandleQuestLogSwapQuest(WorldPacket &recv_data)
bool SatisfyQuestLevel(Quest const *qInfo, bool msg)
Definition: Player.cpp:13225
void SendQuestGiverRequestItems(Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel)
Definition: GossipDef.cpp:701
#define IS_GAMEOBJECT_GUID(Guid)
Definition: ObjectGuid.h:73
GroupReference * next()
bool CanAddQuest(Quest const *pQuest, bool msg)
Definition: Player.cpp:12752
const char * GetName() const
Definition: Object.h:692
ACE_UINT64 uint64
Definition: Define.h:70
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1816
void HandleQuestLogRemoveQuest(WorldPacket &recv_data)
bool CanTakeQuest(Quest const *pQuest, bool msg)
Definition: Player.cpp:12740
void HandleQuestAutoLaunch(WorldPacket &recvPacket)
void SendPushToPartyResponse(Player *pPlayer, uint32 msg)
Definition: Player.cpp:14234
void CloseGossip()
Definition: GossipDef.cpp:187
bool InBattleground() const
Definition: Player.h:2207
void SwapQuestSlot(uint16 slot1, uint16 slot2)
Definition: Player.h:1407
CreatureInfo const * GetCreatureTemplate() const
Definition: Creature.h:598
GameobjectTypes GetGoType() const
Definition: GameObject.h:718
void HandleQuestQueryOpcode(WorldPacket &recvPacket)
Player * _player
Definition: WorldSession.h:729
void HandleQuestgiverChooseRewardOpcode(WorldPacket &recvPacket)
#define QUEST_REWARD_CHOICES_COUNT
Definition: QuestDef.h:35
Creature * ToCreature()
Definition: Object.h:389
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:179
void HandleQuestgiverStatusQueryMultipleOpcode(WorldPacket &recvPacket)
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:7279
Creature * GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
Definition: Player.cpp:2191
bool CanShareQuest(uint32 quest_id) const
Definition: Player.cpp:13652
void CompleteQuest(uint32 quest_id)
Definition: Player.cpp:13017
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1384
#define sScriptMgr
Definition: Group.h:526
uint32 GetEntry() const
Definition: Object.h:186
WorldSession * GetSession() const
Definition: Player.h:1959
#define sWorld
Definition: World.h:860
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.h:299
ACE_UINT32 uint32
Definition: Define.h:71
GameObject * GetGameObject(uint64 guid)
Definition: Map.cpp:2638
virtual bool hasQuest(uint32) const
Definition: Object.h:372
uint32 getLevel() const
Definition: Unit.h:1029
void StopMoving()
Definition: Unit.cpp:11838
Definition: Player.h:922
virtual bool hasInvolvedQuest(uint32) const
Definition: Object.h:376
#define QUEST_OBJECTIVES_COUNT
Definition: QuestDef.h:33
QuestStatusMap & getQuestStatusMap()
Definition: Player.h:1561
bool GetQuestRewardStatus(uint32 quest_id) const
Definition: Player.cpp:13625
void HandleQuestPushToParty(WorldPacket &recvPacket)
Definition: Group.h:154
const uint64 & GetGUID() const
Definition: Object.h:156
bool CanCompleteRepeatableQuest(Quest const *pQuest)
Definition: Player.cpp:12848
virtual void sGossipHello(Player *)
Definition: UnitAI.h:111
void SetQuestStatus(uint32 quest_id, QuestStatus status)
Definition: Player.cpp:13673