diff options
author | PolarCookie <sei009@post.uit.no> | 2019-04-10 12:58:40 +0200 |
---|---|---|
committer | Giacomo Pozzoni <giacomopoz@gmail.com> | 2019-04-10 12:58:40 +0200 |
commit | 5ed77113b637c49e99a610b00f385c51da67c3bf (patch) | |
tree | 8d65d995762acb0d58590d5da17e234a5a7c0ce3 /src/server/game/Globals/ObjectMgr.cpp | |
parent | 9b3b56f60cc3553d6edcc422b04ee42a4b55678f (diff) |
Core support for breadcrumb quests (#23157)
* Breadcrumb quests support in core
* To Winterspring! & Starfall
* translating ZenoX92's list, part 1
* Carendin Summons is Blood Elf only
* Breadcrumb to an exclusive group
* translating ZenoX92's list, part 2
* class quests
* breadcrumb trails
* better prevquest check
* less harsh error warnings
* minor optimization
* Rename 9999_99_99_99_world.sql to 2019_04_10_00_world.sql
Diffstat (limited to 'src/server/game/Globals/ObjectMgr.cpp')
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 56 |
1 files changed, 52 insertions, 4 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 486c1712d35..365f23323fb 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -4437,9 +4437,9 @@ 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", "quest_template_addon", "template addons", &Quest::LoadQuestTemplateAddon }, // 0 1 @@ -4978,8 +4978,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 %u has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->_prevQuestId); + 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) @@ -4991,6 +4994,19 @@ 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.emplace(qinfo->_exclusiveGroup, qinfo->GetQuestId()); if (qinfo->_timeAllowed) @@ -5019,6 +5035,38 @@ void ObjectMgr::LoadQuests() } } + // 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 (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) { |