From 39c20cd8bef7a48a8b79afd18cc21ac68ac12d02 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Wed, 18 Dec 2019 05:54:53 +0100 Subject: [PATCH] Core/Packets: converted SMSG_QUEST_GIVER_REQUEST_ITEMS to packet class --- .../game/Entities/Creature/GossipDef.cpp | 65 +++++++----------- .../game/Server/Packets/QuestPackets.cpp | 53 +++++++++++++++ src/server/game/Server/Packets/QuestPackets.h | 68 +++++++++++++++++++ src/server/game/Server/Protocol/Opcodes.cpp | 2 +- src/server/game/Server/Protocol/Opcodes.h | 2 +- 5 files changed, 148 insertions(+), 42 deletions(-) create mode 100644 src/server/game/Server/Packets/QuestPackets.cpp create mode 100644 src/server/game/Server/Packets/QuestPackets.h diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 1b69f61aa34..69e7b646114 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -20,6 +20,7 @@ #include "Formulas.h" #include "ObjectMgr.h" #include "QuestDef.h" +#include "QuestPackets.h" #include "WorldSession.h" GossipMenu::GossipMenu() @@ -721,65 +722,49 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU 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; + WorldPackets::Quest::QuestGiverRequestItems packet; - data << uint32(0); // unknown + packet.QuestTitle = questTitle; + packet.CompletionText = requestItemsText; + packet.QuestID = quest->GetQuestId(); + packet.QuestGiverGUID = npcGUID; + // There are no delays in any 4.x quest sniffs sent so we skip them and send them as 0 if (canComplete) - data << quest->GetCompleteEmote(); - else - data << quest->GetIncompleteEmote(); + packet.CompEmoteType = canComplete ? quest->GetCompleteEmote() : quest->GetIncompleteEmote(); - // Close Window after cancel - data << uint32(autoLaunched); + packet.AutoLaunched = autoLaunched; + packet.QuestFlags = quest->GetFlags(); + packet.SuggestPartyMembers = quest->GetSuggestedPlayers(); + packet.MoneyToGet = quest->GetRewOrReqMoney() < 0 ? -quest->GetRewOrReqMoney() : 0; - 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) + for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) { if (!quest->RequiredItemId[i]) continue; - data << uint32(quest->RequiredItemId[i]); - data << uint32(quest->RequiredItemCount[i]); - + uint32 displayId = 0; if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RequiredItemId[i])) - data << uint32(itemTemplate->DisplayInfoID); - else - data << uint32(0); + displayId = itemTemplate->DisplayInfoID; + + packet.Collect.emplace_back(quest->RequiredItemId[i], quest->RequiredItemCount[i], displayId); } - data << uint32(quest->GetReqCurrencyCount()); - for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) + for (uint8 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i) { if (!quest->RequiredCurrencyId[i]) continue; - data << uint32(quest->RequiredCurrencyId[i]); - data << uint32(quest->RequiredCurrencyCount[i]); + packet.Currency.emplace_back(quest->RequiredCurrencyId[i], 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); + // incomplete: FD + // incomplete quest with item objective but item objective is complete DD + // To-do: validate this. 4.3.4 the packet parser reads this flag as 6 seperate values which seems a bit odd for a bitmask based flag + packet.StatusFlags = canComplete ? 0xFF : 0xFD; - 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 NPC=%s, questid=%u", npcGUID.ToString().c_str(), quest->GetQuestId()); + _session->SendPacket(packet.Write()); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_REQUEST_ITEMS NPC=%s, questid=%u", npcGUID.ToString().c_str(), quest->GetQuestId()); } void PlayerMenu::AddQuestLevelToTitle(std::string &title, int32 level) diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp new file mode 100644 index 00000000000..0a3bd17e690 --- /dev/null +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "QuestPackets.h" +#include "Errors.h" + +WorldPacket const* WorldPackets::Quest::QuestGiverRequestItems::Write() +{ + _worldPacket << QuestGiverGUID; + _worldPacket << uint32(QuestID); + _worldPacket << QuestTitle; + _worldPacket << CompletionText; + _worldPacket << uint32(CompEmoteDelay); + _worldPacket << uint32(CompEmoteType); + _worldPacket << uint32(AutoLaunched); + _worldPacket << uint32(QuestFlags); + _worldPacket << uint32(SuggestPartyMembers); + _worldPacket << uint32(MoneyToGet); + + _worldPacket << uint32(Collect.size()); + for (QuestObjectiveCollect const& obj : Collect) + { + _worldPacket << uint32(obj.ObjectID); + _worldPacket << uint32(obj.Amount); + _worldPacket << uint32(obj.DisplayID); + + } + + _worldPacket << uint32(Currency.size()); + for (QuestCurrency const& cur : Currency) + { + _worldPacket << uint32(cur.CurrencyID); + _worldPacket << uint32(cur.Amount); + } + + _worldPacket << uint32(StatusFlags); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h new file mode 100644 index 00000000000..5c94cbe133a --- /dev/null +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008-2019 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef SystemPackets_h__ +#define SystemPackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" +#include "Optional.h" + +namespace WorldPackets +{ + namespace Quest + { + struct QuestObjectiveCollect + { + QuestObjectiveCollect(int32 objectID = 0, int32 amount = 0, uint32 displayId = 0) : ObjectID(objectID), Amount(amount), DisplayID(displayId) { } + uint32 ObjectID; + uint32 Amount; + uint32 DisplayID; + }; + + struct QuestCurrency + { + QuestCurrency(int32 currencyID = 0, int32 amount = 0) : CurrencyID(currencyID), Amount(amount) { } + uint32 CurrencyID; + uint32 Amount; + }; + + class QuestGiverRequestItems final : public ServerPacket + { + public: + QuestGiverRequestItems() : ServerPacket(SMSG_QUEST_GIVER_REQUEST_ITEMS, 300) { } + + WorldPacket const* Write() override; + + ObjectGuid QuestGiverGUID; + uint32 QuestID = 0; + uint32 CompEmoteDelay = 0; + uint32 CompEmoteType = 0; + bool AutoLaunched = false; + uint32 SuggestPartyMembers = 0; + uint32 MoneyToGet = 0; + std::vector Collect; + std::vector Currency; + uint32 StatusFlags = 0; + uint32 QuestFlags = 0; + std::string QuestTitle; + std::string CompletionText; + }; + } +} + +#endif // SystemPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 58fd9753a58..6fbc53f7a41 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1140,7 +1140,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_REQUEST_ITEMS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_NEVER, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 9606adf32e8..847c8591c3c 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1099,7 +1099,7 @@ enum OpcodeServer SMSG_QUESTGIVER_QUEST_FAILED = 0x4236, SMSG_QUESTGIVER_QUEST_INVALID = 0x4016, SMSG_QUESTGIVER_QUEST_LIST = 0x0134, - SMSG_QUESTGIVER_REQUEST_ITEMS = 0x6236, + SMSG_QUEST_GIVER_REQUEST_ITEMS = 0x6236, SMSG_QUESTGIVER_STATUS = 0x2115, SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x4F25, SMSG_QUESTLOG_FULL = 0x0E36,