aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Globals/ObjectMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index ce3d12c8ef4..4cbe4830866 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4326,11 +4326,11 @@ void ObjectMgr::LoadQuests()
// 0 1 2 3 4 5 6 7 8 9
{ "ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4, RewardText", "quest_offer_reward", "", "reward emotes", &Quest::LoadQuestOfferReward },
- // 0 1 2 3 4 5 6 7 8
- { "ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, RewardMailTemplateID, RewardMailDelay,"
- // 9 10 11 12 13 14 15 16
+ // 0 1 2 3 4 5 6 7 8 9
+ { "ID, MaxLevel, AllowableClasses, SourceSpellID, PrevQuestID, NextQuestID, ExclusiveGroup, BreadcrumbForQuestId, RewardMailTemplateID, RewardMailDelay,"
+ // 10 11 12 13 14 15 16 17
" RequiredSkillID, RequiredSkillPoints, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, ProvidedItemCount, SpecialFlags,"
- // 17
+ // 18
" ScriptName", "quest_template_addon", "", "template addons", &Quest::LoadQuestTemplateAddon },
// 0 1
@@ -4986,8 +4986,11 @@ void ObjectMgr::LoadQuests()
// fill additional data stores
if (uint32 prevQuestId = std::abs(qinfo->_prevQuestID))
{
- if (!_questTemplates.count(prevQuestId))
+ auto prevQuestItr = _questTemplates.find(prevQuestId);
+ if (prevQuestItr == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
+ else if (prevQuestItr->second._breadcrumbForQuestId)
+ TC_LOG_ERROR("sql.sql", "Quest %u should not be unlocked by breadcrumb quest %u", qinfo->_id, prevQuestId);
}
if (uint32 nextQuestId = qinfo->_nextQuestID)
@@ -4999,10 +5002,55 @@ void ObjectMgr::LoadQuests()
nextQuestItr->second.DependentPreviousQuests.push_back(qinfo->GetQuestId());
}
+ if (uint32 breadcrumbForQuestId = std::abs(qinfo->_breadcrumbForQuestId))
+ {
+ if (_questTemplates.find(breadcrumbForQuestId) == _questTemplates.end())
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u is a breadcrumb for quest %u, but no such quest exists", qinfo->_id, breadcrumbForQuestId);
+ qinfo->_breadcrumbForQuestId = 0;
+ }
+ if (qinfo->_nextQuestID)
+ TC_LOG_ERROR("sql.sql", "Quest %u is a breadcrumb, should not unlock quest %u", qinfo->_id, qinfo->_nextQuestID);
+ if (qinfo->_exclusiveGroup)
+ TC_LOG_ERROR("sql.sql", "Quest %u is a breadcrumb in exclusive group %i", qinfo->_id, qinfo->_exclusiveGroup);
+ }
+
if (qinfo->_exclusiveGroup)
_exclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->_exclusiveGroup, qinfo->GetQuestId()));
}
+ // Disallow any breadcrumb loops and inform quests of their breadcrumbs
+ for (auto& questPair : _questTemplates)
+ {
+ // skip post-loading checks for disabled quests
+ if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, questPair.first, nullptr))
+ continue;
+
+ Quest* qinfo = &questPair.second;
+ uint32 qid = qinfo->GetQuestId();
+ uint32 breadcrumbForQuestId = std::abs(qinfo->_breadcrumbForQuestId);
+ std::set<uint32> questSet;
+
+ while(breadcrumbForQuestId)
+ {
+ //a previously visited quest was found as a breadcrumb quest
+ //breadcrumb loop found!
+ if (!questSet.insert(qinfo->_id).second)
+ {
+ TC_LOG_ERROR("sql.sql", "Breadcrumb quests %u and %u are in a loop", qid, breadcrumbForQuestId);
+ qinfo->_breadcrumbForQuestId = 0;
+ break;
+ }
+
+ qinfo = const_cast<Quest*>(sObjectMgr->GetQuestTemplate(breadcrumbForQuestId));
+
+ //every quest has a list of every breadcrumb towards it
+ qinfo->DependentBreadcrumbQuests.push_back(qid);
+
+ breadcrumbForQuestId = qinfo->GetBreadcrumbForQuestId();
+ }
+ }
+
// check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
for (SpellNameEntry const* spellNameEntry : sSpellNameStore)
{