From 70b0de4e1fd198eefc14ae0aa0e5ed348b7349d8 Mon Sep 17 00:00:00 2001 From: acidmanifesto Date: Thu, 4 Nov 2021 18:51:54 -0400 Subject: [PATCH] fix(Core/Quest): Refresh SMSG_QUESTGIVER_STATUS_MULTIPLE after a quest change (#8902) Co-authored-by: Malcrom --- src/server/game/Entities/Player/Player.cpp | 47 +++++++++++++++++++ src/server/game/Entities/Player/Player.h | 1 + .../game/Entities/Player/PlayerQuest.cpp | 2 + src/server/game/Handlers/ItemHandler.cpp | 3 ++ src/server/game/Handlers/QuestHandler.cpp | 41 +--------------- 5 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 34781bd7e..2bd05b131 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2470,6 +2470,8 @@ void Player::GiveLevel(uint8 level) SetByteFlag(PLAYER_FIELD_BYTES, 1, 0x01); } + SendQuestGiverStatusMultiple(); + sScriptMgr->OnPlayerLevelChanged(this, oldLevel); } @@ -7438,6 +7440,50 @@ bool Player::CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const return true; } +void Player::SendQuestGiverStatusMultiple() +{ + uint32 count = 0; + + WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4); + data << uint32(count); // placeholder + + for (GuidUnorderedSet::const_iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) + { + uint32 questStatus = DIALOG_STATUS_NONE; + + if ((*itr).IsAnyTypeCreature()) + { + // need also pet quests case support + Creature* questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr); + if (!questgiver || questgiver->IsHostileTo(this)) + continue; + if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) + continue; + + questStatus = GetQuestDialogStatus(questgiver); + + data << questgiver->GetGUID(); + data << uint8(questStatus); + ++count; + } + else if ((*itr).IsGameObject()) + { + GameObject* questgiver = GetMap()->GetGameObject(*itr); + if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) + continue; + + questStatus = GetQuestDialogStatus(questgiver); + + data << questgiver->GetGUID(); + data << uint8(questStatus); + ++count; + } + } + + data.put(0, count); // write real count + GetSession()->SendPacket(&data); +} + /* If in a battleground a player dies, and an enemy removes the insignia, the player's bones is lootable Called by remove insignia spell effect */ void Player::RemovedInsignia(Player* looterPlr) @@ -10928,6 +10974,7 @@ void Player::SendInitialPacketsAfterAddToMap() GetAurasForTarget(this); SendEnchantmentDurations(); // must be after add to map SendItemDurations(); // must be after add to map + SendQuestGiverStatusMultiple(); // raid downscaling - send difficulty to player if (GetMap()->IsRaid()) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 2cd618b30..62540d0af 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2743,6 +2743,7 @@ public: RewardedQuestSet m_RewardedQuests; QuestStatusSaveMap m_RewardedQuestsSave; + void SendQuestGiverStatusMultiple(); SkillStatusMap mSkillStatus; diff --git a/src/server/game/Entities/Player/PlayerQuest.cpp b/src/server/game/Entities/Player/PlayerQuest.cpp index 4747e66e5..06be32c20 100644 --- a/src/server/game/Entities/Player/PlayerQuest.cpp +++ b/src/server/game/Entities/Player/PlayerQuest.cpp @@ -859,6 +859,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, SendQuestUpdate(quest_id); + SendQuestGiverStatusMultiple(); + //lets remove flag for delayed teleports SetMustDelayTeleport(false); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 854cd44d2..1195705cd 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -329,7 +329,10 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData) _player->DestroyItemCount(pItem, i_count, true); } else + { _player->DestroyItem(bag, slot, true); + } + _player->SendQuestGiverStatusMultiple(); } bool ItemTemplate::HasStat(ItemModType stat) const diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index fe815d212..bf0598afe 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -640,46 +640,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket { LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY"); - uint32 count = 0; - - WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4); - data << uint32(count); // placeholder - - for (GuidUnorderedSet::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) - { - uint32 questStatus = DIALOG_STATUS_NONE; - - if ((*itr).IsAnyTypeCreature()) - { - // need also pet quests case support - Creature* questgiver = ObjectAccessor::GetCreatureOrPetOrVehicle(*GetPlayer(), *itr); - if (!questgiver || questgiver->IsHostileTo(_player)) - continue; - if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER)) - continue; - - questStatus = _player->GetQuestDialogStatus(questgiver); - - data << questgiver->GetGUID(); - data << uint8(questStatus); - ++count; - } - else if ((*itr).IsGameObject()) - { - GameObject* questgiver = GetPlayer()->GetMap()->GetGameObject(*itr); - if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) - continue; - - questStatus = _player->GetQuestDialogStatus(questgiver); - - data << questgiver->GetGUID(); - data << uint8(questStatus); - ++count; - } - } - - data.put(0, count); // write real count - SendPacket(&data); + _player->SendQuestGiverStatusMultiple(); } void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/)