aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp4
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp157
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp29
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp4
-rw-r--r--src/server/game/Quests/QuestDef.cpp1
-rw-r--r--src/server/game/Quests/QuestDef.h18
7 files changed, 85 insertions, 130 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 10efffbca77..ef6bb5943b8 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -1172,7 +1172,7 @@ public:
SmartQuest() : QuestScript("SmartQuest") { }
// Called when a quest status change
- void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus /*oldStatus*/, QuestStatus newStatus)
+ void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus /*oldStatus*/, QuestStatus newStatus) override
{
SmartScript smartScript;
smartScript.OnInitialize(nullptr, nullptr, nullptr, quest);
@@ -1197,7 +1197,7 @@ public:
}
// Called when a quest objective data change
- void OnQuestObjectiveChange(Player* player, Quest const* quest, QuestObjective const& objective, int32 /*oldAmount*/, int32 /*newAmount*/)
+ void OnQuestObjectiveChange(Player* player, Quest const* quest, QuestObjective const& objective, int32 /*oldAmount*/, int32 /*newAmount*/) override
{
if (player->IsQuestObjectiveComplete(objective))
{
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index e9e407d64d9..304fb9e273f 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -542,7 +542,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
// We can always call to RequestItems, but this packet only goes out if there are actually
// items. Otherwise, we'll skip straight to the OfferReward
- if (!quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER) && canComplete)
+ if (!quest->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM) && canComplete)
{
SendQuestGiverOfferReward(quest, npcGUID, true);
return;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4507a8a8d7d..1443d0d72d0 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -15069,7 +15069,7 @@ bool Player::CanCompleteQuest(uint32 quest_id)
}
}
- if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED) && q_status.Timer == 0)
+ if (qInfo->GetLimitTime() && q_status.Timer == 0)
return false;
return true;
@@ -15086,7 +15086,7 @@ bool Player::CanCompleteRepeatableQuest(Quest const* quest)
if (!CanTakeQuest(quest, false))
return false;
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
+ if (quest->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM))
for (QuestObjective const& obj : quest->GetObjectives())
if (obj.Type == QUEST_OBJECTIVE_ITEM && !HasItemCount(obj.ObjectID, obj.Amount))
return false;
@@ -15112,7 +15112,7 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg) const
return false;
// prevent receive reward with quest items in bank
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
+ if (quest->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM))
{
for (QuestObjective const& obj : quest->GetObjectives())
{
@@ -15345,10 +15345,8 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
}
uint32 qtime = 0;
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
+ if (uint32 limittime = quest->GetLimitTime())
{
- uint32 limittime = quest->GetLimitTime();
-
// shared timed quest
if (questGiver && questGiver->GetTypeId() == TYPEID_PLAYER)
limittime = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].Timer / IN_MILLISECONDS;
@@ -15776,7 +15774,7 @@ void Player::FailQuest(uint32 questId)
if (qStatus != QUEST_STATUS_INCOMPLETE)
{
// completed timed quest with no requirements
- if (qStatus != QUEST_STATUS_COMPLETE || !quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED) || !quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_COMPLETED_AT_START))
+ if (qStatus != QUEST_STATUS_COMPLETE || !quest->GetLimitTime() || !quest->GetObjectives().empty())
return;
}
@@ -15790,7 +15788,7 @@ void Player::FailQuest(uint32 questId)
SetQuestSlotState(log_slot, QUEST_STATE_FAIL);
}
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
+ if (quest->GetLimitTime())
{
QuestStatusData& q_status = m_QuestStatus[questId];
@@ -16115,7 +16113,7 @@ bool Player::SatisfyQuestConditions(Quest const* qInfo, bool msg)
bool Player::SatisfyQuestTimed(Quest const* qInfo, bool msg) const
{
- if (!m_timedquests.empty() && qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
+ if (!m_timedquests.empty() && qInfo->GetLimitTime())
{
if (msg)
{
@@ -16550,16 +16548,17 @@ uint16 Player::GetReqKillOrCastCurrentCount(uint32 quest_id, int32 entry) const
void Player::AdjustQuestReqItemCount(Quest const* quest)
{
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
+ // adjust progress of quest objectives that rely on external counters, like items
+ if (quest->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM))
{
for (QuestObjective const& obj : quest->GetObjectives())
{
- if (obj.Type != QUEST_OBJECTIVE_ITEM)
- continue;
-
- uint32 reqItemCount = obj.Amount;
- uint32 curItemCount = GetItemCount(obj.ObjectID, true);
- SetQuestObjectiveData(obj, std::min(curItemCount, reqItemCount));
+ if (obj.Type == QUEST_OBJECTIVE_ITEM)
+ {
+ uint32 reqItemCount = obj.Amount;
+ uint32 curItemCount = GetItemCount(obj.ObjectID, true);
+ SetQuestObjectiveData(obj, std::min(curItemCount, reqItemCount));
+ }
}
}
}
@@ -16725,7 +16724,7 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count)
continue;
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
- if (!qInfo || !qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
+ if (!qInfo || !qInfo->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM))
continue;
for (QuestObjective const& obj : qInfo->GetObjectives())
@@ -16766,10 +16765,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
continue;
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
- if (!qInfo)
- continue;
-
- if (!qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
+ if (!qInfo || !qInfo->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM))
continue;
for (QuestObjective const& obj : qInfo->GetObjectives())
@@ -16834,38 +16830,35 @@ void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid /*= ObjectGuid::E
continue;
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
- if (!qInfo)
+ if (!qInfo || !qInfo->HasQuestObjectiveType(QUEST_OBJECTIVE_MONSTER))
continue;
// just if !ingroup || !noraidgroup || raidgroup
QuestStatusData& q_status = m_QuestStatus[questid];
if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficultyID())))
{
- if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL) /*&& !qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_CAST)*/)
+ for (QuestObjective const& obj : qInfo->GetObjectives())
{
- for (QuestObjective const& obj : qInfo->GetObjectives())
- {
- if (obj.Type != QUEST_OBJECTIVE_MONSTER)
- continue;
+ if (obj.Type != QUEST_OBJECTIVE_MONSTER)
+ continue;
- uint32 reqkill = obj.ObjectID;
+ uint32 reqkill = obj.ObjectID;
- if (reqkill == real_entry)
+ if (reqkill == real_entry)
+ {
+ uint32 reqKillCount = obj.Amount;
+ uint16 curKillCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
+ if (curKillCount < reqKillCount)
{
- uint32 reqKillCount = obj.Amount;
- uint16 curKillCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
- if (curKillCount < reqKillCount)
- {
- SetQuestObjectiveData(obj, curKillCount + addKillCount);
- SendQuestUpdateAddCredit(qInfo, guid, obj, curKillCount + addKillCount);
- }
+ SetQuestObjectiveData(obj, curKillCount + addKillCount);
+ SendQuestUpdateAddCredit(qInfo, guid, obj, curKillCount + addKillCount);
+ }
- if (CanCompleteQuest(questid))
- CompleteQuest(questid);
+ if (CanCompleteQuest(questid))
+ CompleteQuest(questid);
- // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization).
- break;
- }
+ // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization).
+ break;
}
}
}
@@ -16883,11 +16876,7 @@ void Player::KilledPlayerCredit()
continue;
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questid);
- if (!qInfo)
- continue;
-
- // This flag is only used for performance optimisation to prevent iterating over all quests
- if (!qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL))
+ if (!qInfo || !qInfo->HasQuestObjectiveType(QUEST_OBJECTIVE_PLAYERKILLS))
continue;
// just if !ingroup || !noraidgroup || raidgroup
@@ -16933,33 +16922,30 @@ void Player::KillCreditGO(uint32 entry, ObjectGuid guid)
if (q_status.Status == QUEST_STATUS_INCOMPLETE)
{
- if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_CAST) /*&& !qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL)*/)
+ for (QuestObjective const& obj : qInfo->GetObjectives())
{
- for (QuestObjective const& obj : qInfo->GetObjectives())
- {
- if (obj.Type != QUEST_OBJECTIVE_GAMEOBJECT)
- continue;
+ if (obj.Type != QUEST_OBJECTIVE_GAMEOBJECT)
+ continue;
- uint32 reqTarget = obj.ObjectID;
+ uint32 reqTarget = obj.ObjectID;
- // other not this creature/GO related objectives
- if (reqTarget != entry)
- continue;
+ // other not this creature/GO related objectives
+ if (reqTarget != entry)
+ continue;
- uint32 reqCastCount = obj.Amount;
- uint32 curCastCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
- if (curCastCount < reqCastCount)
- {
- SetQuestObjectiveData(obj, curCastCount + addCastCount);
- SendQuestUpdateAddCredit(qInfo, guid, obj, curCastCount + addCastCount);
- }
+ uint32 reqCastCount = obj.Amount;
+ uint32 curCastCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
+ if (curCastCount < reqCastCount)
+ {
+ SetQuestObjectiveData(obj, curCastCount + addCastCount);
+ SendQuestUpdateAddCredit(qInfo, guid, obj, curCastCount + addCastCount);
+ }
- if (CanCompleteQuest(questid))
- CompleteQuest(questid);
+ if (CanCompleteQuest(questid))
+ CompleteQuest(questid);
- // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization).
- break;
- }
+ // same objective target can be in many active quests, but not in 2 objectives for single quest (code optimization).
+ break;
}
}
}
@@ -16982,31 +16968,28 @@ void Player::TalkedToCreature(uint32 entry, ObjectGuid guid)
if (q_status.Status == QUEST_STATUS_INCOMPLETE)
{
- if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST | QUEST_SPECIAL_FLAGS_SPEAKTO))
+ for (QuestObjective const& obj : qInfo->GetObjectives())
{
- for (QuestObjective const& obj : qInfo->GetObjectives())
- {
- if (obj.Type != QUEST_OBJECTIVE_TALKTO)
- continue;
+ if (obj.Type != QUEST_OBJECTIVE_TALKTO)
+ continue;
- uint32 reqTarget = obj.ObjectID;
+ uint32 reqTarget = obj.ObjectID;
- if (reqTarget == entry)
+ if (reqTarget == entry)
+ {
+ uint32 reqTalkCount = obj.Amount;
+ uint32 curTalkCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
+ if (curTalkCount < reqTalkCount)
{
- uint32 reqTalkCount = obj.Amount;
- uint32 curTalkCount = GetQuestObjectiveData(qInfo, obj.StorageIndex);
- if (curTalkCount < reqTalkCount)
- {
- SetQuestObjectiveData(obj, curTalkCount + addTalkCount);
- SendQuestUpdateAddCredit(qInfo, guid, obj, curTalkCount + addTalkCount);
- }
+ SetQuestObjectiveData(obj, curTalkCount + addTalkCount);
+ SendQuestUpdateAddCredit(qInfo, guid, obj, curTalkCount + addTalkCount);
+ }
- if (CanCompleteQuest(questid))
- CompleteQuest(questid);
+ if (CanCompleteQuest(questid))
+ CompleteQuest(questid);
- // Quest can't have more than one objective for the same creature (code optimisation)
- break;
- }
+ // Quest can't have more than one objective for the same creature (code optimisation)
+ break;
}
}
}
@@ -19489,7 +19472,7 @@ void Player::_LoadQuestStatus(PreparedQueryResult result)
time_t quest_time = fields[2].GetInt64();
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED) && !GetQuestRewardStatus(quest_id))
+ if (quest->GetLimitTime() && !GetQuestRewardStatus(quest_id))
{
AddTimedQuest(quest_id);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 1aad9f94285..241ffcc3535 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4562,26 +4562,21 @@ void ObjectMgr::LoadQuests()
switch (obj.Type)
{
case QUEST_OBJECTIVE_ITEM:
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER);
if (!sObjectMgr->GetItemTemplate(obj.ObjectID))
TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing item entry %u, quest can't be done.",
qinfo->GetQuestId(), obj.ID, obj.ObjectID);
break;
case QUEST_OBJECTIVE_MONSTER:
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST);
if (!sObjectMgr->GetCreatureTemplate(obj.ObjectID))
TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing creature entry %u, quest can't be done.",
qinfo->GetQuestId(), obj.ID, uint32(obj.ObjectID));
break;
case QUEST_OBJECTIVE_GAMEOBJECT:
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST);
if (!sObjectMgr->GetGameObjectTemplate(obj.ObjectID))
TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing gameobject entry %u, quest can't be done.",
qinfo->GetQuestId(), obj.ID, uint32(obj.ObjectID));
break;
case QUEST_OBJECTIVE_TALKTO:
- // Need checks (is it creature only?)
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_CAST | QUEST_SPECIAL_FLAGS_SPEAKTO);
break;
case QUEST_OBJECTIVE_MIN_REPUTATION:
case QUEST_OBJECTIVE_MAX_REPUTATION:
@@ -4589,7 +4584,6 @@ void ObjectMgr::LoadQuests()
TC_LOG_ERROR("sql.sql", "Quest %u objective %u has non existing faction id %d", qinfo->GetQuestId(), obj.ID, obj.ObjectID);
break;
case QUEST_OBJECTIVE_PLAYERKILLS:
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL);
if (obj.Amount <= 0)
TC_LOG_ERROR("sql.sql", "Quest %u objective %u has invalid player kills count %d", qinfo->GetQuestId(), obj.ID, obj.Amount);
break;
@@ -4893,29 +4887,6 @@ void ObjectMgr::LoadQuests()
if (qinfo->_exclusiveGroup)
_exclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->_exclusiveGroup, qinfo->GetQuestId()));
- if (qinfo->_limitTime)
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED);
-
- // Special flag to determine if quest is completed from the start, used to determine if we can fail timed quest if it is completed
- if (!qinfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL | QUEST_SPECIAL_FLAGS_CAST | QUEST_SPECIAL_FLAGS_SPEAKTO | QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT))
- {
- bool addFlag = true;
- if (qinfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER))
- {
- for (QuestObjective const& obj : qinfo->GetObjectives())
- {
- if (obj.Type == QUEST_OBJECTIVE_ITEM)
- if (static_cast<uint32>(obj.ObjectID) != qinfo->GetSrcItemId() || static_cast<uint32>(obj.Amount) > qinfo->GetSrcItemCount())
- {
- addFlag = false;
- break;
- }
- }
- }
-
- if (addFlag)
- qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_COMPLETED_AT_START);
- }
}
// check QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT for spell with SPELL_EFFECT_QUEST_COMPLETE
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 52ed231c53f..f1380aef1be 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -472,7 +472,7 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPackets::Quest::QuestLogRemove
if (quest)
{
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
+ if (quest->GetLimitTime())
_player->RemoveTimedQuest(questId);
if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
@@ -604,7 +604,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPackets::Quest::QuestGiver
}
else
{
- if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_DELIVER)) // some items required
+ if (quest->HasQuestObjectiveType(QUEST_OBJECTIVE_ITEM)) // some items required
_player->PlayerTalkClass->SendQuestGiverRequestItems(quest, packet.QuestGiverGUID, _player->CanRewardQuest(quest, false), false);
else // no items required
_player->PlayerTalkClass->SendQuestGiverOfferReward(quest, packet.QuestGiverGUID, true);
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index c252076c3c4..88fe8510784 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -252,6 +252,7 @@ void Quest::LoadQuestObjective(Field* fields)
obj.Description = fields[9].GetString();
Objectives.push_back(obj);
+ _usedQuestObjectiveTypes[obj.Type] = true;
}
void Quest::LoadQuestObjectiveVisualEffect(Field* fields)
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index cc31c021b49..c497f332b05 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -25,6 +25,7 @@
#include "RaceMask.h"
#include "SharedDefines.h"
#include "WorldPacket.h"
+#include <bitset>
#include <vector>
class Player;
@@ -248,17 +249,10 @@ enum QuestSpecialFlags
QUEST_SPECIAL_FLAGS_AUTO_ACCEPT = 0x004, // Set by 4 in SpecialFlags in DB if the quest is to be auto-accepted.
QUEST_SPECIAL_FLAGS_DF_QUEST = 0x008, // Set by 8 in SpecialFlags in DB if the quest is used by Dungeon Finder.
QUEST_SPECIAL_FLAGS_MONTHLY = 0x010, // Set by 16 in SpecialFlags in DB if the quest is reset at the begining of the month
- QUEST_SPECIAL_FLAGS_CAST = 0x020, // Set by 32 in SpecialFlags in DB if the quest requires RequiredOrNpcGo killcredit but NOT kill (a spell cast)
// room for more custom flags
- QUEST_SPECIAL_FLAGS_DB_ALLOWED = QUEST_SPECIAL_FLAGS_REPEATABLE | QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT | QUEST_SPECIAL_FLAGS_AUTO_ACCEPT | QUEST_SPECIAL_FLAGS_DF_QUEST | QUEST_SPECIAL_FLAGS_MONTHLY | QUEST_SPECIAL_FLAGS_CAST,
+ QUEST_SPECIAL_FLAGS_DB_ALLOWED = QUEST_SPECIAL_FLAGS_REPEATABLE | QUEST_SPECIAL_FLAGS_EXPLORATION_OR_EVENT | QUEST_SPECIAL_FLAGS_AUTO_ACCEPT | QUEST_SPECIAL_FLAGS_DF_QUEST | QUEST_SPECIAL_FLAGS_MONTHLY,
- QUEST_SPECIAL_FLAGS_DELIVER = 0x080, // Internal flag computed only
- QUEST_SPECIAL_FLAGS_SPEAKTO = 0x100, // Internal flag computed only
- QUEST_SPECIAL_FLAGS_KILL = 0x200, // Internal flag computed only
- QUEST_SPECIAL_FLAGS_TIMED = 0x400, // Internal flag computed only
- QUEST_SPECIAL_FLAGS_PLAYER_KILL = 0x800, // Internal flag computed only
- QUEST_SPECIAL_FLAGS_COMPLETED_AT_START = 0x1000 // Internal flag computed only
};
enum class QuestTagType
@@ -303,7 +297,9 @@ enum QuestObjectiveType
QUEST_OBJECTIVE_OBTAIN_CURRENCY = 17, // requires the player to gain X currency after starting the quest but not required to keep it until the end (does not consume)
QUEST_OBJECTIVE_INCREASE_REPUTATION = 18, // requires the player to gain X reputation with a faction
QUEST_OBJECTIVE_AREA_TRIGGER_ENTER = 19,
- QUEST_OBJECTIVE_AREA_TRIGGER_EXIT = 20
+ QUEST_OBJECTIVE_AREA_TRIGGER_EXIT = 20,
+
+ MAX_QUEST_OBJECTIVE_TYPE
};
enum QuestObjectiveFlags
@@ -384,6 +380,8 @@ struct QuestObjective
case QUEST_OBJECTIVE_WINPETBATTLEAGAINSTNPC:
case QUEST_OBJECTIVE_DEFEATBATTLEPET:
case QUEST_OBJECTIVE_CRITERIA_TREE:
+ case QUEST_OBJECTIVE_AREA_TRIGGER_ENTER:
+ case QUEST_OBJECTIVE_AREA_TRIGGER_EXIT:
return true;
default:
break;
@@ -434,6 +432,7 @@ class TC_GAME_API Quest
bool HasSpecialFlag(uint32 flag) const { return (_specialFlags & flag) != 0; }
void SetSpecialFlag(uint32 flag) { _specialFlags |= flag; }
+ bool HasQuestObjectiveType(QuestObjectiveType type) const { return _usedQuestObjectiveTypes[type]; }
bool IsAutoPush() const { return HasFlagEx(QUEST_FLAGS_EX_AUTO_PUSH); }
bool IsWorldQuest() const { return HasFlagEx(QUEST_FLAGS_EX_IS_WORLD_QUEST); }
@@ -662,6 +661,7 @@ class TC_GAME_API Quest
uint32 _sourceItemIdCount = 0;
uint32 _rewardMailSenderEntry = 0;
uint32 _specialFlags = 0; // custom flags, not sniffed/WDB
+ std::bitset<MAX_QUEST_OBJECTIVE_TYPE> _usedQuestObjectiveTypes;
uint32 _scriptId = 0;
// Helpers