void PlayerMenu::SendQuestGiverRequestItems(Quest const *pQuest, ObjectGuid npcGUID, bool Completable, bool CloseOnCancel) { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string Title = pQuest->GetTitle(); std::string RequestItemsText = pQuest->GetRequestItemsText(); int loc_idx = GetMenuSession()->GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (QuestLocale const *ql = sObjectMgr.GetQuestLocale(pQuest->GetQuestId())) { if (ql->Title.size() > (size_t)loc_idx && !ql->Title[loc_idx].empty()) Title = ql->Title[loc_idx]; if (ql->RequestItemsText.size() > (size_t)loc_idx && !ql->RequestItemsText[loc_idx].empty()) RequestItemsText = ql->RequestItemsText[loc_idx]; } } if (!pQuest->GetReqItemsCount() && Completable) { SendQuestGiverOfferReward(pQuest, npcGUID, true); return; } WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 ); // guess size data << ObjectGuid(npcGUID); data << uint32(pQuest->GetQuestId()); data << Title; data << RequestItemsText; data << uint32(0x00); // emote delay if(Completable) data << pQuest->GetCompleteEmote(); // emote id else data << pQuest->GetIncompleteEmote(); // Close Window after cancel if (CloseOnCancel) data << uint32(0x01); // auto finish else data << uint32(0x00); data << uint32(pQuest->GetQuestFlags()); // 3.3.3 questFlags data << uint32(pQuest->GetSuggestedPlayers()); // SuggestedGroupNum // Required Money data << uint32(pQuest->GetRewOrReqMoney() < 0 ? -pQuest->GetRewOrReqMoney() : 0); data << uint32( pQuest->GetReqItemsCount() ); ItemPrototype const *pItem; for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if ( !pQuest->ReqItemId[i] ) continue; pItem = ObjectMgr::GetItemPrototype(pQuest->ReqItemId[i]); data << uint32(pQuest->ReqItemId[i]); data << uint32(pQuest->ReqItemCount[i]); if ( pItem ) data << uint32(pItem->DisplayInfoID); else data << uint32(0); } data << uint32(QUEST_EMOTE_COUNT); for (uint8 i = 0; i < QUEST_EMOTE_COUNT; ++i) { data << uint32(pQuest->DetailsEmote[i]); data << uint32(pQuest->DetailsEmoteDelay[i]); } if ( !Completable ) // Completable = flags1 && flags2 && flags3 && flags4 data << uint32(0x00); // flags1 else data << uint32(0x03); data << uint32(0x04); // flags2 data << uint32(0x08); // flags3 data << uint32(0x10); // flags4 data << uint32(0x20); // flags5 GetMenuSession()->SendPacket( &data ); DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid = %s, questid = %u", npcGUID.GetString().c_str(), pQuest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel) { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string Title = pQuest->GetTitle(); std::string RequestItemsText = pQuest->GetRequestItemsText(); int loc_idx = pSession->GetSessionDbLocaleIndex(); if (loc_idx >= 0) { if (QuestLocale const *ql = sObjectMgr->GetQuestLocale(pQuest->GetQuestId())) { sObjectMgr->GetLocaleString(ql->Title, loc_idx, Title); sObjectMgr->GetLocaleString(ql->RequestItemsText, loc_idx, RequestItemsText); } } if (!pQuest->GetReqItemsCount() && Completable) { SendQuestGiverOfferReward(pQuest, npcGUID, true); return; } WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 50); // guess size data << uint64(npcGUID); data << uint32(pQuest->GetQuestId()); data << Title; data << RequestItemsText; data << uint32(0x00); // unknown if (Completable) data << pQuest->GetCompleteEmote(); else data << pQuest->GetIncompleteEmote(); // Close Window after cancel if (CloseOnCancel) data << uint32(0x01); else data << uint32(0x00); data << uint32(pQuest->GetQuestFlags()); // 3.3.3 questFlags data << uint32(pQuest->GetSuggestedPlayers()); // SuggestedGroupNum // Required Money data << uint32(pQuest->GetRewOrReqMoney() < 0 ? -pQuest->GetRewOrReqMoney() : 0); data << uint32(pQuest->GetReqItemsCount()); ItemPrototype const *pItem; for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (!pQuest->ReqItemId[i]) continue; pItem = ObjectMgr::GetItemPrototype(pQuest->ReqItemId[i]); data << uint32(pQuest->ReqItemId[i]); data << uint32(pQuest->ReqItemCount[i]); if (pItem) data << uint32(pItem->DisplayInfoID); else data << uint32(0); } // Added in 4.0.1 uint32 counter = 0; data << counter; for(uint32 i = 0; i < counter; i++) { data << uint32(0); data << uint32(0); } if (!Completable) data << uint32(0x00); else data << uint32(0x02); data << uint32(0x04); data << uint32(0x08); data << uint32(0x10); data << uint32(0x40); // added in 4.0.1 pSession->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward if (!quest->GetReqItemsCount() && canComplete) { SendQuestGiverOfferReward(quest, npcGUID, true); return; } // Xinef: recheck completion on reward display Player* _player = _session->GetPlayer(); QuestStatusMap::iterator qsitr = _player->getQuestStatusMap().find(quest->GetQuestId()); if (qsitr != _player->getQuestStatusMap().end() && qsitr->second.Status == QUEST_STATUS_INCOMPLETE) { for (uint8 i=0; i<6; ++i) if (quest->RequiredItemId[i] && qsitr->second.ItemCount[i] < quest->RequiredItemCount[i]) if (_player->GetItemCount(quest->RequiredItemId[i], false) >= quest->RequiredItemCount[i]) qsitr->second.ItemCount[i] = quest->RequiredItemCount[i]; if (_player->CanCompleteQuest(quest->GetQuestId())) { _player->CompleteQuest(quest->GetQuestId()); canComplete = true; } } WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 300); // guess size data << uint64(npcGUID); data << uint32(quest->GetQuestId()); data << quest->GetTitle(); data << quest->GetRequestItemsText(); data << uint32(0x00); // unknown if (canComplete) data << quest->GetCompleteEmote(); else data << quest->GetIncompleteEmote(); // Close Window after cancel if (closeOnCancel) data << uint32(0x01); else data << uint32(0x00); data << uint32(quest->GetFlags()); // 3.3.3 questFlags data << uint32(quest->GetSuggestedPlayers()); // SuggestedGroupNum // Required Money data << uint32(quest->GetRewOrReqMoney() < 0 ? -quest->GetRewOrReqMoney() : 0); data << uint32(quest->GetReqItemsCount()); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (!quest->RequiredItemId[i]) continue; data << uint32(quest->RequiredItemId[i]); data << uint32(quest->RequiredItemCount[i]); if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i])) data << uint32(itemTemplate->DisplayInfoID); else data << uint32(0); } if (!canComplete) data << uint32(0x00); else data << uint32(0x03); data << uint32(0x04); data << uint32(0x08); data << uint32(0x10); _session->SendPacket(&data); ;//sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel ) { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string Title = pQuest->GetTitle(); std::string RequestItemsText = pQuest->GetRequestItemsText(); int loc_idx = pSession->GetSessionDbLocaleIndex(); if (loc_idx >= 0) { QuestLocale const *ql = objmgr.GetQuestLocale(pQuest->GetQuestId()); if (ql) { if (ql->Title.size() > loc_idx && !ql->Title[loc_idx].empty()) Title=ql->Title[loc_idx]; if (ql->RequestItemsText.size() > loc_idx && !ql->RequestItemsText[loc_idx].empty()) RequestItemsText=ql->RequestItemsText[loc_idx]; } } if (!pQuest->GetReqItemsCount() && Completable) { SendQuestGiverOfferReward(pQuest, npcGUID, true); return; } WorldPacket data( SMSG_QUESTGIVER_REQUEST_ITEMS, 50 ); // guess size data << npcGUID; data << pQuest->GetQuestId(); data << Title; data << RequestItemsText; data << uint32(0x00); // unknown if(Completable) data << pQuest->GetCompleteEmote(); else data << pQuest->GetIncompleteEmote(); // Close Window after cancel if (CloseOnCancel) data << uint32(0x01); else data << uint32(0x00); data << uint32(0x00); // unknown // Required Money data << uint32(pQuest->GetRewOrReqMoney() < 0 ? -pQuest->GetRewOrReqMoney() : 0); data << uint32( pQuest->GetReqItemsCount() ); ItemPrototype const *pItem; for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) { if ( !pQuest->ReqItemId[i] ) continue; pItem = objmgr.GetItemPrototype(pQuest->ReqItemId[i]); data << uint32(pQuest->ReqItemId[i]); data << uint32(pQuest->ReqItemCount[i]); if ( pItem ) data << uint32(pItem->DisplayInfoID); else data << uint32(0); } if ( !Completable ) data << uint32(0x00); else data << uint32(0x03); data << uint32(0x04); data << uint32(0x08); data << uint32(0x10); pSession->SendPacket( &data ); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() ); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } if (!quest->GetReqItemsCount() && canComplete) { SendQuestGiverOfferReward(quest, npcGUID, true); return; } WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 50); // guess size data << uint64(npcGUID); data << uint32(quest->GetQuestId()); data << questTitle; data << requestItemsText; data << uint32(0x00); // unknown if (canComplete) data << quest->GetCompleteEmote(); else data << quest->GetIncompleteEmote(); // Close Window after cancel if (closeOnCancel) data << uint32(0x01); else data << uint32(0x00); data << uint32(quest->GetFlags()); // 3.3.3 questFlags data << uint32(quest->GetSuggestedPlayers()); // SuggestedGroupNum // Required Money data << uint32(quest->GetRewOrReqMoney() < 0 ? -quest->GetRewOrReqMoney() : 0); data << uint32(quest->GetReqItemsCount()); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (!quest->RequiredItemId[i]) continue; data << uint32(quest->RequiredItemId[i]); data << uint32(quest->RequiredItemCount[i]); if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i])) data << uint32(itemTemplate->DisplayInfoID); else data << uint32(0); } if (!canComplete) data << uint32(0x00); else data << uint32(0x03); data << uint32(0x04); data << uint32(0x08); data << uint32(0x10); _session->SendPacket(&data); sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); uint32 itemCount = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_ITEM); uint32 currencyCount = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_CURRENCY); uint32 moneyCount = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_MONEY); if (!itemCount && !currencyCount && !moneyCount && canComplete) { SendQuestGiverOfferReward(quest, npcGUID, true); return; } int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } uint32 requiredMoney = 0; ByteBuffer currencyData, itemData; for (const auto &questObjective : quest->m_questObjectives) { switch (questObjective->Type) { case QUEST_OBJECTIVE_TYPE_ITEM: { if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(questObjective->ObjectId)) itemData << uint32(itemTemplate->DisplayInfoID); else itemData << uint32(0); itemData << uint32(questObjective->Amount); itemData << uint32(questObjective->ObjectId); break; } case QUEST_OBJECTIVE_TYPE_CURRENCY: { currencyData << uint32(questObjective->Amount); currencyData << uint32(questObjective->ObjectId); break; } case QUEST_OBJECTIVE_TYPE_MONEY: { requiredMoney = questObjective->Amount; break; } default: break; } } ObjectGuid guid = npcGUID; WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1 + 8 + 8 + questTitle.size() + requestItemsText.size() + itemCount * (4 + 4 + 4) + currencyCount * (4 + 4)); data << uint32(0); data << uint32(canComplete ? quest->GetCompleteEmote() : quest->GetIncompleteEmote()); data << uint32(quest->GetFlags()); data << uint32(quest->GetQuestId()); data << uint32(GUID_ENPART(npcGUID)); data << uint32(requiredMoney); data << uint32(0); data << uint32(canComplete ? 0x5F : 0x5B); // status flags data << uint32(0); data.WriteBit(closeOnCancel); data.WriteBitSeq<5, 1, 0>(guid); data.WriteBits(requestItemsText.size(), 12); data.WriteBitSeq<4>(guid); data.WriteBits(currencyCount, 21); data.WriteBits(itemCount, 20); data.WriteBitSeq<3, 2, 6, 7>(guid); data.WriteBits(questTitle.size(), 9); data.FlushBits(); data.WriteByteSeq<6>(guid); data.append(itemData); data.WriteString(questTitle); data.append(currencyData); data.WriteByteSeq<4>(guid); data.WriteString(requestItemsText); data.WriteByteSeq<0, 7, 2, 5, 1, 3>(guid); _session->SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } if (!quest->GetReqItemsCount() && canComplete) { SendQuestGiverOfferReward(quest, npcGUID, true); return; } if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 50); // guess size data << uint64(npcGUID); data << uint32(quest->GetQuestId()); data << questTitle; data << requestItemsText; data << uint32(0); // unknown if (canComplete) data << quest->GetCompleteEmote(); else data << quest->GetIncompleteEmote(); // Close Window after cancel data << uint32(closeOnCancel); data << uint32(quest->GetFlags()); // 3.3.3 questFlags data << uint32(quest->GetSuggestedPlayers()); // SuggestedGroupNum // Required Money data << uint32(quest->GetRewOrReqMoney() < 0 ? -quest->GetRewOrReqMoney() : 0); data << uint32(quest->GetReqItemsCount()); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (!quest->RequiredItemId[i]) continue; data << uint32(quest->RequiredItemId[i]); data << uint32(quest->RequiredItemCount[i]); if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i])) data << uint32(itemTemplate->DisplayInfoID); else data << uint32(0); } data << uint32(quest->GetReqCurrencyCount()); for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) { if (!quest->RequiredCurrencyId[i]) continue; data << uint32(quest->RequiredCurrencyId[i]); data << uint32(quest->RequiredCurrencyCount[i]); } if (!canComplete) // Experimental; there are 6 similar flags, if any of them data << uint32(0x00); // of them is 0 player can't complete quest (still unknown meaning) else data << uint32(0x02); data << uint32(0x04); data << uint32(0x08); data << uint32(0x10); data << uint32(0x40); _session->SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string questTitle = quest->GetLogTitle(); std::string requestItemsText = quest->GetRequestItemsText(); LocaleConstant locale = _session->GetSessionDbLocaleIndex(); if (locale >= LOCALE_enUS) { if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(questTemplateLocale->LogTitle, locale, questTitle); ObjectMgr::GetLocaleString(questTemplateLocale->RequestItemsText, locale, requestItemsText); } } if (!quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER) && canComplete) { SendQuestGiverOfferReward(quest, npcGUID, true); return; } if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); WorldPackets::Quest::QuestGiverRequestItems packet; packet.QuestGiverGUID = npcGUID; // Is there a better way? what about game objects? if (Creature const* creature = ObjectAccessor::GetCreature(*_session->GetPlayer(), npcGUID)) packet.QuestGiverCreatureID = creature->GetCreatureTemplate()->Entry; packet.QuestID = quest->GetQuestId(); if (canComplete) { packet.CompEmoteDelay = quest->EmoteOnCompleteDelay; packet.CompEmoteType = quest->EmoteOnComplete; } else { packet.CompEmoteDelay = quest->EmoteOnIncompleteDelay; packet.CompEmoteType = quest->EmoteOnIncomplete; } packet.QuestFlags[0] = quest->GetFlags(); packet.QuestFlags[1] = quest->GetFlagsEx(); packet.SuggestPartyMembers = quest->GetSuggestedPlayers(); packet.StatusFlags = 0xDF; // Unk, send common value packet.MoneyToGet = 0; for (QuestObjective const& obj : quest->GetObjectives()) { switch (obj.Type) { case QUEST_OBJECTIVE_ITEM: packet.Collect.push_back(WorldPackets::Quest::QuestObjectiveCollect(obj.ObjectID, obj.Amount, obj.Flags)); break; case QUEST_OBJECTIVE_CURRENCY: packet.Currency.push_back(WorldPackets::Quest::QuestCurrency(obj.ObjectID, obj.Amount)); break; case QUEST_OBJECTIVE_MONEY: packet.MoneyToGet += obj.Amount; break; default: break; } } packet.AutoLaunched = closeOnCancel; packet.QuestTitle = questTitle; packet.CompletionText = requestItemsText; _session->SendPacket(packet.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPC=%s, questid=%u", npcGUID.ToString().c_str(), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGuid, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward uint32 itemCounter = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_ITEM); if (!itemCounter && canComplete) { SendQuestGiverOfferReward(quest, npcGuid, true); return; } std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } uint32 requiredMoney = 0; ByteBuffer currencyData, itemData; for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); citr++) { QuestObjective const* questObjective = *citr; switch (questObjective->Type) { case QUEST_OBJECTIVE_TYPE_ITEM: { if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(questObjective->ObjectId)) itemData << uint32(itemTemplate->DisplayInfoID); else itemData << uint32(0); itemData << uint32(questObjective->ObjectId); itemData << uint32(questObjective->Amount); break; } case QUEST_OBJECTIVE_TYPE_CURRENCY: { currencyData << uint32(questObjective->ObjectId); currencyData << uint32(questObjective->Amount); break; } case QUEST_OBJECTIVE_TYPE_MONEY: { requiredMoney = questObjective->Amount; break; } default: break; } } if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); ObjectGuid guid = npcGuid; uint32 currencyCounter = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_CURRENCY); WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1 + 8 + 8 + questTitle.size() + requestItemsText.size() + itemCounter * (4 + 4 + 4) + currencyCounter * (4 + 4)); data << uint32(0); data << uint32(quest->GetFlags()); data << uint32(0); data << uint32(canComplete ? 0x5F : 0x5B); // status flags data << uint32(requiredMoney); data << uint32(0); // quest starter NPC/GO entry data << uint32(0); data << uint32(canComplete ? quest->GetCompleteEmote() : quest->GetIncompleteEmote()); data << uint32(quest->GetQuestId()); /* * TODO: Quest System * * Finish structure, missing values: * Flags2, SuggestPartyMembers, EmoteDelay * * Research StatusFlags: * 0x5B = 0x01 + 0x02 + 0x08 + 0x10 + 0x40 * 0x5F = 0x01 + 0x02 + 0x04 + 0x08 + 0x10 + 0x40 */ data.WriteBits(currencyCounter, 21); data.WriteBit(closeOnCancel); data.WriteBit(guid[2]); data.WriteBit(guid[5]); data.WriteBit(guid[1]); data.WriteBits(questTitle.size(), 9); data.WriteBits(requestItemsText.size(), 12); data.WriteBit(guid[6]); data.WriteBit(guid[0]); data.WriteBits(itemCounter, 20); data.WriteBit(guid[4]); data.WriteBit(guid[7]); data.WriteBit(guid[3]); data.FlushBits(); data.WriteByteSeq(guid[0]); data.WriteByteSeq(guid[2]); data.WriteString(questTitle); data.append(currencyData); data.append(itemData); data.WriteByteSeq(guid[3]); data.WriteByteSeq(guid[1]); data.WriteString(requestItemsText); data.WriteByteSeq(guid[4]); data.WriteByteSeq(guid[5]); data.WriteByteSeq(guid[7]); data.WriteByteSeq(guid[6]); _session->SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGuid), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } if (!quest->GetReqItemsCount() && canComplete) { SendQuestGiverOfferReward(quest, npcGUID, true); return; } if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); ObjectGuid guid = npcGUID; WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 50); // guess size data << uint32(0); data << uint32(quest->GetFlags()); data << uint32(0); data << uint32(canComplete ? 0x5F : 0x5B); // unknown, if not 5F continue button is greyed out data << uint32(quest->GetRewOrReqMoney() < 0 ? -quest->GetRewOrReqMoney() : 0); data << uint32(0); // quest starter NPC/GO entry data << uint32(0); data << uint32(canComplete ? quest->GetCompleteEmote() : quest->GetIncompleteEmote()); data << uint32(quest->GetQuestId()); data.WriteBits(quest->GetReqCurrencyCount(), 21); data.WriteBit(closeOnCancel); data.WriteBit(guid[2]); data.WriteBit(guid[5]); data.WriteBit(guid[1]); data.WriteBits(questTitle.size(), 9); data.WriteBits(requestItemsText.size(), 12); data.WriteBit(guid[6]); data.WriteBit(guid[0]); data.WriteBits(quest->GetReqItemsCount(), 20); data.WriteBit(guid[4]); data.WriteBit(guid[7]); data.WriteBit(guid[3]); data.FlushBits(); data.WriteByteSeq(guid[0]); data.WriteByteSeq(guid[2]); data.WriteString(questTitle); for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; i++) { if (!quest->RequiredCurrencyId[i]) continue; data << uint32(quest->RequiredCurrencyId[i]); data << uint32(quest->RequiredCurrencyCount[i]); } for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; i++) { if (!quest->RequiredItemId[i]) continue; if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i])) data << uint32(itemTemplate->DisplayInfoID); else data << uint32(0); data << uint32(quest->RequiredItemId[i]); data << uint32(quest->RequiredItemCount[i]); } data.WriteByteSeq(guid[3]); data.WriteByteSeq(guid[1]); data.WriteString(requestItemsText); data.WriteByteSeq(guid[4]); data.WriteByteSeq(guid[5]); data.WriteByteSeq(guid[7]); data.WriteByteSeq(guid[6]); _session->SendPacket(&data); // missing from Cata - quest->GetSuggestedPlayers() TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId()); }
void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGuid, bool canComplete, bool closeOnCancel) const { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward uint32 itemCounter = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_ITEM); if (!itemCounter && canComplete) { SendQuestGiverOfferReward(quest, npcGuid, true); return; } std::string questTitle = quest->GetTitle(); std::string requestItemsText = quest->GetRequestItemsText(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->RequestItemsText, locale, requestItemsText); } } uint32 requiredMoney = 0, itemCount = 0, currencyCount = 0; ByteBuffer currencyData, itemData; for (QuestObjectiveSet::const_iterator citr = quest->m_questObjectives.begin(); citr != quest->m_questObjectives.end(); citr++) { QuestObjective const* questObjective = *citr; switch (questObjective->Type) { case QUEST_OBJECTIVE_TYPE_ITEM: { itemData << int32(questObjective->ObjectId); itemData << int32(questObjective->Amount); itemCount++; break; } case QUEST_OBJECTIVE_TYPE_CURRENCY: { currencyData << int32(questObjective->ObjectId); currencyData << int32(questObjective->Amount); currencyCount++; break; } case QUEST_OBJECTIVE_TYPE_MONEY: { requiredMoney = questObjective->Amount; break; } default: break; } } if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) AddQuestLevelToTitle(questTitle, quest->GetQuestLevel()); ObjectGuid guid = npcGuid; uint32 currencyCounter = quest->GetQuestObjectiveCountType(QUEST_OBJECTIVE_TYPE_CURRENCY); WorldPacket data(SMSG_QUESTGIVER_REQUEST_ITEMS, 16 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + itemCount * (4 + 4) + currencyCount * (4 + 4)); data << guid; data << int32(0); // QuestGiverCreatureID data << int32(quest->GetQuestId()); data << int32(0); // CompEmoteDelay data << int32(canComplete ? quest->GetCompleteEmote() : quest->GetIncompleteEmote()); data << int32(quest->GetFlags()); data << int32(quest->GetFlags2()); data << int32(quest->GetSuggestedPlayers()); data << int32(requiredMoney); data << uint32(itemCount); data << uint32(currencyCount); data << int32(canComplete ? 0xDF : 0xDB); // StatusFlags data.append(itemData); data.append(currencyData); data.WriteBit(closeOnCancel); data.FlushBits(); data.WriteBits(questTitle.size(), 9); data.WriteBits(requestItemsText.size(), 12); data.FlushBits(); data.WriteString(questTitle); data.WriteString(requestItemsText); _session->SendPacket(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGuid), quest->GetQuestId()); }