diff options
author | Rat <gmstreetrat@gmail.com> | 2015-03-31 19:55:53 +0200 |
---|---|---|
committer | Rat <gmstreetrat@gmail.com> | 2015-03-31 19:55:53 +0200 |
commit | e734146a6f813c2996c217bc4a0997fe165f604f (patch) | |
tree | b848f210b39e778abad15711be617fc38d3e78f8 /src | |
parent | 2fcfae180676b20024198c890dd77c55272f5cda (diff) |
Core/Quests: updated SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE packet
- updated gossip window handling
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 30 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 106 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.cpp | 25 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QuestPackets.h | 27 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 |
5 files changed, 114 insertions, 76 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index d676a54d79f..c48ed5de26b 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -333,15 +333,12 @@ void QuestMenu::ClearMenu() void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, ObjectGuid npcGUID) { - WorldPacket data(SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE, 100); // guess size - data << npcGUID; - data << Title; - data << uint32(eEmote._Delay); // player emote - data << uint32(eEmote._Emote); // NPC emote - - size_t count_pos = data.wpos(); - data << uint8 (0); - uint32 count = 0; + WorldPackets::Quest::QuestGiverQuestList questList; + + questList.QuestGiverGUID = npcGUID; + questList.Greeting = Title; + questList.GreetEmoteDelay = eEmote._Delay; + questList.GreetEmoteType = eEmote._Emote; // Store this instead of checking the Singleton every loop iteration bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); @@ -354,7 +351,6 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID)) { - ++count; std::string title = quest->GetLogTitle(); int32 locale = _session->GetSessionDbLocaleIndex(); @@ -365,18 +361,14 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string if (questLevelInTitle) AddQuestLevelToTitle(title, quest->GetQuestLevel()); - data << uint32(questID); - data << uint32(qmi.QuestIcon); - data << int32(quest->GetQuestLevel()); - data << uint32(quest->GetFlags()); // 3.3.3 quest flags - data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation - data << title; + bool repeatable = false; // NYI + + questList.GossipTexts.push_back(WorldPackets::Quest::GossipTextData(questID, qmi.QuestIcon, quest->GetQuestLevel(), quest->GetFlags(), quest->GetFlagsEx(), repeatable, title)); } } - data.put<uint8>(count_pos, count); - _session->SendPacket(&data); - TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC=%s", npcGUID.ToString().c_str()); + _session->SendPacket(questList.Write()); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE NPC=%s", npcGUID.ToString().c_str()); } void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e63c8e5feaa..2b37e228add 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13797,19 +13797,9 @@ void Player::SendPreparedGossip(WorldObject* source) if (!source) return; - if (source->GetTypeId() == TYPEID_UNIT) + if (source->GetTypeId() == TYPEID_UNIT || source->GetTypeId() == TYPEID_GAMEOBJECT) { - // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag) - if (!source->ToCreature()->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty()) - { - SendPreparedQuest(source->GetGUID()); - return; - } - } - else if (source->GetTypeId() == TYPEID_GAMEOBJECT) - { - // probably need to find a better way here - if (!PlayerTalkClass->GetGossipMenu().GetMenuId() && !PlayerTalkClass->GetQuestMenu().Empty()) + if (PlayerTalkClass->GetGossipMenu().Empty() && !PlayerTalkClass->GetQuestMenu().Empty()) { SendPreparedQuest(source->GetGUID()); return; @@ -14072,18 +14062,21 @@ void Player::SendPreparedQuest(ObjectGuid guid) QuestMenu& questMenu = PlayerTalkClass->GetQuestMenu(); if (questMenu.Empty()) return; - + // single element case if (questMenu.GetMenuItemCount() == 1) { QuestMenuItem const& qmi0 = questMenu.GetItem(0); uint32 questId = qmi0.QuestId; - // Auto open -- maybe also should verify there is no greeting + // Auto open if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) { if (qmi0.QuestIcon == 4) + { PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanRewardQuest(quest, false), true); + return; + } // Send completable on repeatable and autoCompletable quest if player don't have quest /// @todo verify if check for !quest->IsDaily() is really correct (possibly not) else @@ -14095,62 +14088,63 @@ void Player::SendPreparedQuest(ObjectGuid guid) return; } - if (quest->IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true)) - AddQuestAndCheckCompletion(quest, object); + if (object->GetTypeId() != TYPEID_UNIT || object->ToCreature()->GetUInt32Value(UNIT_NPC_FLAGS) & UNIT_NPC_FLAG_GOSSIP) + { + if (quest->IsAutoAccept() && CanAddQuest(quest, true) && CanTakeQuest(quest, true)) + AddQuestAndCheckCompletion(quest, object); - if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) - PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true); - else - PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true); + if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) + PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, CanCompleteRepeatableQuest(quest), true); + else + PlayerTalkClass->SendQuestGiverQuestDetails(quest, guid, true); + return; + } } } } - // multiple entries - else - { - QEmote qe; - qe._Delay = 0; - qe._Emote = 0; - std::string title = ""; - // need pet case for some quests - Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid); - if (creature) + QEmote qe; + qe._Delay = 0; + qe._Emote = 0; + std::string title = ""; + + // need pet case for some quests + Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid); + if (creature) + { + uint32 textid = GetGossipTextId(creature); + GossipText const* gossiptext = sObjectMgr->GetGossipText(textid); + if (!gossiptext) { - uint32 textid = GetGossipTextId(creature); - GossipText const* gossiptext = sObjectMgr->GetGossipText(textid); - if (!gossiptext) + qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote + qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote + title.clear(); + } + else + { + qe = gossiptext->Options[0].Emotes[0]; + + if (!gossiptext->Options[0].Text_0.empty()) { - qe._Delay = 0; //TEXTEMOTE_MESSAGE; //zyg: player emote - qe._Emote = 0; //TEXTEMOTE_HELLO; //zyg: NPC emote - title.clear(); + title = gossiptext->Options[0].Text_0; + + int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) + ObjectMgr::GetLocaleString(nl->Text_0[0], loc_idx, title); } else { - qe = gossiptext->Options[0].Emotes[0]; - - if (!gossiptext->Options[0].Text_0.empty()) - { - title = gossiptext->Options[0].Text_0; - - int loc_idx = GetSession()->GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) - ObjectMgr::GetLocaleString(nl->Text_0[0], loc_idx, title); - } - else - { - title = gossiptext->Options[0].Text_1; + title = gossiptext->Options[0].Text_1; - int loc_idx = GetSession()->GetSessionDbLocaleIndex(); - if (loc_idx >= 0) - if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) - ObjectMgr::GetLocaleString(nl->Text_1[0], loc_idx, title); - } + int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) + ObjectMgr::GetLocaleString(nl->Text_1[0], loc_idx, title); } } - PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid); } + PlayerTalkClass->SendQuestGiverQuestList(qe, title, guid); } bool Player::IsActiveQuest(uint32 quest_id) const diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index 9801db09844..ce3f9115772 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -438,3 +438,28 @@ void WorldPackets::Quest::QuestLogRemoveQuest::Read() { _worldPacket >> Entry; } + +WorldPacket const* WorldPackets::Quest::QuestGiverQuestList::Write() +{ + _worldPacket << QuestGiverGUID; + _worldPacket << GreetEmoteDelay; + _worldPacket << GreetEmoteType; + _worldPacket << uint32(GossipTexts.size()); + for (GossipTextData const& gossip : GossipTexts) + { + _worldPacket << gossip.QuestID; + _worldPacket << gossip.QuestType; + _worldPacket << gossip.QuestLevel; + _worldPacket << gossip.QuestFlags; + _worldPacket << gossip.QuestFlagsEx; + _worldPacket.FlushBits(); + _worldPacket.WriteBit(gossip.Repeatable); + _worldPacket.WriteBits(gossip.QuestTitle.size(), 9); + _worldPacket.WriteString(gossip.QuestTitle); + } + _worldPacket.FlushBits(); + _worldPacket.WriteBits(Greeting.size(), 11); + _worldPacket.WriteString(Greeting); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index 016fb2e0df3..75ac9329512 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -427,6 +427,33 @@ namespace WorldPackets uint8 Entry = 0; }; + + struct GossipTextData + { + GossipTextData(uint32 questID, uint32 questType, uint32 questLevel, uint32 questFlags, uint32 questFlagsEx, bool repeatable, std::string questTitle) : + QuestID(questID), QuestType(questType), QuestLevel(questLevel), QuestFlags(questFlags), QuestFlagsEx(questFlagsEx), Repeatable(repeatable), QuestTitle(questTitle) { } + uint32 QuestID; + uint32 QuestType; + uint32 QuestLevel; + uint32 QuestFlags; + uint32 QuestFlagsEx; + bool Repeatable; + std::string QuestTitle; + }; + + class QuestGiverQuestList final : public ServerPacket + { + public: + QuestGiverQuestList() : ServerPacket(SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE, 100) { } + + WorldPacket const* Write() override; + + ObjectGuid QuestGiverGUID; + uint32 GreetEmoteDelay = 0; + uint32 GreetEmoteType = 0; + std::vector<GossipTextData> GossipTexts; + std::string Greeting; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 6bc83ac52f1..3a85b2c14c6 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1597,7 +1597,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_DETAILS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_QUEST_LIST_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_REQUEST_ITEMS, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_STATUS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_STATUS_MULTIPLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); |