diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 147 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 5 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Groups/Group.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_quest.cpp | 2 |
8 files changed, 77 insertions, 97 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7498890db63..56ddc31a2b7 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2034,37 +2034,6 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, Gameo return go; } -void Player::UpdateNearbyCreatureNpcFlags() -{ - std::vector<Creature*> creatures; - GetCreatureListWithOptionsInGrid(creatures, GetVisibilityRange(), { .IgnorePhases = false }); - - UpdateData udata(GetMapId()); - UF::ObjectData::Base objMask; - UF::UnitData::Base unitMask; - for (uint32 i = 0; i < m_unitData->NpcFlags.size(); ++i) - unitMask.MarkChanged(&UF::UnitData::NpcFlags, i); - - for (Creature* creature : creatures) - { - if (!HaveAtClient(creature)) - continue; - - // skip creatures which dont have any npcflags set - if (!creature->GetNpcFlags() && !creature->GetNpcFlags2()) - continue; - - creature->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), unitMask.GetChangesMask(), this); - } - - if (!udata.HasData()) - return; - - WorldPacket packet; - udata.BuildPacket(&packet); - SendDirectMessage(&packet); -} - bool Player::IsInAreaTriggerRadius(AreaTriggerEntry const* trigger) const { if (!trigger) @@ -15027,8 +14996,6 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) sScriptMgr->OnQuestStatusChange(this, quest_id); sScriptMgr->OnQuestStatusChange(this, quest, oldStatus, questStatusData.Status); - - UpdateNearbyCreatureNpcFlags(); } void Player::CompleteQuest(uint32 quest_id) @@ -15408,16 +15375,12 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew UpdatePvPState(); } - SendQuestGiverStatusMultiple(); - - SendQuestUpdate(quest_id); + SendQuestUpdate(quest_id, true, true); bool updateVisibility = false; if (quest->HasFlag(QUEST_FLAGS_UPDATE_PHASESHIFT)) updateVisibility = PhasingHandler::OnConditionChange(this, false); - UpdateNearbyCreatureNpcFlags(); - //lets remove flag for delayed teleports SetCanDelayTeleport(false); @@ -15449,8 +15412,6 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew if (updateVisibility) UpdateObjectVisibility(); - - UpdateNearbyCreatureNpcFlags(); } void Player::SetRewardedQuest(uint32 quest_id) @@ -16105,8 +16066,6 @@ void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= sScriptMgr->OnQuestStatusChange(this, quest, oldStatus, status); } - UpdateNearbyCreatureNpcFlags(); - if (update) SendQuestUpdate(questId); } @@ -16160,7 +16119,7 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/) SendQuestUpdate(questId); } -void Player::SendQuestUpdate(uint32 questId) +void Player::SendQuestUpdate(uint32 questId, bool updateInteractions /*= true*/, bool updateGameObjectQuestGiverStatus /*= false*/) { SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(questId); @@ -16208,7 +16167,8 @@ void Player::SendQuestUpdate(uint32 questId) RemoveAurasDueToSpell(spellId); } - UpdateVisibleGameobjectsOrSpellClicks(); + if (updateInteractions) + UpdateVisibleObjectInteractions(true, false, updateGameObjectQuestGiverStatus, true); } QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const @@ -16355,7 +16315,7 @@ void Player::SkipQuests(std::vector<uint32> const& questIds) } SetRewardedQuest(questId); - SendQuestUpdate(questId); + SendQuestUpdate(questId, false); if (!updateVisibility && quest->HasFlag(QUEST_FLAGS_UPDATE_PHASESHIFT)) updateVisibility = PhasingHandler::OnConditionChange(this, false); @@ -16364,15 +16324,13 @@ void Player::SkipQuests(std::vector<uint32> const& questIds) sScriptMgr->OnQuestStatusChange(this, quest, oldStatus, QUEST_STATUS_REWARDED); } - SendQuestGiverStatusMultiple(); + UpdateVisibleObjectInteractions(true, false, true, true); // make full db save SaveToDB(false); if (updateVisibility) UpdateObjectVisibility(); - - UpdateNearbyCreatureNpcFlags(); } void Player::DespawnPersonalSummonsForQuest(uint32 questId) @@ -16677,7 +16635,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 /*count*/) IncompleteQuest(questId); } } - UpdateVisibleGameobjectsOrSpellClicks(); + UpdateVisibleObjectInteractions(true, false, false, true); } void Player::KilledMonster(CreatureTemplate const* cInfo, ObjectGuid guid) @@ -16900,13 +16858,11 @@ void Player::UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int3 } if (anyObjectiveChangedCompletionState) - UpdateVisibleGameobjectsOrSpellClicks(); + UpdateVisibleObjectInteractions(true, false, false, true); if (updatePhaseShift) PhasingHandler::OnConditionChange(this); - UpdateNearbyCreatureNpcFlags(); - if (updateZoneAuras) { UpdateZoneDependentAuras(GetZoneId()); @@ -25155,33 +25111,37 @@ bool Player::HasQuestForGO(int32 GOId) const return false; } -void Player::UpdateVisibleGameobjectsOrSpellClicks() +void Player::UpdateVisibleObjectInteractions(bool allUnits, bool onlySpellClicks, bool gameObjectQuestGiverStatus, bool questObjectiveGameObjects) { - if (m_clientGUIDs.empty()) - return; - + WorldPackets::Quest::QuestGiverStatusMultiple giverStatusMultiple; UpdateData udata(GetMapId()); - WorldPacket packet; - for (auto itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr) + for (ObjectGuid visibleObjectGuid : m_clientGUIDs) { - if (itr->IsGameObject()) + if (visibleObjectGuid.IsGameObject() && (gameObjectQuestGiverStatus || questObjectiveGameObjects)) { - if (GameObject* obj = ObjectAccessor::GetGameObject(*this, *itr)) + GameObject* gameObject = ObjectAccessor::GetGameObject(*this, visibleObjectGuid); + if (!gameObject) + continue; + + if (gameObjectQuestGiverStatus && gameObject->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) + giverStatusMultiple.QuestGiver.emplace_back(visibleObjectGuid, GetQuestDialogStatus(gameObject)); + + if (questObjectiveGameObjects) { UF::ObjectData::Base objMask; UF::GameObjectData::Base goMask; - if (m_questObjectiveStatus.find({ QUEST_OBJECTIVE_GAMEOBJECT, int32(obj->GetEntry()) }) != m_questObjectiveStatus.end()) + if (m_questObjectiveStatus.contains({ QUEST_OBJECTIVE_GAMEOBJECT, int32(gameObject->GetEntry()) })) objMask.MarkChanged(&UF::ObjectData::DynamicFlags); - switch (obj->GetGoType()) + switch (gameObject->GetGoType()) { case GAMEOBJECT_TYPE_QUESTGIVER: case GAMEOBJECT_TYPE_CHEST: case GAMEOBJECT_TYPE_GOOBER: case GAMEOBJECT_TYPE_GENERIC: case GAMEOBJECT_TYPE_GATHERING_NODE: - if (sObjectMgr->IsGameObjectForQuests(obj->GetEntry())) + if (sObjectMgr->IsGameObjectForQuests(gameObject->GetEntry())) objMask.MarkChanged(&UF::ObjectData::DynamicFlags); break; default: @@ -25189,35 +25149,62 @@ void Player::UpdateVisibleGameobjectsOrSpellClicks() } if (objMask.GetChangesMask().IsAnySet() || goMask.GetChangesMask().IsAnySet()) - obj->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), goMask.GetChangesMask(), this); + gameObject->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), goMask.GetChangesMask(), this); } } - else if (itr->IsCreatureOrVehicle()) + else if (visibleObjectGuid.IsCreatureOrVehicle() && (allUnits || onlySpellClicks)) { - Creature* obj = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, *itr); - if (!obj) + Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, visibleObjectGuid); + if (!creature) continue; - // check if this unit requires quest specific flags - if (!obj->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK)) - continue; + if (allUnits) + { + UF::ObjectData::Base objMask; + UF::UnitData::Base unitMask; + for (uint32 i = 0; i < creature->m_unitData->NpcFlags.size(); ++i) + if (creature->m_unitData->NpcFlags[i]) + unitMask.MarkChanged(&UF::UnitData::NpcFlags, i); + + if (objMask.GetChangesMask().IsAnySet() || unitMask.GetChangesMask().IsAnySet()) + creature->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), unitMask.GetChangesMask(), this); - auto clickBounds = sObjectMgr->GetSpellClickInfoMapBounds(obj->GetEntry()); - for (auto const& clickPair : clickBounds) + if (creature->IsQuestGiver()) + giverStatusMultiple.QuestGiver.emplace_back(visibleObjectGuid, GetQuestDialogStatus(creature)); + } + else if (onlySpellClicks) { - if (sConditionMgr->HasConditionsForSpellClickEvent(obj->GetEntry(), clickPair.second.spellId)) + // check if this unit requires quest specific flags + if (!creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK)) + continue; + + auto clickBounds = sObjectMgr->GetSpellClickInfoMapBounds(creature->GetEntry()); + for (auto const& clickPair : clickBounds) { - UF::ObjectData::Base objMask; - UF::UnitData::Base unitMask; - unitMask.MarkChanged(&UF::UnitData::NpcFlags, 0); // NpcFlags[0] has UNIT_NPC_FLAG_SPELLCLICK - obj->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), unitMask.GetChangesMask(), this); - break; + if (sConditionMgr->HasConditionsForSpellClickEvent(creature->GetEntry(), clickPair.second.spellId)) + { + UF::ObjectData::Base objMask; + UF::UnitData::Base unitMask; + unitMask.MarkChanged(&UF::UnitData::NpcFlags, 0); // NpcFlags[0] has UNIT_NPC_FLAG_SPELLCLICK + creature->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), unitMask.GetChangesMask(), this); + break; + } } } } } - udata.BuildPacket(&packet); - SendDirectMessage(&packet); + + // If as a result of npcflag updates we stop seeing UNIT_NPC_FLAG_QUESTGIVER then + // we must also send SMSG_QUEST_GIVER_STATUS_MULTIPLE because client will not request it automatically + if (!giverStatusMultiple.QuestGiver.empty()) + SendDirectMessage(giverStatusMultiple.Write()); + + if (udata.HasData()) + { + WorldPacket packet; + udata.BuildPacket(&packet); + SendDirectMessage(&packet); + } } bool Player::HasSummonPending() const diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 80eed2d2ccd..e5a39a319fc 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1150,7 +1150,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> Creature* GetNPCIfCanInteractWith(ObjectGuid const& guid, NPCFlags npcFlags, NPCFlags2 npcFlags2) const; GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid) const; GameObject* GetGameObjectIfCanInteractWith(ObjectGuid const& guid, GameobjectTypes type) const; - void UpdateNearbyCreatureNpcFlags(); void ToggleAFK(); void ToggleDND(); @@ -1595,7 +1594,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> void SetQuestStatus(uint32 questId, QuestStatus status, bool update = true); void RemoveActiveQuest(uint32 questId, bool update = true); void RemoveRewardedQuest(uint32 questId, bool update = true); - void SendQuestUpdate(uint32 questId); + void SendQuestUpdate(uint32 questId, bool updateInteractions = true, bool updateGameObjectQuestGiverStatus = false); QuestGiverStatus GetQuestDialogStatus(Object const* questGiver) const; void SkipQuests(std::vector<uint32> const& questIds); // removes quest from log, flags rewarded, but does not give any rewards to player void DespawnPersonalSummonsForQuest(uint32 questId); @@ -1646,7 +1645,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> bool HasQuestForItem(uint32 itemId) const; QuestObjective const* GetQuestObjectiveForItem(uint32 itemId, bool onlyIncomplete) const; bool HasQuestForGO(int32 goId) const; - void UpdateVisibleGameobjectsOrSpellClicks(); + void UpdateVisibleObjectInteractions(bool allUnits, bool onlySpellClicks, bool gameObjectQuestGiverStatus, bool questObjectiveGameObjects); bool CanShareQuest(uint32 questId) const; int32 GetQuestObjectiveData(QuestObjective const& objective) const; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 7648dd96fe3..45252511720 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3443,7 +3443,7 @@ void Unit::_ApplyAura(AuraApplication* aurApp, uint32 effMask) if (Player* player = ToPlayer()) { if (sConditionMgr->IsSpellUsedInSpellClickConditions(aurApp->GetBase()->GetId())) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, false); player->FailCriteria(CriteriaFailEvent::GainAura, aurApp->GetBase()->GetId()); player->StartCriteria(CriteriaStartEvent::GainAura, aurApp->GetBase()->GetId()); @@ -3538,7 +3538,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo if (Player* player = ToPlayer()) { if (sConditionMgr->IsSpellUsedInSpellClickConditions(aurApp->GetBase()->GetId())) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, false); player->FailCriteria(CriteriaFailEvent::LoseAura, aurApp->GetBase()->GetId()); } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index c98dcee1152..ea6c783571e 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -319,7 +319,7 @@ void Group::ConvertToRaid() // update quest related GO states (quest activity dependent from raid membership) for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) if (Player* player = ObjectAccessor::FindPlayer(citr->guid)) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, true); } void Group::ConvertToGroup() @@ -350,7 +350,7 @@ void Group::ConvertToGroup() // update quest related GO states (quest activity dependent from raid membership) for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) if (Player* player = ObjectAccessor::FindPlayer(citr->guid)) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, true); } bool Group::AddInvite(Player* player) @@ -523,7 +523,7 @@ bool Group::AddMember(Player* player) // quest related GO state dependent from raid membership if (isRaidGroup()) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, true); player->FailCriteria(CriteriaFailEvent::ModifyPartyStatus, 0); @@ -613,7 +613,7 @@ bool Group::RemoveMember(ObjectGuid guid, RemoveMethod method /*= GROUP_REMOVEME player->SetGroup(nullptr); // quest related GO state dependent from raid membership - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, true); } player->SetPartyType(m_groupCategory, GROUP_TYPE_NONE); @@ -758,7 +758,7 @@ void Group::Disband(bool hideDestroy /* = false */) // quest related GO state dependent from raid membership if (isRaidGroup()) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(false, true, false, true); if (!hideDestroy) player->SendDirectMessage(WorldPackets::Party::GroupDestroyed().Write()); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 2416a635d1d..e7baa92f361 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -550,7 +550,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPackets::AreaTrigger::AreaTrigge } if (anyObjectiveChangedCompletionState) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateVisibleObjectInteractions(true, false, false, true); } } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 4e86ba962d1..e98b85608aa 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -490,8 +490,6 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPackets::Quest::QuestLogRemove if (quest) sScriptMgr->OnQuestStatusChange(_player, quest, oldStatus, QUEST_STATUS_NONE); - - _player->UpdateNearbyCreatureNpcFlags(); } _player->UpdateCriteria(CriteriaType::AbandonAnyQuest, 1); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9425c36e836..72d0271d656 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4018,8 +4018,6 @@ void Spell::EffectQuestClear() sScriptMgr->OnQuestStatusChange(player, quest_id); sScriptMgr->OnQuestStatusChange(player, quest, oldStatus, QUEST_STATUS_NONE); - - player->UpdateNearbyCreatureNpcFlags(); } void Spell::EffectSendTaxi() diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index bf8d4ebcddf..3dd04ef8eea 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -142,8 +142,6 @@ public: sScriptMgr->OnQuestStatusChange(player, quest->GetQuestId()); sScriptMgr->OnQuestStatusChange(player, quest, oldStatus, QUEST_STATUS_NONE); - player->UpdateNearbyCreatureNpcFlags(); - handler->SendSysMessage(LANG_COMMAND_QUEST_REMOVED); return true; } |