aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Globals/ObjectMgr.cpp
diff options
context:
space:
mode:
authorPolarCookie <sei009@post.uit.no>2019-04-10 12:58:40 +0200
committerShauren <shauren.trinity@gmail.com>2021-11-27 00:21:08 +0100
commit0bde06c4027d2e60edc30b55fa7b42da8d253d29 (patch)
tree97712d17c00b8a0055bcce47b07af16c1390f2fc /src/server/game/Globals/ObjectMgr.cpp
parent7f57f6f6061f44a98a021d3de35d524e0fc8eec8 (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 (cherry picked from commit 5ed77113b637c49e99a610b00f385c51da67c3bf)
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)
{