aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-03-16 02:49:57 -0300
committerariel- <ariel-@users.noreply.github.com>2017-03-16 02:55:48 -0300
commit3b27a06265e4f022ec81b00ab99255246e8dd467 (patch)
tree9725ca78afd3efcad3433ee812eba10ea94a474d /src
parentdca276716fecb819fec668f59954113a77f9e393 (diff)
Core/Quests: fixed exclusivegroup interaction with prevquestId and nextQuestId.
- They should work as documented by wiki now. - Add some consts to Player methods - Fixed negative PrevQuestID to mean only active quest (ie not rewarded/complete, as those quests are required to complete another) Closes #19300
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp139
-rw-r--r--src/server/game/Entities/Player/Player.h10
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp9
-rw-r--r--src/server/game/Quests/QuestDef.h2
4 files changed, 77 insertions, 83 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0ec90f9d9c6..50c9b80edc0 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -14741,7 +14741,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))
{
@@ -14757,7 +14757,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)
@@ -15464,95 +15464,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(INVALIDREASON_DONT_HAVE_REQ);
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (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(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (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(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (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(INVALIDREASON_DONT_HAVE_REQ);
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestDependentPreviousQuests: Sent INVALIDREASON_DONT_HAVE_REQ (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(INVALIDREASON_DONT_HAVE_REQ);
- TC_LOG_DEBUG("misc", "Player::SatisfyQuestPreviousQuest: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have required quest (3).",
+ TC_LOG_DEBUG("misc", "Player::SatisfyQuestDependentPreviousQuests: Sent INVALIDREASON_DONT_HAVE_REQ (QuestID: %u) because player '%s' (%s) doesn't have required quest (2).",
qInfo->GetQuestId(), GetName().c_str(), GetGUID().ToString().c_str());
}
@@ -15699,7 +15694,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)
@@ -15774,9 +15769,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)
@@ -15837,7 +15832,7 @@ bool Player::SatisfyQuestDay(Quest const* qInfo, bool msg) const
return true;
}
-bool Player::SatisfyQuestWeek(Quest const* qInfo, bool /*msg*/)
+bool Player::SatisfyQuestWeek(Quest const* qInfo, bool /*msg*/) const
{
if (!qInfo->IsWeekly() || m_weeklyquests.empty())
return true;
@@ -15859,7 +15854,7 @@ bool Player::SatisfyQuestSeasonal(Quest const* qInfo, bool /*msg*/) const
return itr->second.find(qInfo->GetQuestId()) == itr->second.end();
}
-bool Player::SatisfyQuestMonth(Quest const* qInfo, bool /*msg*/)
+bool Player::SatisfyQuestMonth(Quest const* qInfo, bool /*msg*/) const
{
if (!qInfo->IsMonthly() || m_monthlyquests.empty())
return true;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 9d8c9c38f3b..3d2ccc388a4 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1349,19 +1349,21 @@ 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;
- bool SatisfyQuestWeek(Quest const* qInfo, bool msg);
- bool SatisfyQuestMonth(Quest const* qInfo, bool msg);
+ bool SatisfyQuestWeek(Quest const* qInfo, bool msg) const;
+ bool SatisfyQuestMonth(Quest const* qInfo, bool msg) const;
bool SatisfyQuestSeasonal(Quest const* qInfo, bool msg) const;
bool GiveQuestSourceItem(Quest const* quest);
bool TakeQuestSourceItem(uint32 questId, bool msg);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index f7646a46ccc..b7a1788871f 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -3961,7 +3961,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();
@@ -4046,8 +4046,7 @@ void ObjectMgr::LoadQuests()
for (QuestLoaderHelper const& loader : QuestLoaderHelpers)
{
- QueryResult result = WorldDatabase.Query(Trinity::StringFormat("SELECT %s FROM %s", loader.QueryFields, loader.TableName).c_str());
-
+ QueryResult result = WorldDatabase.PQuery("SELECT %s FROM %s", loader.QueryFields, loader.TableName);
if (!result)
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest %s. DB table `%s` is empty.", loader.TableDesc, loader.TableName);
else
@@ -4582,8 +4581,6 @@ void ObjectMgr::LoadQuests()
{
if (_questTemplates.find(std::abs(qinfo->_prevQuestId)) == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %u has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->_prevQuestId);
- else
- qinfo->PrevQuests.push_back(qinfo->_prevQuestId);
}
if (qinfo->_nextQuestId)
@@ -4592,7 +4589,7 @@ void ObjectMgr::LoadQuests()
if (qNextItr == _questTemplates.end())
TC_LOG_ERROR("sql.sql", "Quest %u 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 5647bb0f997..51f7c8bf7a6 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -315,7 +315,7 @@ class TC_GAME_API Quest
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
- std::vector<int32> PrevQuests;
+ std::vector<uint32> DependentPreviousQuests;
std::vector<uint32> PrevChainQuests;
WorldPacket QueryData[TOTAL_LOCALES];