diff options
author | ModoX <moardox@gmail.com> | 2024-02-24 15:05:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-24 15:05:21 +0100 |
commit | dd15d763cc0529afc9b7f077817645d875608626 (patch) | |
tree | 2a20e5e9b23609f856195ad26789dbabe263c581 | |
parent | 7751d278b1e594ea5abb8d292a42be361886ba5e (diff) |
Core/Creatures: Implemented UNIT_NPC_FLAG_GOSSIP as viewer dependent and update npcflags on quest changes (#29646)
-rw-r--r-- | src/server/game/Entities/Object/Updates/ViewerDependentValues.h | 12 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 78 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 4 | ||||
-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 |
6 files changed, 96 insertions, 4 deletions
diff --git a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h index 852ba9b86e3..b6c3c61bb6a 100644 --- a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h +++ b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h @@ -326,9 +326,17 @@ public: static value_type GetValue(UF::UnitData const* unitData, uint32 i, Unit const* unit, Player const* receiver) { value_type npcFlag = unitData->NpcFlags[i]; - if (i == 0 && unit->IsCreature() && !receiver->CanSeeSpellClickOn(unit->ToCreature())) - npcFlag &= ~UNIT_NPC_FLAG_SPELLCLICK; + if (i == 0) + { + if (Creature const* creature = unit->ToCreature()) + { + if (!receiver->CanSeeGossipOn(creature)) + npcFlag &= ~(UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + if (!receiver->CanSeeSpellClickOn(creature)) + npcFlag &= ~UNIT_NPC_FLAG_SPELLCLICK; + } + } return npcFlag; } }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 51e79741296..f0a1d0ab99f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2033,6 +2033,37 @@ 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) @@ -14362,7 +14393,7 @@ uint32 Player::GetGossipTextId(uint32 menuId, WorldObject* source) return textId; } -uint32 Player::GetGossipMenuForSource(WorldObject* source) +uint32 Player::GetGossipMenuForSource(WorldObject const* source) const { switch (source->GetTypeId()) { @@ -14995,6 +15026,8 @@ 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) @@ -15382,6 +15415,8 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew if (quest->HasFlag(QUEST_FLAGS_UPDATE_PHASESHIFT)) updateVisibility = PhasingHandler::OnConditionChange(this, false); + UpdateNearbyCreatureNpcFlags(); + //lets remove flag for delayed teleports SetCanDelayTeleport(false); @@ -15413,6 +15448,8 @@ void Player::RewardQuest(Quest const* quest, LootItemType rewardType, uint32 rew if (updateVisibility) UpdateObjectVisibility(); + + UpdateNearbyCreatureNpcFlags(); } void Player::SetRewardedQuest(uint32 quest_id) @@ -16067,6 +16104,8 @@ void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= sScriptMgr->OnQuestStatusChange(this, quest, oldStatus, status); } + UpdateNearbyCreatureNpcFlags(); + if (update) SendQuestUpdate(questId); } @@ -16331,6 +16370,8 @@ void Player::SkipQuests(std::vector<uint32> const& questIds) if (updateVisibility) UpdateObjectVisibility(); + + UpdateNearbyCreatureNpcFlags(); } void Player::DespawnPersonalSummonsForQuest(uint32 questId) @@ -16863,6 +16904,8 @@ void Player::UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int3 if (updatePhaseShift) PhasingHandler::OnConditionChange(this); + UpdateNearbyCreatureNpcFlags(); + if (updateZoneAuras) { UpdateZoneDependentAuras(GetZoneId()); @@ -27086,6 +27129,39 @@ bool Player::IsPetNeedBeTemporaryUnsummoned() const return !IsInWorld() || !IsAlive() || HasUnitMovementFlag(MOVEMENTFLAG_FLYING) || HasExtraUnitMovementFlag2(MOVEMENTFLAG3_ADV_FLYING); } +bool Player::CanSeeGossipOn(Creature const* creature) const +{ + if (creature->HasNpcFlag(UNIT_NPC_FLAG_GOSSIP)) + { + if (GetGossipMenuForSource(creature)) + return true; + } + + // for cases with questgiver/ender without gossip menus + if (creature->HasNpcFlag(UNIT_NPC_FLAG_QUESTGIVER)) + { + QuestRelationResult objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelations(creature->GetEntry()); + for (uint32 quest_id : objectQIR) + { + QuestStatus status = GetQuestStatus(quest_id); + if (status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_INCOMPLETE) + return true; + } + + QuestRelationResult objectQR = sObjectMgr->GetCreatureQuestRelations(creature->GetEntry()); + for (uint32 quest_id : objectQR) + { + Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id); + if (!quest) + continue; + + if (CanTakeQuest(quest, false)) + return true; + } + } + return false; +} + bool Player::CanSeeSpellClickOn(Creature const* c) const { if (!c->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 446a0725333..da3e165ffe3 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1150,6 +1150,7 @@ 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(); @@ -1531,7 +1532,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> uint32 GetGossipTextId(uint32 menuId, WorldObject* source); uint32 GetGossipTextId(WorldObject* source); - uint32 GetGossipMenuForSource(WorldObject* source); + uint32 GetGossipMenuForSource(WorldObject const* source) const; /*********************************************************/ /*** QUEST SYSTEM ***/ @@ -2663,6 +2664,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> void SetKnownTitles(uint32 index, uint64 mask) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::KnownTitles, index), mask); } //bool isActiveObject() const { return true; } + bool CanSeeGossipOn(Creature const* creature) const; bool CanSeeSpellClickOn(Creature const* creature) const; uint32 GetChampioningFaction() const { return m_ChampioningFaction; } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index e98b85608aa..4e86ba962d1 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -490,6 +490,8 @@ 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 06c3ccaf4ad..ecbba144f33 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4030,6 +4030,8 @@ 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 3dd04ef8eea..bf8d4ebcddf 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -142,6 +142,8 @@ public: sScriptMgr->OnQuestStatusChange(player, quest->GetQuestId()); sScriptMgr->OnQuestStatusChange(player, quest, oldStatus, QUEST_STATUS_NONE); + player->UpdateNearbyCreatureNpcFlags(); + handler->SendSysMessage(LANG_COMMAND_QUEST_REMOVED); return true; } |