OregonCore  revision be9e804-git
Your Favourite TBC server
GossipDef.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 <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "QuestDef.h"
19 #include "GossipDef.h"
20 #include "ObjectMgr.h"
21 #include "Opcodes.h"
22 #include "WorldPacket.h"
23 #include "WorldSession.h"
24 #include "Formulas.h"
25 
27 {
28  _menuId = 0;
29 }
30 
32 {
33  ClearMenu();
34 }
35 
36 void GossipMenu::AddMenuItem(int32 menuItemId, uint8 icon, std::string const& message, uint32 sender, uint32 action, std::string const& boxMessage, uint32 boxMoney, bool coded /*= false*/)
37 {
39 
40  // Find a free new id - script case
41  if (menuItemId == -1)
42  {
43  menuItemId = 0;
44  if (!_menuItems.empty())
45  {
46  for (GossipMenuItemContainer::const_iterator itr = _menuItems.begin(); itr != _menuItems.end(); ++itr)
47  {
48  if (int32(itr->first) > menuItemId)
49  break;
50 
51  menuItemId = itr->first + 1;
52  }
53  }
54  }
55 
56  GossipMenuItem& menuItem = _menuItems[menuItemId];
57 
58  menuItem.MenuItemIcon = icon;
59  menuItem.Message = message;
60  menuItem.IsCoded = coded;
61  menuItem.Sender = sender;
62  menuItem.OptionType = action;
63  menuItem.BoxMessage = boxMessage;
64  menuItem.BoxMoney = boxMoney;
65 }
66 
67 void GossipMenu::AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi, uint32 gossipActionScript)
68 {
69  GossipMenuItemData& itemData = _menuItemData[menuItemId];
70 
71  itemData.GossipActionMenuId = gossipActionMenuId;
72  itemData.GossipActionPoi = gossipActionPoi;
73  itemData.GossipActionScript = gossipActionScript;
74 }
75 
77 {
78  GossipMenuItemContainer::const_iterator itr = _menuItems.find(menuItemId);
79  if (itr == _menuItems.end())
80  return 0;
81 
82  return itr->second.Sender;
83 }
84 
86 {
87  GossipMenuItemContainer::const_iterator itr = _menuItems.find(menuItemId);
88  if (itr == _menuItems.end())
89  return 0;
90 
91  return itr->second.OptionType;
92 }
93 
94 bool GossipMenu::IsMenuItemCoded(uint32 menuItemId) const
95 {
96  GossipMenuItemContainer::const_iterator itr = _menuItems.find(menuItemId);
97  if (itr == _menuItems.end())
98  return false;
99 
100  return itr->second.IsCoded;
101 }
102 
104 {
105  _menuItems.clear();
106  _menuItemData.clear();
107 }
108 
109 PlayerMenu::PlayerMenu(WorldSession *session) : _session(session)
110 {
111 }
112 
114 {
115  ClearMenus();
116 }
117 
119 {
122 }
123 
124 void PlayerMenu::SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const
125 {
126  WorldPacket data(SMSG_GOSSIP_MESSAGE, 100); // guess size
127  data << uint64(objectGUID);
128  data << uint32(_gossipMenu.GetMenuId()); // new 2.4.0
129  data << uint32(titleTextId);
130  data << uint32(_gossipMenu.GetMenuItemCount()); // max count 0x20
131 
132  for (GossipMenuItemContainer::const_iterator itr = _gossipMenu.GetMenuItems().begin(); itr != _gossipMenu.GetMenuItems().end(); ++itr)
133  {
134  GossipMenuItem const& item = itr->second;
135  data << uint32(itr->first);
136  data << uint8(item.MenuItemIcon);
137  data << uint8(0); // makes pop up box password
138  data << uint32(item.BoxMoney); // money required to open menu, 2.0.3
139  data << item.Message; // text for gossip item, max 0x800
140  data << item.BoxMessage; // accept text (related to money) pop up box, 2.0.3, max 0x800
141  }
142 
143  data << uint32(_questMenu.GetMenuItemCount()); // max count 0x20
144 
145  // Store this instead of checking the Singleton every loop iteration
146  bool questLevelInTitle = sWorld.getConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS);
147 
148  for (uint32 iI = 0; iI < _questMenu.GetMenuItemCount(); ++iI)
149  {
150  QuestMenuItem const& item = _questMenu.GetItem(iI);
151  uint32 questID = item.QuestId;
152  Quest const* quest = sObjectMgr.GetQuestTemplate(questID);
153 
154  data << uint32(questID);
155  data << uint32(item.QuestIcon);
156  data << int32(quest->GetQuestLevel());
157  std::string title = quest->GetTitle();
158 
159  int locale = _session->GetSessionDbLocaleIndex();
160  if (locale >= 0)
161  if (QuestLocale const* localeData = sObjectMgr.GetQuestLocale(questID))
162  if (localeData->Title.size() > uint32(locale) && !localeData->Title[locale].empty())
163  title = localeData->Title[locale];
164 
165  if (questLevelInTitle)
166  AddQuestLevelToTitle(title, quest->GetQuestLevel());
167 
168  data << title;
169  }
170 
171  _session->SendPacket(&data);
172 }
173 
175 {
177  _session->SendPacket(&data);
178 }
179 
180 // Outdated
181 void PlayerMenu::SendPointOfInterest(float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, char* locName) const
182 {
183  WorldPacket data(SMSG_GOSSIP_POI, (4 + 4 + 4 + 4 + 4 + 10)); // guess size
184  data << Flags;
185  data << X << Y;
186  data << uint32(Icon);
187  data << uint32(Data);
188  data << locName;
189 
190  _session->SendPacket(&data);
191  //sLog.outDebug("WORLD: Sent SMSG_GOSSIP_POI");
192 }
193 
195 {
196  PointOfInterest const* poi = sObjectMgr.GetPointOfInterest(poiId);
197  if (!poi)
198  {
199  sLog.outErrorDb("Request to send non-existing POI (Id: %u), ignored.", poiId);
200  return;
201  }
202 
203  std::string iconText = poi->icon_name;
205  if (locale >= 0)
206  if (PointOfInterestLocale const *localeData = sObjectMgr.GetPointOfInterestLocale(poiId))
207  sObjectMgr.GetLocaleString(localeData->IconName, locale, iconText);
208 
209  WorldPacket data(SMSG_GOSSIP_POI, 4 + 4 + 4 + 4 + 4 + 10); // guess size
210  data << uint32(poi->flags);
211  data << float(poi->x);
212  data << float(poi->y);
213  data << uint32(poi->icon);
214  data << uint32(poi->data);
215  data << iconText;
216 
217  _session->SendPacket(&data);
218 }
219 
220 /*********************************************************/
221 /*** QUEST SYSTEM ***/
222 /*********************************************************/
223 
225 {
226  _questMenuItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use
227 }
228 
230 {
231  ClearMenu();
232 }
233 
235 {
236  if (!sObjectMgr.GetQuestTemplate(QuestId))
237  return;
238 
239  ASSERT(_questMenuItems.size() <= GOSSIP_MAX_MENU_ITEMS);
240 
241  QuestMenuItem questMenuItem;
242 
243  questMenuItem.QuestId = QuestId;
244  questMenuItem.QuestIcon = Icon;
245 
246  _questMenuItems.push_back(questMenuItem);
247 }
248 
249 bool QuestMenu::HasItem(uint32 questId) const
250 {
251  for (QuestMenuItemList::const_iterator i = _questMenuItems.begin(); i != _questMenuItems.end(); ++i)
252  if (i->QuestId == questId)
253  return true;
254 
255  return false;
256 }
257 
259 {
260  _questMenuItems.clear();
261 }
262 
263 void PlayerMenu::SendQuestGiverQuestList(QEmote eEmote, const std::string& Title, uint64 npcGUID)
264 {
265  WorldPacket data(SMSG_QUESTGIVER_QUEST_LIST, 100); // guess size
266  data << uint64(npcGUID);
267  data << Title;
268  data << uint32(eEmote._Delay); // player emote
269  data << uint32(eEmote._Emote); // NPC emote
270  data << uint8 (_questMenu.GetMenuItemCount());
271 
272  // Store this instead of checking the Singleton every loop iteration
273  bool questLevelInTitle = sWorld.getConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS);
274 
275  for (uint32 iI = 0; iI < _questMenu.GetMenuItemCount(); iI++)
276  {
277  QuestMenuItem const& qmi = _questMenu.GetItem(iI);
278 
279  uint32 questID = qmi.QuestId;
280  Quest const* pQuest = sObjectMgr.GetQuestTemplate(questID);
281 
282  std::string title = pQuest ? pQuest->GetTitle() : "";
283 
284  int loc_idx = _session->GetSessionDbLocaleIndex();
285  if (loc_idx >= 0)
286  {
287  if (QuestLocale const* ql = sObjectMgr.GetQuestLocale(questID))
288  {
289  if (ql->Title.size() > uint32(loc_idx) && !ql->Title[loc_idx].empty())
290  title = ql->Title[loc_idx];
291  }
292  }
293 
294  if (questLevelInTitle)
295  AddQuestLevelToTitle(title, pQuest->GetQuestLevel());
296 
297  data << uint32(questID);
298  data << uint32(qmi.QuestIcon);
299  data << int32(pQuest->GetQuestLevel());
300  data << title;
301  }
302  _session->SendPacket(&data);
303  DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u", GUID_LOPART(npcGUID));
304 }
305 
306 void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const
307 {
309  data << uint64(npcGUID);
310  data << uint8(questStatus);
311 
312  _session->SendPacket(&data);
313  DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u", GUID_LOPART(npcGUID), questStatus);
314 }
315 
316 void PlayerMenu::SendQuestGiverQuestDetails(Quest const *quest, uint64 npcGUID, bool activateAccept) const
317 {
318  std::string questTitle = quest->GetTitle();
319  std::string questDetails = quest->GetDetails();
320  std::string questObjectives = quest->GetObjectives();
321  std::string questEndText = quest->GetEndText();
322 
324  if (locale >= 0)
325  {
326  if (QuestLocale const* localeData = sObjectMgr.GetQuestLocale(quest->GetQuestId()))
327  {
328  if (localeData->Title.size() > uint32(locale) && !localeData->Title[locale].empty())
329  questTitle = localeData->Title[locale];
330  if (localeData->Details.size() > uint32(locale) && !localeData->Details[locale].empty())
331  questDetails = localeData->Details[locale];
332  if (localeData->Objectives.size() > uint32(locale) && !localeData->Objectives[locale].empty())
333  questObjectives = localeData->Objectives[locale];
334  if (localeData->EndText.size() > uint32(locale) && !localeData->EndText[locale].empty())
335  questEndText = localeData->EndText[locale];
336  }
337  }
338 
340  AddQuestLevelToTitle(questTitle, quest->GetQuestLevel());
341 
342  WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size
343  data << uint64(npcGUID);
344  data << uint32(quest->GetQuestId());
345  data << questTitle;
346  data << questDetails;
347  data << questObjectives;
348  data << uint32(activateAccept ? 1 : 0);
349  data << uint32(quest->GetSuggestedPlayers());
350 
352  {
353  data << uint32(0); // Rewarded chosen items hidden
354  data << uint32(0); // Rewarded items hidden
355  data << uint32(0); // Rewarded money hidden
356  }
357  else
358  {
359  data << uint32(quest->GetRewChoiceItemsCount());
360  for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
361  {
362  if (!quest->RewChoiceItemId[i])
363  continue;
364 
365  data << uint32(quest->RewChoiceItemId[i]);
366  data << uint32(quest->RewChoiceItemCount[i]);
367 
368  if (ItemTemplate const* itemTemplate = sObjectMgr.GetItemTemplate(quest->RewChoiceItemId[i]))
369  data << uint32(itemTemplate->DisplayInfoID);
370  else
371  data << uint32(0x00);
372  }
373 
374  data << uint32(quest->GetRewItemsCount());
375 
376  for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
377  {
378  if (!quest->RewItemId[i])
379  continue;
380 
381  data << uint32(quest->RewItemId[i]);
382  data << uint32(quest->RewItemCount[i]);
383 
384  if (ItemTemplate const* itemTemplate = sObjectMgr.GetItemTemplate(quest->RewItemId[i]))
385  data << uint32(itemTemplate->DisplayInfoID);
386  else
387  data << uint32(0);
388  }
389 
390  data << uint32(quest->GetRewOrReqMoney());
391  }
392 
393  // rewarded honor points. Multiply with 10 to satisfy client
395  data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
396  data << uint32(quest->GetRewSpellCast()); // casted spell
397  data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
398 
399  data << uint32(QUEST_EMOTE_COUNT);
400  for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
401  {
402  data << uint32(quest->DetailsEmote[i]);
403  data << uint32(0); // DetailsEmoteDelay
404  }
405  _session->SendPacket(&data);
406 
407  DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId());
408 }
409 
411 {
412  std::string questTitle = quest->GetTitle();
413  std::string questDetails = quest->GetDetails();
414  std::string questObjectives = quest->GetObjectives();
415  std::string questEndText = quest->GetEndText();
416  //std::string questCompletedText = quest->GetCompletedText();
417 
418  std::string questObjectiveText[QUEST_OBJECTIVES_COUNT];
419  for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
420  questObjectiveText[i] = quest->ObjectiveText[i];
421 
423  if (locale >= 0)
424  {
425  if (QuestLocale const* localeData = sObjectMgr.GetQuestLocale(quest->GetQuestId()))
426  {
427  if (localeData->Title.size() > uint32(locale) && !localeData->Title[locale].empty())
428  questTitle = localeData->Title[locale];
429  if (localeData->Details.size() > uint32(locale) && !localeData->Details[locale].empty())
430  questDetails = localeData->Details[locale];
431  if (localeData->Objectives.size() > uint32(locale) && !localeData->Objectives[locale].empty())
432  questObjectives = localeData->Objectives[locale];
433  if (localeData->EndText.size() > uint32(locale) && !localeData->EndText[locale].empty())
434  questEndText = localeData->EndText[locale];
435 
436  for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
437  if (localeData->ObjectiveText[i].size() > locale && !localeData->ObjectiveText[i][locale].empty())
438  questObjectiveText[i] = localeData->ObjectiveText[i][locale];
439  }
440  }
441 
442  WorldPacket data(SMSG_QUEST_QUERY_RESPONSE, 100); // guess size
443 
444  data << uint32(quest->GetQuestId()); // quest id
445  data << uint32(quest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0 == IsAutoComplete() (skip objectives/details)
446  data << int32(quest->GetQuestLevel()); // may be 0, -1, static data, in other cases must be used dynamic level: Player::GetQuestLevelForPlayer
447  data << uint32(quest->GetZoneOrSort()); // zone or sort to display in quest log
448 
449  data << uint32(quest->GetType()); // quest type
450  data << uint32(quest->GetSuggestedPlayers()); // suggested players count
451 
452  data << uint32(quest->GetRepObjectiveFaction()); // shown in quest log as part of quest objective
453  data << uint32(quest->GetRepObjectiveValue()); // shown in quest log as part of quest objective
454 
455  data << uint32(0); // RequiredOpositeRepFaction
456  data << uint32(0); // RequiredOpositeRepValue, required faction value with another (oposite) faction (objective)
457 
458  data << uint32(quest->GetNextQuestInChain()); // client will request this quest from NPC, if not 0
459 
461  data << uint32(0); // Hide money rewarded
462  else
463  data << uint32(quest->GetRewOrReqMoney()); // reward money (below max lvl)
464 
465  data << uint32(quest->GetRewMoneyMaxLevel()); // used in XP calculation at client
466  data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
467  data << uint32(quest->GetRewSpellCast()); // casted spell
468 
469  // rewarded honor points
471  data << uint32(quest->GetSrcItemId());
472  data << uint32(quest->GetFlags() & 0xFFFF);
473  data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
474 
476  {
477  for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
478  data << uint32(0) << uint32(0);
479  for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
480  data << uint32(0) << uint32(0);
481  }
482  else
483  {
484  for (uint32 i = 0; i < QUEST_REWARDS_COUNT; ++i)
485  {
486  data << uint32(quest->RewItemId[i]);
487  data << uint32(quest->RewItemCount[i]);
488  }
489  for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
490  {
491  data << uint32(quest->RewChoiceItemId[i]);
492  data << uint32(quest->RewChoiceItemCount[i]);
493  }
494  }
495 
496  data << quest->GetPointMapId();
497  data << quest->GetPointX();
498  data << quest->GetPointY();
499  data << quest->GetPointOpt();
500 
501  data << questTitle;
502  data << questObjectives;
503  data << questDetails;
504  data << questEndText;
505 
506  for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
507  {
508  if (quest->ReqCreatureOrGOId[i] < 0)
509  data << uint32((quest->ReqCreatureOrGOId[i] * (-1)) | 0x80000000); // client expects gameobject template id in form (id|0x80000000)
510  else
511  data << uint32(quest->ReqCreatureOrGOId[i]);
512 
513  data << uint32(quest->ReqCreatureOrGOCount[i]);
514  data << uint32(quest->RequiredItemId[i]);
515  data << uint32(quest->ReqItemCount[i]);
516  }
517 
518  for (uint32 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
519  data << questObjectiveText[i];
520 
521  _session->SendPacket(&data);
522  DEBUG_LOG("WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", quest->GetQuestId());
523 }
524 
525 void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, bool enableNext) const
526 {
527  std::string questTitle = quest->GetTitle();
528  std::string questOfferRewardText = quest->GetOfferRewardText();
529 
530  int locale = _session->GetSessionDbLocaleIndex();
531  if (locale >= 0)
532  {
533  if (QuestLocale const* localeData = sObjectMgr.GetQuestLocale(quest->GetQuestId()))
534  {
535  if (localeData->Title.size() > uint32(locale) && !localeData->Title[locale].empty())
536  questTitle = localeData->Title[locale];
537  if (localeData->OfferRewardText.size() > uint32(locale) && !localeData->OfferRewardText[locale].empty())
538  questOfferRewardText = localeData->OfferRewardText[locale];
539  }
540  }
541 
542  WorldPacket data(SMSG_QUESTGIVER_OFFER_REWARD, 50); // guess size
543 
544  data << uint64(npcGUID);
545  data << uint32(quest->GetQuestId());
546  data << questTitle;
547  data << questOfferRewardText;
548 
549  data << uint32(enableNext ? 1 : 0);
550  data << uint32(0); // unk
551 
552  uint32 emoteCount = 0;
553  for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
554  {
555  if (quest->OfferRewardEmote[i] <= 0)
556  break;
557  ++emoteCount;
558  }
559 
560  data << emoteCount; // Emote Count
561  for (uint32 i = 0; i < emoteCount; ++i)
562  {
563  data << uint32(0); // Delay Emote
564  data << uint32(quest->OfferRewardEmote[i]);
565  }
566 
567  data << uint32(quest->GetRewChoiceItemsCount());
568  for (uint32 i = 0; i < quest->GetRewChoiceItemsCount(); ++i)
569  {
570  data << uint32(quest->RewChoiceItemId[i]);
571  data << uint32(quest->RewChoiceItemCount[i]);
572 
573  if (ItemTemplate const* itemTemplate = sObjectMgr.GetItemTemplate(quest->RewChoiceItemId[i]))
574  data << uint32(itemTemplate->DisplayInfoID);
575  else
576  data << uint32(0);
577  }
578 
579  data << uint32(quest->GetRewItemsCount());
580  for (uint32 i = 0; i < quest->GetRewItemsCount(); ++i)
581  {
582  data << uint32(quest->RewItemId[i]);
583  data << uint32(quest->RewItemCount[i]);
584 
585  if (ItemTemplate const* itemTemplate = sObjectMgr.GetItemTemplate(quest->RewItemId[i]))
586  data << uint32(itemTemplate->DisplayInfoID);
587  else
588  data << uint32(0);
589  }
590 
591  data << uint32(quest->GetRewOrReqMoney());
592 
593  // rewarded honor points. Multiply with 10 to satisfy client
595  data << uint32(0x08); // unused by client?
596  data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
597  data << uint32(quest->GetRewSpellCast()); // casted spell
598  data << uint32(0); // unknown
599  _session->SendPacket(&data);
600  sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId());
601 }
602 
603 void PlayerMenu::SendQuestGiverRequestItems(Quest const *quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const
604 {
605  // We can always call to RequestItems, but this packet only goes out if there are actually
606  // items. Otherwise, we'll skip straight to the OfferReward
607 
608  std::string questTitle = quest->GetTitle();
609  std::string requestItemsText = quest->GetRequestItemsText();
610 
612  if (locale >= 0)
613  {
614  if (QuestLocale const* localeData = sObjectMgr.GetQuestLocale(quest->GetQuestId()))
615  {
616  if (localeData->Title.size() > uint32(locale) && !localeData->Title[locale].empty())
617  questTitle = localeData->Title[locale];
618  if (localeData->RequestItemsText.size() > uint32(locale) && !localeData->RequestItemsText[locale].empty())
619  requestItemsText = localeData->RequestItemsText[locale];
620  }
621  }
622 
623  // We may wish a better check, perhaps checking the real quest requirements
624  if (quest->GetRequestItemsText().empty() && canComplete)
625  {
626  SendQuestGiverOfferReward(quest, npcGUID, true);
627  return;
628  }
629 
631  AddQuestLevelToTitle(questTitle, quest->GetQuestLevel());
632 
633  WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 50); // guess size
634  data << uint64(npcGUID);
635  data << uint32(quest->GetQuestId());
636  data << questTitle;
637  data << requestItemsText;
638 
639  data << uint32(0x00); // unknown
640 
641  if (canComplete)
642  data << quest->GetCompleteEmote();
643  else
644  data << quest->GetIncompleteEmote();
645 
646  // Close Window after cancel
647  if (closeOnCancel)
648  data << uint32(0x01);
649  else
650  data << uint32(0x00);
651 
652  data << uint32(0x00); // unknown
653 
654  // Required Money
655  data << uint32(quest->GetRewOrReqMoney() < 0 ? -quest->GetRewOrReqMoney() : 0);
656 
657  data << uint32(quest->GetReqItemsCount());
658 
659  for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
660  {
661  if (!quest->RequiredItemId[i])
662  continue;
663 
664  data << uint32(quest->RequiredItemId[i]);
665  data << uint32(quest->ReqItemCount[i]);
666 
667  if (ItemTemplate const* itemTemplate = sObjectMgr.GetItemTemplate(quest->RequiredItemId[i]))
668  data << uint32(itemTemplate->DisplayInfoID);
669  else
670  data << uint32(0);
671  }
672 
673  if (!canComplete)
674  data << uint32(0x00);
675  else
676  data << uint32(0x03);
677 
678  data << uint32(0x04);
679  data << uint32(0x08);
680  data << uint32(0x10);
681 
682  _session->SendPacket(&data);
683  sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId());
684 }
685 
686 void PlayerMenu::AddQuestLevelToTitle(std::string& title, int32 level)
687 {
688  // Adds the quest level to the front of the quest title
689  // example: [13] Westfall Stew
690 
691  std::stringstream questTitlePretty;
692  questTitlePretty << "[" << level << "] " << title;
693  title = questTitlePretty.str();
694 }
695 
uint32 RequiredItemId[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:385
uint32 GetRewChoiceItemsCount() const
Definition: QuestDef.h:403
std::string BoxMessage
Definition: GossipDef.h:123
uint32 OptionType
Definition: GossipDef.h:122
void SendPointOfInterest(float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, char *locName) const
Definition: GossipDef.cpp:181
GossipMenuItemDataContainer _menuItemData
Definition: GossipDef.h:202
#define GUID_LOPART(x)
Definition: ObjectGuid.h:110
std::string GetTitle() const
Definition: QuestDef.h:285
uint32 DetailsEmote[QUEST_EMOTE_COUNT]
Definition: QuestDef.h:398
uint32 GetSuggestedPlayers() const
Definition: QuestDef.h:245
void ClearMenus()
Definition: GossipDef.cpp:118
uint32 GetIncompleteEmote() const
Definition: QuestDef.h:351
uint32 GetMenuItemAction(uint32 menuItemId) const
Definition: GossipDef.cpp:85
uint32 GossipActionMenuId
Definition: GossipDef.h:132
int32 GetZoneOrSort() const
Definition: QuestDef.h:189
static void AddQuestLevelToTitle(std::string &title, int32 level)
Definition: GossipDef.cpp:686
uint32 GetRewItemsCount() const
Definition: QuestDef.h:404
#define QUEST_EMOTE_COUNT
Definition: QuestDef.h:39
uint32 GetFlags() const
Definition: QuestDef.h:374
uint32 GossipActionPoi
Definition: GossipDef.h:133
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:389
uint32 GetPointMapId() const
Definition: QuestDef.h:335
uint32 GetNextQuestInChain() const
Definition: QuestDef.h:265
std::string GetEndText() const
Definition: QuestDef.h:305
#define sLog
Log class singleton.
Definition: Log.h:187
ACE_INT32 int32
Definition: Define.h:67
int32 GetRepObjectiveValue() const
Definition: QuestDef.h:225
void SendGossipMenu(uint32 titleTextId, uint64 objectGUID) const
Definition: GossipDef.cpp:124
float GetPointY() const
Definition: QuestDef.h:343
uint32 GossipActionScript
Definition: GossipDef.h:134
Player * GetPlayer() const
Definition: WorldSession.h:104
void AddMenuItem(uint32 QuestId, uint8 Icon)
Definition: GossipDef.cpp:234
uint8 MenuItemIcon
Definition: GossipDef.h:118
#define sObjectMgr
Definition: ObjectMgr.h:1317
void SendPacket(WorldPacket const *packet)
uint32 GetRewHonorableKills() const
Definition: QuestDef.h:310
void AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi, uint32 gossipActionScript)
Definition: GossipDef.cpp:67
uint32 GetCharTitleId() const
Definition: QuestDef.h:269
uint32 GetMenuItemCount() const
Definition: GossipDef.h:161
uint8 getLevel() const
Definition: Unit.h:1057
std::string GetObjectives() const
Definition: QuestDef.h:293
PlayerMenu(WorldSession *session)
Definition: GossipDef.cpp:109
void SendQuestGiverQuestDetails(Quest const *quest, uint64 npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:316
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:384
std::string GetRequestItemsText() const
Definition: QuestDef.h:301
uint32 GetSrcItemId() const
Definition: QuestDef.h:273
ACE_UINT8 uint8
Definition: Define.h:73
uint32 _menuId
Definition: GossipDef.h:203
void SendQuestGiverRequestItems(Quest const *quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const
Definition: GossipDef.cpp:603
uint32 GetQuestId() const
Definition: QuestDef.h:186
uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT]
Definition: QuestDef.h:393
uint32 Sender
Definition: GossipDef.h:121
QuestMenu _questMenu
Definition: GossipDef.h:274
GossipMenuItemContainer _menuItems
Definition: GossipDef.h:201
bool IsMenuItemCoded(uint32 menuItemId) const
Definition: GossipDef.cpp:94
void SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const
Definition: GossipDef.cpp:306
uint32 GetCompleteEmote() const
Definition: QuestDef.h:355
uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT]
Definition: QuestDef.h:392
GossipMenuItemContainer const & GetMenuItems() const
Definition: GossipDef.h:195
#define DEBUG_LOG(...)
Definition: Log.h:194
uint32 GetMenuItemSender(uint32 menuItemId) const
Definition: GossipDef.cpp:76
void SendCloseGossip() const
Definition: GossipDef.cpp:174
uint32 GetRewSpell() const
Definition: QuestDef.h:319
float GetPointX() const
Definition: QuestDef.h:339
void AddMenuItem(int32 menuItemId, uint8 icon, std::string const &message, uint32 sender, uint32 action, std::string const &boxMessage, uint32 boxMoney, bool coded=false)
Definition: GossipDef.cpp:36
void SendQuestGiverQuestList(QEmote eEmote, const std::string &Title, uint64 npcGUID)
Definition: GossipDef.cpp:263
uint32 GetQuestMethod() const
Definition: QuestDef.h:187
uint32 GetReqItemsCount() const
Definition: QuestDef.h:401
uint32 GetType() const
Definition: QuestDef.h:201
uint32 GetRewSpellCast() const
Definition: QuestDef.h:323
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:386
ACE_UINT64 uint64
Definition: Define.h:70
uint8 QuestIcon
Definition: GossipDef.h:143
void ClearMenu()
Definition: GossipDef.cpp:103
std::string GetDetails() const
Definition: QuestDef.h:289
int GetSessionDbLocaleIndex() const
Definition: WorldSession.h:237
uint32 _Delay
Definition: NPCHandler.h:46
uint32 hk_honor_at_level(uint32 level, uint32 count=1)
Definition: Formulas.h:27
int32 GetRewOrReqMoney() const
Definition: QuestDef.cpp:190
#define QUEST_REWARD_CHOICES_COUNT
Definition: QuestDef.h:35
bool HasItem(uint32 questId) const
Definition: GossipDef.cpp:249
bool HasFlag(uint32 flag) const
Definition: QuestDef.h:179
void SendQuestGiverOfferReward(Quest const *quest, uint64 npcGUID, bool enableNext) const
Definition: GossipDef.cpp:525
std::string GetOfferRewardText() const
Definition: QuestDef.h:297
#define GOSSIP_MAX_MENU_ITEMS
Definition: GossipDef.h:27
#define QUEST_REWARDS_COUNT
Definition: QuestDef.h:36
WorldSession * _session
Definition: GossipDef.h:275
#define ASSERT
Definition: Errors.h:29
GossipMenu _gossipMenu
Definition: GossipDef.h:273
uint32 GetRepObjectiveFaction() const
Definition: QuestDef.h:221
uint32 RewItemId[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:394
uint32 _Emote
Definition: NPCHandler.h:45
uint32 RewItemCount[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:395
#define sWorld
Definition: World.h:860
int32 GetQuestLevel() const
Definition: QuestDef.h:197
uint32 QuestId
Definition: GossipDef.h:142
std::string Message
Definition: GossipDef.h:120
ACE_UINT32 uint32
Definition: Define.h:71
uint32 GetPointOpt() const
Definition: QuestDef.h:347
uint32 GetMenuId() const
Definition: GossipDef.h:157
std::string icon_name
Definition: ObjectMgr.h:431
QuestMenuItem const & GetItem(uint16 index) const
Definition: GossipDef.h:227
void SendQuestQueryResponse(Quest const *quest) const
Definition: GossipDef.cpp:410
#define QUEST_OBJECTIVES_COUNT
Definition: QuestDef.h:33
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT]
Definition: QuestDef.h:390
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT]
Definition: QuestDef.h:399
uint32 GetRewMoneyMaxLevel() const
Definition: QuestDef.h:314
void ClearMenu()
Definition: GossipDef.cpp:258
uint8 GetMenuItemCount() const
Definition: GossipDef.h:215
uint32 BoxMoney
Definition: GossipDef.h:124