aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp135
-rw-r--r--src/server/game/Entities/Player/Player.h6
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp8
-rw-r--r--src/server/game/Quests/QuestDef.h2
4 files changed, 73 insertions, 78 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index bb1812466cd..981004300ba 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -15204,7 +15204,7 @@ bool Player::CanSeeStartQuest(Quest const* quest)
{
if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, quest->GetQuestId(), this) && SatisfyQuestClass(quest, false) && SatisfyQuestRace(quest, false) &&
SatisfyQuestSkill(quest, false) && SatisfyQuestExclusiveGroup(quest, false) && SatisfyQuestReputation(quest, false) &&
- SatisfyQuestPreviousQuest(quest, false) && SatisfyQuestNextChain(quest, false) &&
+ SatisfyQuestDependentQuests(quest, false) && SatisfyQuestNextChain(quest, false) &&
SatisfyQuestPrevChain(quest, false) && SatisfyQuestDay(quest, false) && SatisfyQuestWeek(quest, false) &&
SatisfyQuestMonth(quest, false) && SatisfyQuestSeasonal(quest, false))
{
@@ -15220,7 +15220,7 @@ bool Player::CanTakeQuest(Quest const* quest, bool msg)
&& SatisfyQuestStatus(quest, msg) && SatisfyQuestExclusiveGroup(quest, msg)
&& SatisfyQuestClass(quest, msg) && SatisfyQuestRace(quest, msg) && SatisfyQuestLevel(quest, msg)
&& SatisfyQuestSkill(quest, msg) && SatisfyQuestReputation(quest, msg)
- && SatisfyQuestPreviousQuest(quest, msg) && SatisfyQuestTimed(quest, msg)
+ && SatisfyQuestDependentQuests(quest, msg) && SatisfyQuestTimed(quest, msg)
&& SatisfyQuestNextChain(quest, msg) && SatisfyQuestPrevChain(quest, msg)
&& SatisfyQuestDay(quest, msg) && SatisfyQuestWeek(quest, msg)
&& SatisfyQuestMonth(quest, msg) && SatisfyQuestSeasonal(quest, msg)
@@ -16085,95 +16085,90 @@ bool Player::SatisfyQuestLog(bool msg) const
return false;
}
-bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestDependentQuests(Quest const* qInfo, bool msg) const
+{
+ return SatisfyQuestPreviousQuest(qInfo, msg) && SatisfyQuestDependentPreviousQuests(qInfo, msg);
+}
+
+bool Player::SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const
{
// No previous quest (might be first quest in a series)
- if (qInfo->PrevQuests.empty())
+ if (!qInfo->GetPrevQuestId())
return true;
- for (auto iter = qInfo->PrevQuests.begin(); iter != qInfo->PrevQuests.end(); ++iter)
- {
- uint32 prevId = abs(*iter);
+ uint32 prevId = std::abs(qInfo->GetPrevQuestId());
+ // If positive previous quest rewarded, return true
+ if (qInfo->GetPrevQuestId() > 0 && m_RewardedQuests.count(prevId) > 0)
+ return true;
- Quest const* qPrevInfo = sObjectMgr->GetQuestTemplate(prevId);
+ // If negative previous quest active, return true
+ if (qInfo->GetPrevQuestId() < 0 && GetQuestStatus(prevId) == QUEST_STATUS_INCOMPLETE)
+ return true;
- if (qPrevInfo)
- {
- // If any of the positive previous quests completed, return true
- if (*iter > 0 && m_RewardedQuests.find(prevId) != m_RewardedQuests.end())
- {
- // skip one-from-all exclusive group
- if (qPrevInfo->GetExclusiveGroup() >= 0)
- return true;
+ // Has positive prev. quest in non-rewarded state
+ // and negative prev. quest in non-active state
+ if (msg)
+ {
+ SendCanTakeQuestResponse(QUEST_ERR_NONE);
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have required quest %u.",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str(), prevId);
+ }
- // each-from-all exclusive group (< 0)
- // can be start if only all quests in prev quest exclusive group completed and rewarded
- auto bounds = sObjectMgr->GetExclusiveQuestGroupBounds(qPrevInfo->GetExclusiveGroup());
- for (auto itr = bounds.first; itr != bounds.second; ++itr)
- {
- uint32 exclude_Id = itr->second;
+ return false;
+}
- // skip checked quest id, only state of other quests in group is interesting
- if (exclude_Id == prevId)
- continue;
+bool Player::SatisfyQuestDependentPreviousQuests(Quest const* qInfo, bool msg) const
+{
+ // No previous quest (might be first quest in a series)
+ if (qInfo->DependentPreviousQuests.empty())
+ return true;
- // alternative quest from group also must be completed and rewarded (reported)
- if (m_RewardedQuests.find(exclude_Id) == m_RewardedQuests.end())
- {
- if (msg)
- {
- SendCanTakeQuestResponse(QUEST_ERR_NONE);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have the required quest (1).",
- qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
- }
- return false;
- }
- }
+ for (uint32 prevId : qInfo->DependentPreviousQuests)
+ {
+ // checked in startup
+ Quest const* questInfo = sObjectMgr->GetQuestTemplate(prevId);
+ ASSERT(questInfo);
+
+ // If any of the previous quests completed, return true
+ if (IsQuestRewarded(prevId))
+ {
+ // skip one-from-all exclusive group
+ if (questInfo->GetExclusiveGroup() >= 0)
return true;
- }
- // If any of the negative previous quests active, return true
- if (*iter < 0 && GetQuestStatus(prevId) != QUEST_STATUS_NONE)
+ // each-from-all exclusive group (< 0)
+ // can be start if only all quests in prev quest exclusive group completed and rewarded
+ auto bounds = sObjectMgr->GetExclusiveQuestGroupBounds(questInfo->GetExclusiveGroup());
+ for (auto itr = bounds.first; itr != bounds.second; ++itr)
{
- // skip one-from-all exclusive group
- if (qPrevInfo->GetExclusiveGroup() >= 0)
- return true;
+ // skip checked quest id, only state of other quests in group is interesting
+ uint32 exclusiveQuestId = itr->second;
+ if (exclusiveQuestId == prevId)
+ continue;
- // each-from-all exclusive group (< 0)
- // can be start if only all quests in prev quest exclusive group active
- auto bounds = sObjectMgr->GetExclusiveQuestGroupBounds(qPrevInfo->GetExclusiveGroup());
- for (auto itr = bounds.first; itr != bounds.second; ++itr)
+ // alternative quest from group also must be completed and rewarded (reported)
+ if (!IsQuestRewarded(exclusiveQuestId))
{
- uint32 exclude_Id = itr->second;
-
- // skip checked quest id, only state of other quests in group is interesting
- if (exclude_Id == prevId)
- continue;
-
- // alternative quest from group also must be active
- if (GetQuestStatus(exclude_Id) != QUEST_STATUS_NONE)
+ if (msg)
{
- if (msg)
- {
- SendCanTakeQuestResponse(QUEST_ERR_NONE);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have the required quest (2).",
- qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
-
- }
- return false;
+ SendCanTakeQuestResponse(QUEST_ERR_NONE);
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestDependentPreviousQuests: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have the required quest (1).",
+ qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
+
+ return false;
}
- return true;
}
+
+ return true;
}
}
- // Has only positive prev. quests in non-rewarded state
- // and negative prev. quests in non-active state
+ // Has only prev. quests in non-rewarded state
if (msg)
{
SendCanTakeQuestResponse(QUEST_ERR_NONE);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have required quest (3).",
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestDependentPreviousQuests: Sent QUEST_ERR_NONE (QuestID: %u) because player '%s' (%s) doesn't have required quest (2).",
qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
@@ -16318,7 +16313,7 @@ bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg) const
return true;
}
-bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg)
+bool Player::SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg) const
{
// non positive exclusive group, if > 0 then can be start if any other quest in exclusive group already started/completed
if (qInfo->GetExclusiveGroup() <= 0)
@@ -16393,9 +16388,9 @@ bool Player::SatisfyQuestPrevChain(Quest const* qInfo, bool msg)
if (qInfo->PrevChainQuests.empty())
return true;
- for (auto iter = qInfo->PrevChainQuests.begin(); iter != qInfo->PrevChainQuests.end(); ++iter)
+ for (uint32 prevQuestId : qInfo->PrevChainQuests)
{
- QuestStatusMap::const_iterator itr = m_QuestStatus.find(*iter);
+ auto itr = m_QuestStatus.find(prevQuestId);
// If any of the previous quests in chain active, return false
if (itr != m_QuestStatus.end() && itr->second.Status != QUEST_STATUS_NONE)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 6bc50b7dc40..acbc5dd6086 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1342,14 +1342,16 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool SatisfyQuestSkill(Quest const* qInfo, bool msg) const;
bool SatisfyQuestLevel(Quest const* qInfo, bool msg) const;
bool SatisfyQuestLog(bool msg) const;
- bool SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg);
+ bool SatisfyQuestDependentQuests(Quest const* qInfo, bool msg) const;
+ bool SatisfyQuestPreviousQuest(Quest const* qInfo, bool msg) const;
+ bool SatisfyQuestDependentPreviousQuests(Quest const* qInfo, bool msg) const;
bool SatisfyQuestClass(Quest const* qInfo, bool msg) const;
bool SatisfyQuestRace(Quest const* qInfo, bool msg) const;
bool SatisfyQuestReputation(Quest const* qInfo, bool msg);
bool SatisfyQuestStatus(Quest const* qInfo, bool msg) const;
bool SatisfyQuestConditions(Quest const* qInfo, bool msg);
bool SatisfyQuestTimed(Quest const* qInfo, bool msg) const;
- bool SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg);
+ bool SatisfyQuestExclusiveGroup(Quest const* qInfo, bool msg) const;
bool SatisfyQuestNextChain(Quest const* qInfo, bool msg) const;
bool SatisfyQuestPrevChain(Quest const* qInfo, bool msg);
bool SatisfyQuestDay(Quest const* qInfo, bool msg) const;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 2c05f4662c3..84196190cce 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -3874,7 +3874,7 @@ void ObjectMgr::LoadQuests()
uint32 oldMSTime = getMSTime();
// For reload case
- for (QuestMap::const_iterator itr=_questTemplates.begin(); itr != _questTemplates.end(); ++itr)
+ for (auto itr = _questTemplates.begin(); itr != _questTemplates.end(); ++itr)
delete itr->second;
_questTemplates.clear();
_questObjectives.clear();
@@ -3969,7 +3969,7 @@ void ObjectMgr::LoadQuests()
for (QuestLoaderHelper const& loader : QuestLoaderHelpers)
{
- QueryResult result = WorldDatabase.Query(Trinity::StringFormat("SELECT %s FROM %s %s", loader.QueryFields, loader.TableName, loader.QueryExtra).c_str());
+ QueryResult result = WorldDatabase.PQuery("SELECT %s FROM %s", loader.QueryFields, loader.TableName, loader.QueryExtra);
if (!result)
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest %s. DB table `%s` is empty.", loader.TableDesc, loader.TableName);
@@ -4617,8 +4617,6 @@ void ObjectMgr::LoadQuests()
{
if (_questTemplates.find(abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
- else
- qinfo->PrevQuests.push_back(qinfo->_prevQuestID);
}
if (qinfo->_nextQuestID)
@@ -4627,7 +4625,7 @@ void ObjectMgr::LoadQuests()
if (qNextItr == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %d has NextQuestId %u, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
else
- qNextItr->second->PrevQuests.push_back(static_cast<int32>(qinfo->GetQuestId()));
+ qNextItr->second->DependentPreviousQuests.push_back(qinfo->GetQuestId());
}
if (qinfo->_exclusiveGroup)
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 8157f647627..2023a4de8e8 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -496,7 +496,7 @@ class TC_GAME_API Quest
void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const;
- std::vector<int32> PrevQuests;
+ std::vector<uint32> DependentPreviousQuests;
std::vector<uint32> PrevChainQuests;
WorldPacket QueryData[TOTAL_LOCALES];