diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index e950e6f52..8f5d5816a 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -1322,8 +1322,8 @@ namespace Game.Entities // each-from-all exclusive group (< 0) // can be start if only all quests in prev quest exclusive group completed and rewarded - var range = Global.ObjectMgr._exclusiveQuestGroups.LookupByKey(qPrevInfo.ExclusiveGroup); - foreach (var exclude_Id in range) + var bounds = Global.ObjectMgr.GetExclusiveQuestGroupBounds(qPrevInfo.ExclusiveGroup); + foreach (var exclude_Id in bounds) { // skip checked quest id, only state of other quests in group is interesting if (exclude_Id == prevId) @@ -1352,7 +1352,7 @@ namespace Game.Entities // each-from-all exclusive group (< 0) // can be start if only all quests in prev quest exclusive group active - var range = Global.ObjectMgr._exclusiveQuestGroups.LookupByKey(qPrevInfo.ExclusiveGroup); + var range = Global.ObjectMgr.GetExclusiveQuestGroupBounds(qPrevInfo.ExclusiveGroup); foreach (var exclude_Id in range) { // skip checked quest id, only state of other quests in group is interesting @@ -1528,7 +1528,7 @@ namespace Game.Entities if (qInfo.ExclusiveGroup <= 0) return true; - var range = Global.ObjectMgr._exclusiveQuestGroups.LookupByKey(qInfo.ExclusiveGroup); + var range = Global.ObjectMgr.GetExclusiveQuestGroupBounds(qInfo.ExclusiveGroup); // always must be found if qInfo.ExclusiveGroup != 0 foreach (var exclude_Id in range) diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index d38956e42..cd30fc072 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -6354,10 +6354,13 @@ namespace Game } while (result.NextRow()); + QuestLoaderHelper helper = new QuestLoaderHelper(); + helper.LoaderFunction = (quest, fields) => quest.LoadQuestDetails(fields); + + // Load `quest_details` // 0 1 2 3 4 5 6 7 8 result = DB.World.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details"); - if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 quest details. DB table `quest_details` is empty."); @@ -6379,7 +6382,6 @@ namespace Game // Load `quest_request_items` // 0 1 2 3 4 5 result = DB.World.Query("SELECT ID, EmoteOnComplete, EmoteOnIncomplete, EmoteOnCompleteDelay, EmoteOnIncompleteDelay, CompletionText FROM quest_request_items"); - if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 quest request items. DB table `quest_request_items` is empty."); @@ -6401,7 +6403,6 @@ namespace Game // Load `quest_offer_reward` // 0 1 2 3 4 5 6 7 8 9 result = DB.World.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText FROM quest_offer_reward"); - if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 quest reward emotes. DB table `quest_offer_reward` is empty."); @@ -6423,9 +6424,9 @@ namespace Game // Load `quest_template_addon` // 0 1 2 3 4 5 6 7 8 result = DB.World.Query("SELECT ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay, " + - //9 10 11 12 13 14 15 16 - "RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, RewardMailSenderEntry, " + - //17 18 + //9 10 11 12 13 14 15 + "RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, " + + //16 17 "SpecialFlags, ScriptName FROM quest_template_addon LEFT JOIN quest_mail_sender ON Id=QuestId"); if (result.IsEmpty()) @@ -6447,9 +6448,29 @@ namespace Game } // Load `quest_objectives` - // 0 1 2 3 4 5 6 7 8 9 - result = DB.World.Query("SELECT ID, QuestID, Type, StorageIndex, ObjectID, Amount, Flags, Flags2, ProgressBarWeight, Description FROM quest_objectives ORDER BY `Order` ASC, StorageIndex ASC"); + // 0 1 + result = DB.World.Query("SELECT QuestId, RewardMailSenderEntry FROM quest_mail_sender"); + if (result.IsEmpty()) + { + Log.outError(LogFilter.ServerLoading, "Loaded 0 quest mail senders. DB table `quest_mail_sender` is empty."); + } + else + { + do + { + uint questId = result.Read(0); + var quest = _questTemplates.LookupByKey(questId); + if (quest != null) + quest.LoadQuestMailSender(result.GetFields()); + else + Log.outError(LogFilter.Sql, "Table `quest_mail_sender` has data for quest {0} but such quest does not exist", questId); + } while (result.NextRow()); + } + + // 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"); if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 quest objectives. DB table `quest_objectives` is empty."); @@ -6471,7 +6492,6 @@ namespace Game // Load `quest_visual_effect` join table with quest_objectives because visual effects are based on objective ID (core stores objectives by their index in quest) // 0 1 2 3 4 result = DB.World.Query("SELECT v.ID, o.ID, o.QuestID, v.Index, v.VisualEffect FROM quest_visual_effect AS v LEFT JOIN quest_objectives AS o ON v.ID = o.ID ORDER BY v.Index DESC"); - if (result.IsEmpty()) { Log.outError(LogFilter.ServerLoading, "Loaded 0 quest visual effects. DB table `quest_visual_effect` is empty."); @@ -7515,7 +7535,11 @@ namespace Game return _questGreetingLocaleStorage[typeIndex].LookupByKey(id); } - + public List GetExclusiveQuestGroupBounds(int exclusiveGroupId) + { + return _exclusiveQuestGroups.LookupByKey(exclusiveGroupId); + } + //Spells /Skills / Phases public void LoadPhases() { @@ -9754,7 +9778,7 @@ namespace Game MultiMap _creatureQuestRelations = new MultiMap(); MultiMap _creatureQuestInvolvedRelations = new MultiMap(); MultiMap _creatureQuestInvolvedRelationsReverse = new MultiMap(); - public MultiMap _exclusiveQuestGroups = new MultiMap(); + MultiMap _exclusiveQuestGroups = new MultiMap(); Dictionary _questPOIStorage = new Dictionary(); MultiMap _questAreaTriggerStorage = new MultiMap(); Dictionary _questObjectives = new Dictionary(); diff --git a/Source/Game/Quest/Quest.cs b/Source/Game/Quest/Quest.cs index cc03af9df..5a59d2f52 100644 --- a/Source/Game/Quest/Quest.cs +++ b/Source/Game/Quest/Quest.cs @@ -207,19 +207,23 @@ namespace Game RequiredMinRepValue = fields.Read(13); RequiredMaxRepValue = fields.Read(14); SourceItemIdCount = fields.Read(15); - RewardMailSenderEntry = fields.Read(16); - SpecialFlags = (QuestSpecialFlags)fields.Read(17); - ScriptId = Global.ObjectMgr.GetScriptId(fields.Read(18)); + SpecialFlags = (QuestSpecialFlags)fields.Read(16); + ScriptId = Global.ObjectMgr.GetScriptId(fields.Read(17)); if (SpecialFlags.HasAnyFlag(QuestSpecialFlags.AutoAccept)) Flags |= QuestFlags.AutoAccept; } + public void LoadQuestMailSender(SQLFields fields) + { + RewardMailSenderEntry = fields.Read(1); + } + public void LoadQuestObjective(SQLFields fields) { - QuestObjective obj = new QuestObjective(); - obj.Id = fields.Read(0); - obj.QuestID = fields.Read(1); + QuestObjective obj = new QuestObjective(); + obj.QuestID = fields.Read(0); + obj.Id = fields.Read(1); obj.Type = (QuestObjectiveType)fields.Read(2); obj.StorageIndex = fields.Read(3); obj.ObjectID = fields.Read(4);