diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 139 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 10 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Quests/QuestDef.h | 2 |
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]; |