Core/Quests: Merged UpdateNearbyCreatureNpcFlags, UpdateVisibleGameobjectsOrSpellClicks and SendQuestGiverStatusMultiple on quest actions

* Fixes quest markers above NPC heads not disappearing when player stops seeing questgiver npc flag
Port From (https://github.com/TrinityCore/TrinityCore/commit/97d7ccd180f96a414f205396261907e1e87d491a)
This commit is contained in:
hondacrx
2024-03-04 12:18:45 -05:00
parent 974ca273ae
commit 0325d8b523
8 changed files with 78 additions and 96 deletions
@@ -112,8 +112,6 @@ namespace Game.Chat
Global.ScriptMgr.OnQuestStatusChange(player, quest.Id);
Global.ScriptMgr.OnQuestStatusChange(player, quest, oldStatus, QuestStatus.None);
player.UpdateNearbyCreatureNpcFlags();
handler.SendSysMessage(CypherStrings.CommandQuestRemoved);
return true;
}
+70 -53
View File
@@ -841,8 +841,6 @@ namespace Game.Entities
Global.ScriptMgr.OnQuestStatusChange(this, questId);
Global.ScriptMgr.OnQuestStatusChange(this, quest, oldStatus, questStatusData.Status);
UpdateNearbyCreatureNpcFlags();
}
public void CompleteQuest(uint quest_id)
@@ -1222,16 +1220,12 @@ namespace Game.Entities
UpdatePvPState();
}
SendQuestGiverStatusMultiple();
SendQuestUpdate(questId);
SendQuestUpdate(questId, true, true);
bool updateVisibility = false;
if (quest.HasFlag(QuestFlags.UpdatePhaseshift))
updateVisibility = PhasingHandler.OnConditionChange(this, false);
UpdateNearbyCreatureNpcFlags();
//lets remove flag for delayed teleports
SetCanDelayTeleport(false);
@@ -1262,8 +1256,6 @@ namespace Game.Entities
if (updateVisibility)
UpdateObjectVisibility();
UpdateNearbyCreatureNpcFlags();
}
public void SetRewardedQuest(uint questId)
@@ -1916,8 +1908,6 @@ namespace Game.Entities
Global.ScriptMgr.OnQuestStatusChange(this, quest, oldStatus, status);
}
UpdateNearbyCreatureNpcFlags();
if (update)
SendQuestUpdate(questId);
}
@@ -1968,7 +1958,7 @@ namespace Game.Entities
SendQuestUpdate(questId);
}
void SendQuestUpdate(uint questId)
void SendQuestUpdate(uint questId, bool updateInteractions = true, bool updateGameObjectQuestGiverStatus = false)
{
var saBounds = Global.SpellMgr.GetSpellAreaForQuestMapBounds(questId);
if (!saBounds.Empty())
@@ -2015,7 +2005,8 @@ namespace Game.Entities
RemoveAurasDueToSpell(spellId);
}
UpdateVisibleGameobjectsOrSpellClicks();
if (updateInteractions)
UpdateVisibleObjectInteractions(true, false, updateGameObjectQuestGiverStatus, true);
}
public QuestGiverStatus GetQuestDialogStatus(WorldObject questgiver)
@@ -2176,7 +2167,7 @@ namespace Game.Entities
}
SetRewardedQuest(questId);
SendQuestUpdate(questId);
SendQuestUpdate(questId, false);
if (!updateVisibility && quest.HasFlag(QuestFlags.UpdatePhaseshift))
updateVisibility = PhasingHandler.OnConditionChange(this, false);
@@ -2185,15 +2176,13 @@ namespace Game.Entities
Global.ScriptMgr.OnQuestStatusChange(this, quest, oldStatus, QuestStatus.Rewarded);
}
SendQuestGiverStatusMultiple();
UpdateVisibleObjectInteractions(true, false, true, true);
// make full db save
SaveToDB(false);
if (updateVisibility)
UpdateObjectVisibility();
UpdateNearbyCreatureNpcFlags();
}
public void DespawnPersonalSummonsForQuest(uint questId)
@@ -2488,7 +2477,7 @@ namespace Game.Entities
}
}
UpdateVisibleGameobjectsOrSpellClicks();
UpdateVisibleObjectInteractions(true, false, false, true);
}
public void KilledMonster(CreatureTemplate cInfo, ObjectGuid guid)
@@ -2710,13 +2699,11 @@ namespace Game.Entities
}
if (anyObjectiveChangedCompletionState)
UpdateVisibleGameobjectsOrSpellClicks();
UpdateVisibleObjectInteractions(true, false, false, true);
if (updatePhaseShift)
PhasingHandler.OnConditionChange(this);
UpdateNearbyCreatureNpcFlags();
if (updateZoneAuras)
{
UpdateZoneDependentAuras(GetZoneId());
@@ -3294,70 +3281,100 @@ namespace Game.Entities
return false;
}
public void UpdateVisibleGameobjectsOrSpellClicks()
public void UpdateVisibleObjectInteractions(bool allUnits, bool onlySpellClicks, bool gameObjectQuestGiverStatus, bool questObjectiveGameObjects)
{
if (m_clientGUIDs.Empty())
return;
QuestGiverStatusMultiple giverStatusMultiple = new();
UpdateData udata = new(GetMapId());
UpdateObject packet;
foreach (var guid in m_clientGUIDs)
foreach (var visibleObjectGuid in m_clientGUIDs)
{
if (guid.IsGameObject())
if (visibleObjectGuid.IsGameObject() && (gameObjectQuestGiverStatus || questObjectiveGameObjects))
{
GameObject obj = ObjectAccessor.GetGameObject(this, guid);
if (obj != null)
GameObject gameObject = ObjectAccessor.GetGameObject(this, visibleObjectGuid);
if (gameObject == null)
continue;
if (gameObjectQuestGiverStatus && gameObject.GetGoType() == GameObjectTypes.QuestGiver)
giverStatusMultiple.QuestGiver.Add(new QuestGiverInfo(visibleObjectGuid, GetQuestDialogStatus(gameObject)));
if (questObjectiveGameObjects)
{
ObjectFieldData objMask = new();
GameObjectFieldData goMask = new();
if (m_questObjectiveStatus.ContainsKey((QuestObjectiveType.GameObject, (int)obj.GetEntry())))
objMask.MarkChanged(obj.m_objectData.DynamicFlags);
if (m_questObjectiveStatus.ContainsKey((QuestObjectiveType.GameObject, (int)gameObject.GetEntry())))
objMask.MarkChanged(gameObject.m_objectData.DynamicFlags);
switch (obj.GetGoType())
switch (gameObject.GetGoType())
{
case GameObjectTypes.QuestGiver:
case GameObjectTypes.Chest:
case GameObjectTypes.Goober:
case GameObjectTypes.Generic:
case GameObjectTypes.GatheringNode:
if (Global.ObjectMgr.IsGameObjectForQuests(obj.GetEntry()))
objMask.MarkChanged(obj.m_objectData.DynamicFlags);
if (Global.ObjectMgr.IsGameObjectForQuests(gameObject.GetEntry()))
objMask.MarkChanged(gameObject.m_objectData.DynamicFlags);
break;
default:
break;
}
if (objMask.GetUpdateMask().IsAnySet() || goMask.GetUpdateMask().IsAnySet())
obj.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), goMask.GetUpdateMask(), this);
gameObject.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), goMask.GetUpdateMask(), this);
}
}
else if (guid.IsCreatureOrVehicle())
else if (visibleObjectGuid.IsCreatureOrVehicle() && (allUnits || onlySpellClicks))
{
Creature obj = ObjectAccessor.GetCreatureOrPetOrVehicle(this, guid);
if (obj == null)
Creature creature = ObjectAccessor.GetCreatureOrPetOrVehicle(this, visibleObjectGuid);
if (creature == null)
continue;
// check if this unit requires quest specific flags
if (!obj.HasNpcFlag(NPCFlags.SpellClick))
continue;
var clickBounds = Global.ObjectMgr.GetSpellClickInfoMapBounds(obj.GetEntry());
foreach (var spellClickInfo in clickBounds)
if (allUnits)
{
if (Global.ConditionMgr.HasConditionsForSpellClickEvent(obj.GetEntry(), spellClickInfo.spellId))
ObjectFieldData objMask = new();
UnitData unitMask = new();
for (int i = 0; i < creature.m_unitData.NpcFlags.GetSize(); ++i)
if (creature.m_unitData.NpcFlags[i] != 0)
unitMask.MarkChanged(creature.m_unitData.NpcFlags, i);
if (objMask.GetUpdateMask().IsAnySet() || unitMask.GetUpdateMask().IsAnySet())
creature.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), unitMask.GetUpdateMask(), this);
if (creature.IsQuestGiver())
giverStatusMultiple.QuestGiver.Add(new QuestGiverInfo(visibleObjectGuid, GetQuestDialogStatus(creature)));
}
else if (onlySpellClicks)
{
// check if this unit requires quest specific flags
if (!creature.HasNpcFlag(NPCFlags.SpellClick))
continue;
var clickBounds = Global.ObjectMgr.GetSpellClickInfoMapBounds(creature.GetEntry());
foreach (var spellClickInfo in clickBounds)
{
ObjectFieldData objMask = new();
UnitData unitMask = new();
unitMask.MarkChanged(m_unitData.NpcFlags, 0); // NpcFlags[0] has UNIT_NPC_FLAG_SPELLCLICK
obj.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), unitMask.GetUpdateMask(), this);
break;
if (Global.ConditionMgr.HasConditionsForSpellClickEvent(creature.GetEntry(), spellClickInfo.spellId))
{
ObjectFieldData objMask = new();
UnitData unitMask = new();
unitMask.MarkChanged(m_unitData.NpcFlags, 0); // NpcFlags[0] has UNIT_NPC_FLAG_SPELLCLICK
creature.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), unitMask.GetUpdateMask(), this);
break;
}
}
}
}
}
udata.BuildPacket(out packet);
SendPacket(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())
SendPacket(giverStatusMultiple);
if (udata.HasData())
{
udata.BuildPacket(out var packet);
SendPacket(packet);
}
}
void SetDailyQuestStatus(uint quest_id)
-29
View File
@@ -5520,35 +5520,6 @@ namespace Game.Entities
return go;
}
public void UpdateNearbyCreatureNpcFlags()
{
List<Creature> creatures = GetCreatureListWithOptionsInGrid(GetVisibilityRange(), new() { IgnorePhases = false });
UpdateData udata = new(GetMapId());
ObjectFieldData objMask = new();
UnitData unitMask = new();
for (int i = 0; i < m_unitData.NpcFlags.GetSize(); ++i)
unitMask.MarkChanged(m_unitData.NpcFlags, i);
foreach (Creature creature in creatures)
{
if (!HaveAtClient(creature))
continue;
// skip creatures which dont have any npcflags set
if (creature.GetNpcFlags() == 0 && creature.GetNpcFlags2() == 0)
continue;
creature.BuildValuesUpdateForPlayerWithMask(udata, objMask.GetUpdateMask(), unitMask.GetUpdateMask(), this);
}
if (!udata.HasData())
return;
udata.BuildPacket(out UpdateObject packet);
SendPacket(packet);
}
public void SendInitialPacketsBeforeAddToMap()
{
if (!m_teleport_options.HasAnyFlag(TeleportToOptions.Seamless))
+2 -2
View File
@@ -3800,7 +3800,7 @@ namespace Game.Entities
if (player != null)
{
if (Global.ConditionMgr.IsSpellUsedInSpellClickConditions(aurApp.GetBase().GetId()))
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(false, true, false, false);
player.FailCriteria(CriteriaFailEvent.LoseAura, aurApp.GetBase().GetId());
}
@@ -4020,7 +4020,7 @@ namespace Game.Entities
if (player != null)
{
if (Global.ConditionMgr.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());
+5 -5
View File
@@ -269,7 +269,7 @@ namespace Game.Groups
{
Player player = Global.ObjAccessor.FindPlayer(member.guid);
if (player != null)
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(false, true, false, true);
}
}
@@ -299,7 +299,7 @@ namespace Game.Groups
{
Player player = Global.ObjAccessor.FindPlayer(member.guid);
if (player != null)
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(false, true, false, true);
}
}
@@ -474,7 +474,7 @@ namespace Game.Groups
// quest related GO state dependent from raid membership
if (IsRaidGroup())
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(false, true, false, true);
player.FailCriteria(CriteriaFailEvent.ModifyPartyStatus, 0);
@@ -566,7 +566,7 @@ namespace Game.Groups
player.SetGroup(null);
// quest related GO state dependent from raid membership
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(false, true, false, true);
}
@@ -713,7 +713,7 @@ namespace Game.Groups
// quest related GO state dependent from raid membership
if (IsRaidGroup())
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(false, true, false, true);
if (!hideDestroy)
player.SendPacket(new GroupDestroyed());
+1 -1
View File
@@ -229,7 +229,7 @@ namespace Game
}
if (anyObjectiveChangedCompletionState)
player.UpdateVisibleGameobjectsOrSpellClicks();
player.UpdateVisibleObjectInteractions(true, false, false, true);
}
}
-2
View File
@@ -445,8 +445,6 @@ namespace Game
if (quest != null)
Global.ScriptMgr.OnQuestStatusChange(_player, quest, oldStatus, QuestStatus.None);
_player.UpdateNearbyCreatureNpcFlags();
}
GetPlayer().UpdateCriteria(CriteriaType.AbandonAnyQuest, 1);
-2
View File
@@ -3752,8 +3752,6 @@ namespace Game.Spells
Global.ScriptMgr.OnQuestStatusChange(player, quest_id);
Global.ScriptMgr.OnQuestStatusChange(player, quest, oldStatus, QuestStatus.None);
player.UpdateNearbyCreatureNpcFlags();
}
[SpellEffectHandler(SpellEffectName.SendTaxi)]