aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp30
-rw-r--r--src/server/game/Entities/Player/Player.cpp106
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp25
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h27
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
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);