From dfdd88a2fc861e22a9b21218080d5395a6cc2880 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 13 Jun 2023 04:38:50 -0400 Subject: [PATCH] Core/Quests: Implemented new db table quest_objectives_completion_effect * Turn off automatic phase updates on quest objective completion * Allow more convenient conversation and spell casts on quest objective completion Port From (https://github.com/TrinityCore/TrinityCore/commit/a2be8d202823706ad4b29c2dc988c0fe978ae652) --- Source/Game/Entities/Player/Player.Quest.cs | 25 +++++++++++++- Source/Game/Globals/ObjectManager.cs | 6 ++-- Source/Game/Quest/Quest.cs | 37 ++++++++++++++++++++- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index 549c6598e..bd976a489 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -2432,6 +2432,8 @@ namespace Game.Entities public void UpdateQuestObjectiveProgress(QuestObjectiveType objectiveType, int objectId, long addCount, ObjectGuid victimGuid = default) { bool anyObjectiveChangedCompletionState = false; + bool updatePhaseShift = false; + bool updateZoneAuras = false; foreach (var objectiveStatusData in m_questObjectiveStatus.LookupByKey((objectiveType, objectId))) { @@ -2535,6 +2537,20 @@ namespace Game.Entities if (objectiveWasComplete != objectiveIsNowComplete) anyObjectiveChangedCompletionState = true; + if (objectiveIsNowComplete && objective.CompletionEffect != null) + { + if (objective.CompletionEffect.GameEventId.HasValue) + GameEvents.Trigger(objective.CompletionEffect.GameEventId.Value, this, null); + if (objective.CompletionEffect.SpellId.HasValue) + CastSpell(this, objective.CompletionEffect.SpellId.Value, true); + if (objective.CompletionEffect.ConversationId.HasValue) + Conversation.CreateConversation(objective.CompletionEffect.ConversationId.Value, this, GetPosition(), GetGUID()); + if (objective.CompletionEffect.UpdatePhaseShift) + updatePhaseShift = true; + if (objective.CompletionEffect.UpdateZoneAuras) + updateZoneAuras = true; + } + if (objectiveIsNowComplete && CanCompleteQuest(questId, objective.Id)) CompleteQuest(questId); else if (objectiveStatusData.QuestStatusPair.Status.Status == QuestStatus.Complete) @@ -2545,7 +2561,14 @@ namespace Game.Entities if (anyObjectiveChangedCompletionState) UpdateVisibleGameobjectsOrSpellClicks(); - PhasingHandler.OnConditionChange(this); + if (updatePhaseShift) + PhasingHandler.OnConditionChange(this); + + if (updateZoneAuras) + { + UpdateZoneDependentAuras(GetZoneId()); + UpdateAreaDependentAuras(GetAreaId()); + } } public bool HasQuestForItem(uint itemid) diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 377e89011..a86e6effa 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -7181,8 +7181,10 @@ namespace Game } // Load `quest_objectives` - // 0 1 2 3 4 5 6 7 8 9 - result = DB.World.Query("SELECT QuestID, ID, Type, StorageIndex, ObjectID, Amount, Flags, Flags2, ProgressBarWeight, Description FROM quest_objectives ORDER BY `Order` ASC, StorageIndex ASC"); + // 0 1 2 3 4 5 6 7 8 9 + result = DB.World.Query("SELECT qo.QuestID, qo.ID, qo.Type, qo.StorageIndex, qo.ObjectID, qo.Amount, qo.Flags, qo.Flags2, qo.ProgressBarWeight, qo.Description, " + + // 10 11 12 13 14 + "qoce.GameEventID, qoce.SpellID, qoce.ConversationID, qoce.UpdatePhaseShift, qoce.UpdateZoneAuras FROM quest_objectives qo LEFT JOIN quest_objectives_completion_effect qoce ON qo.ID = qoce.ObjectiveID ORDER BY `Order` ASC, StorageIndex ASC"); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 quest objectives. DB table `quest_objectives` is empty."); diff --git a/Source/Game/Quest/Quest.cs b/Source/Game/Quest/Quest.cs index f24ab4339..01a6140a2 100644 --- a/Source/Game/Quest/Quest.cs +++ b/Source/Game/Quest/Quest.cs @@ -235,7 +235,7 @@ namespace Game public void LoadQuestObjective(SQLFields fields) { - QuestObjective obj = new(); + QuestObjective obj = new(); obj.QuestID = fields.Read(0); obj.Id = fields.Read(1); obj.Type = (QuestObjectiveType)fields.Read(2); @@ -247,6 +247,31 @@ namespace Game obj.ProgressBarWeight = fields.Read(8); obj.Description = fields.Read(9); + bool hasCompletionEffect = false; + for (var i = 10; i < 15; ++i) + { + if (!fields.IsNull(i)) + { + hasCompletionEffect = true; + break; + } + } + + if (hasCompletionEffect) + { + obj.CompletionEffect = new QuestObjectiveAction(); + if (!fields.IsNull(10)) + obj.CompletionEffect.GameEventId = fields.Read(10); + if (!fields.IsNull(11)) + obj.CompletionEffect.SpellId = fields.Read(11); + if (!fields.IsNull(12)) + obj.CompletionEffect.ConversationId = fields.Read(12); + if (!fields.IsNull(13)) + obj.CompletionEffect.UpdatePhaseShift = fields.Read(13); + if (!fields.IsNull(14)) + obj.CompletionEffect.UpdateZoneAuras = fields.Read(14); + } + Objectives.Add(obj); _usedQuestObjectiveTypes[(int)obj.Type] = true; } @@ -996,6 +1021,15 @@ namespace Game public StringArray Text = new((int)Locale.Total); } + public class QuestObjectiveAction + { + public uint? GameEventId; + public uint? SpellId; + public uint? ConversationId; + public bool UpdatePhaseShift; + public bool UpdateZoneAuras; + } + public class QuestObjective { public uint Id; @@ -1009,6 +1043,7 @@ namespace Game public float ProgressBarWeight; public string Description; public int[] VisualEffects = Array.Empty(); + public QuestObjectiveAction CompletionEffect; public bool IsStoringValue() {